大模型应用实战

OpenAI官方Prompt工程六大原则:从入门到精通

深度解读OpenAI官方发布的Prompt Engineering指南,系统讲解写清晰指令、提供参考文本、任务拆解、给予思考时间、使用外部工具、系统测试六大核心原则,助你掌握99%的Prompt优化技巧

·21 分钟阅读·AI/LLM

引言

如果你问我:"怎样才能让ChatGPT给出更好的回答?",我的答案是:看OpenAI的官方指南

2023年12月,OpenAI正式发布了《Prompt Engineering指南》,这份文档浓缩了他们在大模型应用上的最佳实践。不是网上那些零散的技巧和经验,而是来自源头的官方标准

这份指南提出了六大核心原则:

  1. 写清晰的指令 (Write clear instructions)
  2. 提供参考文本 (Provide reference text)
  3. 拆解复杂任务 (Split complex tasks into simpler subtasks)
  4. 给模型思考时间 (Give the model time to "think")
  5. 使用外部工具 (Use external tools)
  6. 系统地测试 (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】
{应用原则后的版本}

推荐场景

从这些场景开始练习(由易到难):

  1. 内容总结 - 总结会议记录/文章
  2. 格式转换 - 将表格数据转成JSON
  3. 代码审查 - 检查代码问题
  4. 邮件撰写 - 根据要点写正式邮件
  5. 数据分析 - 从CSV提取洞察

总结

让我们回顾OpenAI官方的六大Prompt工程原则:

🎯 六大原则速查表

原则核心思想关键技巧适用场景
1. 写清晰指令不要让模型猜添加细节、角色扮演、分隔符、步骤拆解、提供示例、指定长度所有任务
2. 提供参考文本减少幻觉基于文档回答、要求引用来源知识问答、文档处理
3. 拆解复杂任务分而治之意图分类、对话总结、递归处理多步骤任务、长文档
4. 给思考时间慢思考,准答案先推理再判断、内心独白、检查遗漏推理、数学、审查
5. 使用外部工具术业有专攻Embeddings检索、代码执行、Function Calling知识库、计算、API调用
6. 系统测试数据驱动优化测试集、评估标准、A/B测试生产环境部署

💡 核心要点

  1. 99%的优化靠这六个原则 - OpenAI官方认证
  2. 原则可组合 - 不是单选题,而是多选题
  3. 从简单开始 - 先用原则1,不行再叠加其他
  4. 持续迭代 - Prompt优化是个过程,不是一次性任务

📋 下一步行动

  • 选择一个实际任务,尝试应用六大原则
  • 建立Prompt模板库,把优化后的Prompt保存下来
  • 准备测试集,至少10-20个用例
  • 阅读OpenAI官方文档,查看完整示例
  • 实践Function Calling,体验工具调用能力

🔗 相关资源

官方文档:

进阶阅读:


记住: Prompt工程不是玄学,而是科学。遵循OpenAI的六大原则,用数据验证效果,你就能掌握99%的优化技巧。

有疑问或想分享你的Prompt优化经验?欢迎在评论区留言讨论!