Prompt Engineering Guide
这篇文档不再解释一堆术语,而是直接回答一个更实战的问题:
如果已经知道 Prompt Engineering 是什么,接下来在真实项目里到底该怎么写、怎么改、怎么测、怎么版本化。
这篇内容主要按 OpenAI 当前官方 prompting 路线来整理,重点放在:
- 怎么把任务说清楚
- 怎么控制输出结构
- 怎么把 prompt 做成可复用资产
- 怎么让 prompt 和 evals 连起来
1. 先看最重要的结论
Prompt Engineering 在实战里,通常不是“写一句神奇咒语”,而是下面这几件事:
- 把任务边界讲清楚
- 把输入上下文组织对
- 把输出格式约束好
- 用少量高质量示例校正风格和判断标准
- 通过迭代和 evals 验证修改到底有没有变好
所以更稳的理解方式是:
prompt 不是灵感题,而是一种可以被设计、测试、版本化和回归验证的工程资产。
2. Prompt 到底在控制什么
一个 prompt 至少会影响 4 件事:
- 模型到底在完成什么任务
- 模型应该 依据哪些输入信息做判断
- 模型应该按什么格式输出
- 模型在边界场景下优先遵守什么规则
从工程角度看,prompt 常见的组成包括:
- 角色或系统设定
- 任务目标
- 输入变量
- 约束条件
- 输出格式
- 示例
- 失败时的处理规则
如果这些部分本身是模糊的,那后面大概率不是“模型不够聪明”,而是 prompt 设计还没把问题说清楚。
3. 一个更稳的 Prompt 模板
OpenAI 官方 prompting 路线反复强调的核心,其实都可以收敛到一个很稳的基础模板里:
你是谁
你要完成什么任务
你有哪些必须遵守的限制
会收到什么输入
你应该按什么格式输出
如果信息不足 ,你应该怎么处理
把它展开成更实用的版本,可以写成:
角色:
你是一个负责 {任务类型} 的助手。
目标:
目标是 {目标说明}。
输入:
会收到 {输入类型}。
规则:
- 只基于提供的信息回答
- 不要补充未提供的事实
- 如果信息不足,明确说明缺失点
- 优先满足以下约束:{约束}
输出要求:
- 输出语言:{语言}
- 输出格式:{格式}
- 必须包含字段:{字段列表}
质量标准:
- 结论要清楚
- 结构要稳定
- 不要输出多余解释
这个模板不一定每次都要全部写满,但它适合作为第一版起点。
4. OpenAI 官方路线里可以先用起来的 6 个做法
4.1 把任务写具体
OpenAI 官方 prompting 和 help center 的最佳实践都在强调一件事:
越具体,越稳定。
不够具体的写法:
帮我分析这份用户反馈。
更稳的写法:
请把这份用户反馈按“问题类型、影响范围、紧急程度、建议动作”四个字段整理成表格。
如果反馈中没有足够信息判断紧急程度,请标记为“信息不足”。
实战里更值得补充的是:
- 任务类型
- 目标对象
- 输出用途
- 判断标准
- 缺失信息时的行为
4.2 把输出格式先定死
如果结果还要继续被程序消费、被工作流读取、被前端展示,那比起“让模型自由发挥”,更应 该优先做输出结构约束。
OpenAI 当前官方路线里,这一点可以优先结合:
- Prompting guide
- Structured Outputs
能结构化,就尽量结构化。
例如,不要只写:
请总结下面内容。
更稳的是:
请按 JSON 输出,包含以下字段:
- summary
- key_points
- risks
- next_actions
如果某项无法判断,请返回 null,不要编造。
这会明显降低:
- 结果漂移
- 格式不稳定
- 下游解析失败
4.3 示例要少而准
Few-shot 的重点不是“例子越多越好”,而是:
给模型最能代表判断标准的例子。
更适合给例子的场景:
- 风格要求强
- 分类标准容易歧义
- 输出结构虽然固定,但字段含义容易跑偏
- 你希望模型学会某种边界判断
不太适合一开始就狂堆例子的场景:
- 任务本身已经很简单
- 例子质量参差不齐
- 你还没确认任务定义是否正确
更稳的顺序通常是:
- 先写清楚任务和输出结构
- 先试 zero-shot
- 只有在边界判断不稳时,再加 few-shot
4.4 明确“信息不足时怎么办”
很多 prompt 不稳定,不是因为正常路径没写清,而是没写:
- 资料缺失怎么办
- 冲突信息怎么办
- 工具返回空结果怎么办
- 用户请求超出范围怎么办
这一类规则非常值得直接写进 prompt:
如果输入信息不足以支持可靠结论,请不要猜测。
请输出:
1. 当前可确认的信息
2. 缺失的关键信息
3. 建议下一步获取什么数据
这类约束能明显降低“模型为了显得完整而硬答”的概率。
4.5 把 prompt 和变量分开
OpenAI 当前官方 prompting 文档里,一个非常实际的工程点是:
- prompt object
- variables
- versioning
这件事对团队协作特别有价值。
不要把所有变量都手拼在大字符串里。 更稳的方式是:
- 固定 prompt 主体
- 把可变部分做成变量
- 用 prompt version 管理迭代
这样做的好处是:
- 更容易复用
- 更容易比较版本
- 更容易接 evals
- 更容易知道“到底是哪次修改让效果变差了”
4.6 改 prompt 之前先定义“什么叫变好”
这是最容易被忽略的一点。
很多 prompt 迭代其实只是:
- 看起来更顺眼
- 某个单例结果更好
- 主观觉得更接近专家
但这不等于整体真的变好了。
更稳的方式是先定义:
- 正确率看什么
- 格式稳定性看什么
- 拒答边界看什么
- 幻觉率看什么
- 延迟和成本是否变差
否则 prompt 迭代很容易滑进“越改越有感觉,但系统整体更不稳”。
5. 一套简单但非常实用的 Prompt 迭代方法
如果现在就在做项目,我建议按下面这套 5 步来改 prompt。
5.1 先写最小版
第一版只保留:
- 目标
- 输入
- 输出格式
- 缺失信息规则
不要一开始把所有技巧都塞进去。
5.2 用一小组真实样本跑
先不要拿大而全的数据集。 先找一组最典型的真实样本:
- 正常样本
- 边界样本
- 容易出错样本
5.3 只改一个变量
每次只改一类东西,比如:
- 改任务定义
- 改输出格式
- 改示例
- 改缺失信息规则
不要一次改 5 处,否则你根本不知道到底是哪一处起作用。
5.4 记录版本差异
至少记住这几件事:
- 改了什么
- 为什么改
- 哪些样本变好了
- 哪些样本变差了
这本质上已经是 prompt 的 changelog。
5.5 用 evals 做回归
只看单条结果很容易被骗。
更稳的是:
- 固定样本集
- 每次改 prompt 都回跑
- 看整体指标变化
这样你才能知道:
这次 prompt 修改到底是局部优化,还是整体退化。
6. Prompt 和 Structured Outputs 怎么配合
这是一组非常值得你尽快形成习惯的搭配:
- prompt 负责说清任务和边界
- structured outputs 负责约束结果结构
可以把它理解成:
- prompt 决定“模型要做什么”
- schema 决定“模型最后怎么交卷”
这在下面几类任务里尤其重要:
- 分类
- 抽取
- 表单填充
- 工作流节点输出
- agent 中间状态总结
如果系统后面还有代码要接结果,通常优先级应该是:
- 先定义 schema
- 再写 prompt
- 再补 few-shot
而不是先写一大段自然语言,再希望模型“自己懂结构”。
7. Prompt 和 Context 的边界
这也是实战里特别容易混掉的一件事。
可以这样记:
Prompt Engineering更关注“你怎么给模型下任务”Context Engineering更关注“调用前到底给模型看哪些信息”
比如:
- “按什么格式输出”更接近 prompt 问题
- “要不要把最近 10 轮对话都放进去”更接近 context 问题
- “要不要把检索结果拼进来”更接近 context 问题
- “如果检 索信息冲突该怎么表述”更接近 prompt 问题
很多系统效果不好,不一定是 prompt 写得差,而是 context 已经把模型喂乱了。
8. Prompt 在 Agent 里最容易踩的 5 个坑
8.1 角色写很多,任务写很少
“你是世界顶级专家”通常不如明确任务边界有用。
8.2 约束很多,但优先级没写
当多个要求冲突时,模型不知道先满足哪个。
8.3 输出格式说了,但失败路径没说
结果就是模型遇到信息不足时开始乱补。