引言
如果你问我:"怎样才能让ChatGPT给出更好的回答?",我的答案是:看OpenAI的官方指南。
2023年12月,OpenAI正式发布了《Prompt Engineering指南》,这份文档浓缩了他们在大模型应用上的最佳实践。不是网上那些零散的技巧和经验,而是来自源头的官方标准。
这份指南提出了六大核心原则:
- 写清晰的指令 (Write clear instructions)
- 提供参考文本 (Provide reference text)
- 拆解复杂任务 (Split complex tasks into simpler subtasks)
- 给模型思考时间 (Give the model time to "think")
- 使用外部工具 (Use external tools)
- 系统地测试 (Test changes systematically)
OpenAI明确表示:按照这个框架,可以完成Prompt优化的99%。
今天,我们就来深度拆解这六大原则,看看官方推荐的最佳实践到底长什么样。
原则一:写清晰的指令
核心理念:模型不会读心术
这是最基础也是最重要的原则:ChatGPT不知道你脑子里想什么,你必须明确告诉它。
很多人的Prompt失败,就是因为太含糊:
❌ "总结一下会议记录"这个指令有什么问题?
- 总结多长? 一句话还是一段话?
- 总结什么? 结论还是讨论过程?
- 什么格式? 纯文本还是列表?
ChatGPT面对这种模糊指令,只能猜你想要什么,猜错的概率很高。
改进版本:
✅ "请用一个段落总结会议记录。接着,用markdown列表的形式列出所有发言者及其关键观点。最后,如果有的话,列出发言者提出的下一步计划或建议的行动项。"看到区别了吗?具体、结构化、格式明确。
OpenAI推荐的6个核心技巧
1. 在问题中添加详细信息
原则: 不要让模型猜,把背景、要求、格式都说清楚。
对比:
| 模糊版本 | 清晰版本 |
|---|---|
| "写一篇文章" | "写一篇800字的技术博客,面向前端开发者,介绍React Hooks的使用场景,包含3个代码示例" |
| "帮我改简历" | "优化简历中的'工作经历'部分,突出项目成果和数据指标,每条不超过2行,使用动词开头" |
| "翻译这段话" | "将以下中文翻译成英文,保持技术术语的准确性,语气要正式专业" |
黄金法则: 问问自己"如果我是AI,看到这个指令,我能准确完成任务吗?" 如果答案是"不确定",那就需要补充细节。
2. 请求模型扮演特定角色
原理: 角色设定能激活模型在特定领域的知识和语气。
示例:
我希望你扮演一名**小说家**。您将想出富有创意且引人入胜的故事,可以长时间吸引读者。
你可以选择任何类型,如奇幻、浪漫、历史小说等,但目标是写出具有出色情节、引人入胜的人物和意想不到的高潮的作品。
我的第一个要求是:"我要写一部以未来为背景的科幻小说"。效果对比:
| 无角色设定 | 有角色设定 |
|---|---|
| "写一个故事开头" | "你是畅销小说家,写一个悬疑故事开头" |
| 输出: 平淡的叙述 | 输出: 充满张力的场景描写 |
3. 使用分隔符区分输入的不同部分
目的: 让模型清晰分辨"需求"和"待处理内容"。
推荐分隔符:
"""三重引号---水平线<article>XML标签### 章节标题
示例:
你将会接收到两篇关于相同主题的文章。
首先分别总结这两篇文章的主要论点。
接着评价哪篇文章的论据更具说服力,并说明理由。
"""
第一篇文章内容...
"""
---
"""
第二篇文章内容...
"""为什么有效?
- 避免模型把指令当内容处理
- 减少注入攻击的风险
- 提高解析准确性
安全提示: 如果你的应用允许用户输入文本,使用分隔符可以防止用户在输入中注入恶意指令,覆盖你的原始Prompt。
4. 明确指出完成任务需要的步骤
原理: 复杂任务需要分解成清晰的步骤,引导模型逐步执行。
示例:
请按照以下步骤来回应用户的输入:
第1步 - 用户会给你提供带有三重引号的文本。请将这段文本总结为一句话,并以"摘要:"作为前缀。
第2步 - 将第1步中的摘要翻译成西班牙语,并以"翻译:"作为前缀。
"""
{用户输入文本}
"""为什么这样做?
| 不拆步骤 | 拆解步骤 |
|---|---|
| 模型可能跳过某些环节 | 严格按顺序执行 |
| 输出格式不统一 | 格式可预测可解析 |
| 难以调试 | 每步可单独验证 |
5. 提供实例作为参考(Few-shot)
原理: 示例比文字解释更直观,尤其是定义特殊格式时。
示例:
请按照示例的风格,为新词创造例句:
whatpu是一种原产于坦桑尼亚的毛茸茸的小动物。
使用whatpu这个词的句子示例如下:
"我们在非洲旅行,看到了这些非常可爱的whatpus。"
farduddle的意思是快速地上下跳跃。
使用该词的句子举例如下:模型会根据示例的模式,生成类似风格的句子。
6. 明确指定希望输出的长度
示例:
❌ "总结这篇文章"
✅ "用两段话概括三引号内的文本,每段不超过50字"
❌ "写一个产品介绍"
✅ "写一个150字的产品介绍,包含3个核心卖点,语气要吸引年轻用户"控制长度的方法:
- 指定字数: "100-150字"
- 指定句子数: "用3句话概括"
- 指定段落数: "分两段说明"
- 指定列表项: "列出5个要点"
原则二:提供参考文本
核心问题:模型的"幻觉"
语言模型有个致命弱点:当它不知道答案时,会自信地编造。
尤其是当你问:
- 深奥的专业知识
- 最新的新闻事件
- 特定文档的内容
- 需要引用URL或论文
这时候,提供参考文本能显著减少幻觉。
技巧1: 使用参考文本来构建答案
Prompt模板:
当你被提供特定文章,并需要回答问题时,请依据这些文章中的内容来作答。
如果这些文章中没有包含答案,你只需表明"无法找到答案"。
<插入文章内容,每篇文章之间用三个引号隔开>
"""
文章1内容...
"""
"""
文章2内容...
"""
问题: <插入问题>效果对比:
| 无参考文本 | 有参考文本 |
|---|---|
| 模型根据训练数据"猜答案" | 模型只从提供的文本中找答案 |
| 可能编造事实 | 找不到就说"无法找到" |
| 答案不可验证 | 答案可追溯到源文本 |
技术扩展: 由于模型的上下文窗口有限,对于大规模知识库,可以使用**Embeddings(嵌入技术)**动态检索相关文档,再提供给模型。这就是RAG(检索增强生成)的核心思想。
技巧2: 指导模型用引用的文本回答问题
进阶要求: 不仅要基于参考文本回答,还要标注引用来源。
Prompt模板:
你将会收到一个用三个引号标记的文档和一个问题。
你的任务是仅使用所提供的文档来回答这个问题,并引用文档中用来回答问题的部分。
如果文档中没有包含足够的信息来回答这个问题,就简单地写"信息不足"。
如果提供了问题的答案,那么必须用引用标记。
引用相关段落时,请使用以下格式: {"citation": "引用内容"}
"""
<插入文档>
"""
问题: <插入问题>输出示例:
答案: 根据文档,该产品的保修期为2年。{"citation": "所有电子产品享受2年免费保修服务"}为什么要引用?
- ✅ 增强答案的可信度
- ✅ 方便用户验证信息
- ✅ 避免模型添加文档外的信息
- ✅ 符合学术/专业规范
原则三:拆解复杂任务
核心理念:分而治之
就像你不会一口吃成胖子,模型也不该一次处理太复杂的任务。
复杂任务 → 简单子任务 = 更高的成功率
技巧1: 利用意图分类确定相关指令
场景: 客服机器人面对各种问题,如何分门别类处理?
策略: 先分类,再处理。
Step 1: 意图分类
用户输入: "我断网了咋整"
分类系统提示词:
你是客服助手,请将用户问题分类到以下类别之一:
- 账户问题
- 技术支持 - 网络故障
- 技术支持 - 设备故障
- 订单查询
- 退换货
输出格式: {"category": "分类名"}Step 2: 针对分类执行专项处理
# 如果分类是"技术支持 - 网络故障"
执行网络故障排查流程:
1. 检查路由器指示灯
2. 重启路由器
3. 检查账户是否欠费
4. ...为什么要分类?
| 不分类 | 分类后 |
|---|---|
| 一个超长Prompt处理所有情况 | 每类任务用专门优化的Prompt |
| 容易混淆不同场景 | 明确区分,减少错误 |
| Token消耗高 | 只调用相关部分,省成本 |
技巧2: 对长对话进行总结或过滤
问题: 模型的上下文窗口是有限的,长对话怎么办?
解决方案: 动态总结历史对话。
Prompt模板:
你的任务是总结人工智能角色与人类对话中之前的信息历史。
为您提供的对话来自一个固定的上下文窗口,可能并不完整。
从人工智能的角度总结对话中发生的事情(使用第一人称)。
摘要字数应少于{WORD_LIMIT},切勿超过字数限制。
对话历史:
"""
{历史对话}
"""应用场景:
- 💬 长期客服对话
- 📖 文档问答系统
- 🤖 个人AI助手
替代方案: 使用Embeddings检索,只提取与当前问题最相关的历史片段。
技巧3: 逐段归纳长文档并递归构建摘要
问题: 要总结一本10万字的书,上下文窗口不够怎么办?
解决方案: 分段总结 → 总结的总结 → 递归。
流程:
第1层: 总结每一章 (10章 → 10个摘要)
第2层: 总结10个摘要 (10个摘要 → 1个大摘要)
第3层: 最终总摘要伪代码:
def summarize_book(chapters):
# 第1步: 总结每章
chapter_summaries = [summarize(chapter) for chapter in chapters]
# 第2步: 总结所有章节摘要
book_summary = summarize(chapter_summaries)
return book_summary实战技巧: 如果后续章节需要前面的上下文,可以在总结时附加"前文梗概",形成连续的理解链。
原则四:给模型思考时间
核心理念:慢思考,准答案
人类解复杂题需要草稿纸,AI也需要"思考空间"。
技巧1: 指导模型先推理,再下结论
错误做法:
这道数学题的答案对吗?
题目: ...
学生答案: ...❌ 问题: 模型看到答案,容易受影响,直接判断"对"或"错",而不自己算一遍。
正确做法:
Step 1: 请你先独立解决这道题,写出完整步骤。
题目: ...
---
Step 2: 现在对比你的答案和学生的答案,指出学生的错误(如果有)。
学生答案: ...✅ 改进: 模型先自己推理,再对比,准确率大幅提升。
实际案例(来自OpenAI官方示例):
某数学题,学生答案实际是错的,但如果直接让模型判断,它会说"正确"。 而通过两步法,模型会先算出正确答案,然后发现学生答案有误。
技巧2: 使用内心独白隐藏推理过程
场景: 教育应用中,你希望AI指导学生,但不能直接给出答案。
问题: 如果让模型推理,推理过程会暴露答案。
解决方案: 让模型把推理过程标记为"内心独白",不展示给用户。
Prompt结构:
Step 1: 独立解题(不展示给学生)
输出格式: <reasoning>推理过程</reasoning>
Step 2: 给学生提示(展示)
输出格式: <hint>提示内容</hint>后端处理:
response = model.generate(prompt)
# 解析输出
reasoning = extract_tag(response, "reasoning") # 保存但不显示
hint = extract_tag(response, "hint") # 显示给学生
return hint # 只返回提示技巧3: 询问模型是否有遗漏
场景: 让模型从长文档中提取相关段落。
问题: 模型可能过早停止,遗漏后面的内容。
解决方案: 分两轮查询。
第1轮:
请从以下文档中找出所有与"量子计算"相关的段落。
"""
{长文档}
"""第2轮(追问):
你之前提取了以下段落:
{第1轮结果}
请再次检查文档,是否还有其他相关段落被遗漏?如果有,请列出。✅ 效果: 通常能找回5-20%被遗漏的内容。
原则五:使用外部工具
核心理念:术业有专攻
语言模型的强项是理解和生成文本,但它不擅长:
- ❌ 精确计算
- ❌ 实时信息检索
- ❌ 调用外部API
- ❌ 执行代码
解决方案: 让模型调用外部工具。
技巧1: 使用Embeddings实现高效知识检索
什么是Embeddings?
把文本转换成向量,相似的文本向量距离近,不相似的文本向量距离远。
应用场景: 从大量文档中快速找到与问题最相关的片段。
流程:
1. 离线处理: 把知识库分成chunks,每个chunk转成向量,存入向量数据库
2. 在线查询:
- 用户问题 → 转成向量
- 向量搜索 → 找到最相关的top-K chunks
- 把这些chunks作为参考文本提供给模型伪代码:
# 1. 用户提问
question = "什么是量子纠缠?"
# 2. 向量检索
question_embedding = get_embedding(question)
relevant_chunks = vector_db.search(question_embedding, top_k=3)
# 3. 构建Prompt
prompt = f"""
根据以下文档回答问题:
{relevant_chunks}
问题: {question}
"""
# 4. 调用模型
answer = model.generate(prompt)热门工具:
- 向量数据库: Pinecone, Weaviate, Milvus
- Embedding模型: OpenAI text-embedding-3, Cohere Embed
- 框架: LangChain, LlamaIndex
技巧2: 利用代码执行进行精确计算
问题: 让语言模型算 3*x**5 - 5*x**4 - 3*x**3 - 7*x - 10 = 0 的根?
大概率算错。
解决方案: 让模型写代码,然后执行代码。
Prompt模板:
你可以通过用三个反引号包裹Python代码来编写并执行代码
这种方式适用于需要进行计算的情况。
求解以下多项式的所有实数解: 3*x**5 - 5*x**4 - 3*x**3 - 7*x - 10 = 0模型输出:
import numpy as np
from numpy.polynomial import polynomial as P
# 定义多项式系数
coeffs = [-10, -7, 0, -3, -5, 3]
roots = np.roots(coeffs[::-1])
# 过滤实数解
real_roots = [r.real for r in roots if abs(r.imag) < 1e-5]
print(real_roots)后端执行代码,返回结果:
实数解: [2.0]技巧3: 使用Function Calling调用外部API
什么是Function Calling?
OpenAI的Chat Completions API允许你定义函数,模型会根据对话生成调用这些函数的参数。
示例: 查询天气
第1步: 定义函数
{
"name": "get_weather",
"description": "获取指定城市的天气",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名,如'北京'"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
}第2步: 用户提问
用户: "北京今天天气怎么样?"第3步: 模型返回函数调用
{
"function_call": {
"name": "get_weather",
"arguments": "{\"city\": \"北京\", \"unit\": \"celsius\"}"
}
}第4步: 执行函数,返回结果给模型
{
"role": "function",
"name": "get_weather",
"content": "{\"temperature\": 15, \"condition\": \"晴\"}"
}第5步: 模型生成最终回答
助手: "北京今天天气晴朗,气温15摄氏度。"原则六:系统地测试变更
核心理念:数据驱动优化
你改了Prompt,效果变好了吗?凭感觉不靠谱,要用数据说话。
评估流程
1. 准备测试集
测试用例1
输入: "总结这篇文章"
期望输出: 包含3个关键点的段落
测试用例2
输入: "翻译成英文"
期望输出: 准确的英文翻译
...2. 设定评估标准
方法A: 标准答案对比
如果有标准答案,检查模型输出是否包含必要事实。
Prompt模板:
你是评估助手。给定标准答案和候选答案,判断候选答案是否:
1. 包含标准答案中的所有关键事实
2. 没有与标准答案矛盾的内容
标准答案: {standard_answer}
候选答案: {model_output}
输出格式: {"contains_facts": true/false, "has_contradictions": true/false}方法B: 多维度打分
| 维度 | 权重 | 评分标准 |
|---|---|---|
| 准确性 | 40% | 事实是否正确 |
| 完整性 | 30% | 是否遗漏要点 |
| 简洁性 | 20% | 是否冗余 |
| 格式 | 10% | 是否符合要求 |
3. A/B测试
# 版本A: 原始Prompt
prompt_a = "总结这篇文章"
# 版本B: 优化Prompt
prompt_b = "用3句话总结这篇文章的核心观点,每句不超过30字"
# 在测试集上对比
results_a = evaluate(prompt_a, test_set)
results_b = evaluate(prompt_b, test_set)
# 统计
print(f"版本A平均分: {results_a.mean()}")
print(f"版本B平均分: {results_b.mean()}")注意: 样本量太少(如少于10个)时,结果容易受随机因素影响。建议至少准备30-50个测试用例。
实战建议
开发流程:
1. 基线版本 → 在测试集上跑一遍,记录分数
2. 迭代优化 → 改Prompt,再跑测试集
3. 对比分析 → 哪些用例改进了,哪些变差了
4. 针对性优化 → 分析失败用例,调整策略
5. 重复2-4,直到满意工具推荐:
- 📊 Prompt评估: OpenAI Evals, LangSmith
- 🧪 实验管理: W&B, MLflow
- 📝 测试集管理: Google Sheets, Airtable
综合应用:六大原则组合拳
让我们看一个完整的案例,如何综合运用这些原则。
任务:构建客服机器人
需求: 回答用户关于产品的问题,准确且友好。
应用原则:
✅ 原则1: 写清晰指令
你是[公司名]的客服助手,专注于回答产品相关问题。
你的职责:
- 根据产品文档回答问题
- 如果文档中没有答案,告知用户并建议联系人工客服
- 语气要友好、专业、简洁
你不应该:
- 提供产品文档外的信息
- 猜测未确认的信息
- 推销产品或服务✅ 原则2: 提供参考文本
产品文档:
"""
{从知识库中通过Embeddings检索到的相关文档}
"""
用户问题: {user_question}✅ 原则3: 拆解任务
Step 1: 意图分类
判断问题类型: 产品功能 | 价格 | 技术支持 | 其他
Step 2: 针对性回答
if 类型 == "技术支持":
执行故障排查流程
elif 类型 == "价格":
查询价格表
...✅ 原则4: 给思考时间
请先在<analysis>标签中分析:
1. 用户问题的核心是什么
2. 文档中是否包含答案
3. 如何用简洁的语言回答
然后在<response>标签中给出最终回答。✅ 原则5: 使用外部工具
# 使用Embeddings检索相关文档
# 使用Function Calling查询订单状态
# 使用代码执行计算价格✅ 原则6: 系统测试
准备100个真实用户问题
对比不同Prompt版本的表现
持续优化常见误区与避坑指南
误区1: 过度复杂化
错误想法: "我要把所有技巧都用上,Prompt越长越好!"
问题: 过长的Prompt会:
- 💰 增加Token成本
- ⏱️ 降低响应速度
- 🐛 引入更多不确定性
正确做法: 够用就好,根据任务复杂度选择技巧。
误区2: 忽略测试
错误想法: "感觉这个Prompt挺好的,直接上线吧。"
问题: 没测试过,怎么知道真的好?
正确做法: 至少准备10-20个测试用例,验证效果。
误区3: 一成不变
错误想法: "按官方指南写了,就不用改了。"
问题: 不同领域、不同任务,最佳实践不同。
正确做法: 把指南当起点,不断迭代优化。
我踩过的坑
分享一个真实案例:
坑:指令太模糊,效果不稳定
最开始做文档问答时,我的Prompt是:
根据文档回答问题。
文档: {doc}
问题: {question}问题: 有时答得很好,有时瞎编。
原因: 没明确"找不到答案时怎么办"。
改进后:
你是文档问答助手。请根据提供的文档回答问题。
规则:
1. 只使用文档中的信息
2. 如果文档中没有答案,明确回复"文档中未找到相关信息"
3. 不要猜测或编造
4. 引用文档时注明段落
文档:
"""
{doc}
"""
问题: {question}✅ 效果: 幻觉问题基本消失,准确率从70%提升到95%。
启示: 明确边界很重要——告诉模型"可以做什么"和"不能做什么"。
实战练习:优化你的第一个Prompt
现在,轮到你了!选择一个你常用的任务,用六大原则优化它。
练习模板
【原始Prompt】
{你现在使用的Prompt}
【应用原则】
□ 原则1: 指令是否清晰明确?
□ 原则2: 是否需要参考文本?
□ 原则3: 任务是否可拆解?
□ 原则4: 是否需要推理步骤?
□ 原则5: 是否需要外部工具?
□ 原则6: 如何测试效果?
【优化后Prompt】
{应用原则后的版本}推荐场景
从这些场景开始练习(由易到难):
- 内容总结 - 总结会议记录/文章
- 格式转换 - 将表格数据转成JSON
- 代码审查 - 检查代码问题
- 邮件撰写 - 根据要点写正式邮件
- 数据分析 - 从CSV提取洞察
总结
让我们回顾OpenAI官方的六大Prompt工程原则:
🎯 六大原则速查表
| 原则 | 核心思想 | 关键技巧 | 适用场景 |
|---|---|---|---|
| 1. 写清晰指令 | 不要让模型猜 | 添加细节、角色扮演、分隔符、步骤拆解、提供示例、指定长度 | 所有任务 |
| 2. 提供参考文本 | 减少幻觉 | 基于文档回答、要求引用来源 | 知识问答、文档处理 |
| 3. 拆解复杂任务 | 分而治之 | 意图分类、对话总结、递归处理 | 多步骤任务、长文档 |
| 4. 给思考时间 | 慢思考,准答案 | 先推理再判断、内心独白、检查遗漏 | 推理、数学、审查 |
| 5. 使用外部工具 | 术业有专攻 | Embeddings检索、代码执行、Function Calling | 知识库、计算、API调用 |
| 6. 系统测试 | 数据驱动优化 | 测试集、评估标准、A/B测试 | 生产环境部署 |
💡 核心要点
- 99%的优化靠这六个原则 - OpenAI官方认证
- 原则可组合 - 不是单选题,而是多选题
- 从简单开始 - 先用原则1,不行再叠加其他
- 持续迭代 - Prompt优化是个过程,不是一次性任务
📋 下一步行动
- 选择一个实际任务,尝试应用六大原则
- 建立Prompt模板库,把优化后的Prompt保存下来
- 准备测试集,至少10-20个用例
- 阅读OpenAI官方文档,查看完整示例
- 实践Function Calling,体验工具调用能力
🔗 相关资源
官方文档:
进阶阅读:
记住: Prompt工程不是玄学,而是科学。遵循OpenAI的六大原则,用数据验证效果,你就能掌握99%的优化技巧。
有疑问或想分享你的Prompt优化经验?欢迎在评论区留言讨论!