返回归档
⚱️LLM 与 Agent

Prompt Engineering:技法与持续优化

从技法分层到 OpenAI 最佳实践、Meta Prompt,以及评测后如何把 prompt 持续往更好的版本靠拢。

文章目录

提示工程是在不改变模型权重的前提下,用输入决定模型此刻看见什么、怎么想、怎么答。好的 prompt 几乎都是测出来的。

这篇最早是一份技法备忘。现在补上三块更常用的东西:OpenAI 仍然有效的写法、新模型上「写得更清、更结果导向、更精简」的变化,以及评测发现版本 B 更好之后,怎么系统性地往 B 靠。

从模型视角看上下文工程 对着看会更清楚:

  • Prompt 主要拧思考方向、角色、规则、输出合同
  • Context 主要补事实、例子、资料、边界
  • 真正拉开差距的,往往不是一句更华丽的指令,而是模型到底看见了哪些关键信息

七层技法

提示工程可以看成一层层加码,而不是一上来就堆技巧:

  1. 基础层:让模型明白我要什么
  2. 示范层:让模型知道怎么做才对
  3. 推理层:让模型把思考过程写出来
  4. 可靠性层:减少单次推理的偶然错误
  5. 探索层:考虑多种可能,再选择
  6. 工具层:走出封闭世界
  7. 风格 / 约束层:按指定格式和角色输出

image

层级 技法 核心思路 典型场景 成本 常见做法
基础 Zero-shot 直接指令,靠模型已有知识 翻译、摘要、简单问答 极低 直接写任务
示范 Few-shot 用少量高质量例子教格式和逻辑 分类、抽取、结构化输出 给 2–6 个 input → output
推理 Chain-of-Thought 强制写出中间步骤,降低单步跳跃 数学、逻辑、多步问题 「一步一步思考」
推理 Zero-shot CoT 不加例子的极简 CoT 快速抬推理 极低 只加一句「让我们一步一步思考」
可靠性 Self-Consistency 多次独立采样,再投票 选择题、确定答案 CoT + 5–15 次采样
探索 Tree-of-Thoughts 多路径生成 → 评估 → 剪枝 规划、策略、解谜 多个思路打分,深入最优分支
探索 Graph-of-Thoughts 思路之间建立非树状连接 多维度综合分析 很高 显式连接不同思路
工具 ReAct 思考 → 行动 → 观察,循环 搜索、计算、API 中–高 Thought / Action / Observation
工具 RAG 先检索,再注入上下文 私有知识、最新信息 中–高 检索结果塞进 prompt
风格 / 约束 Role / Persona 激活对应知识和语气 写作、咨询、教学 「你是一位……」
风格 / 约束 System Prompt 全局规则、格式、禁止事项 产品化、长期对话 系统消息里写规则
风格 / 约束 Format Constraint 强制 JSON / 表格 / Markdown 程序化解析 写出期望结构
自动优化 APE / OPRO / Auto-CoT / Meta Prompt 让模型生成或改进 prompt 批量任务、已知效果不够 中–高 用更强模型改当前 prompt

image

怎么选,而不是堆技法

任务来了

非常简单、模型大概率会做对? → Zero-shot
  ↓ 否
要严格格式或风格? → Few-shot + Format Constraint
  ↓ 否
多步推理、计算、逻辑? → CoT / Zero-shot CoT
  ↓ 否
正确率很重要、算力够? → CoT + Self-Consistency
  ↓ 否
多条合理路径、容易局部最优? → ToT / GoT
  ↓ 否
要外部知识、工具、新信息? → ReAct 或 RAG
  ↓ 否
要特定角色或语气? → Role + System Prompt
  ↓ 最后
还要继续抬? → Meta Prompt / APE / OPRO,并用评测驱动

工程取舍也很直:

  • 成本 vs 效果:Zero-shot → Few-shot → CoT → Self-Consistency → ToT / ReAct,一层比一层贵
  • 速度 vs 质量:低温 + 单次更快;高温 + Self-Consistency 更稳
  • 确定性 vs 创造性:低 temperature 更确定,高 temperature 更多样
  • 可解释性:CoT、ToT、ReAct 过程可见;Self-Consistency 结果更稳,过程不一定好看

新模型上还有一条更重要:技法可以叠加,但 system prompt 不要越写越厚。每个指令只说一次,只暴露当前任务需要的工具。

OpenAI 仍然有效的写法

这些规则最早写在 Help Center 的最佳实践 里,现在也还成立:

  1. 用更新、更强的模型。新模型通常更好跟指令。注意推理模型和普通 GPT 的写法不一样。
  2. 指令放最前面,用分隔符切开指令和上下文###"""、Markdown 标题、XML 标签都可以。不要把长文本直接糊在指令后面。
  3. 写具体:目标、上下文、期望结果、长度、格式、风格、受众。不要写「短一点就行」,要写「用 3–5 句说明这个产品」。
  4. 用示例锁定输出格式。直接描述格式,往往不如给 1–3 个样例,尤其后面还要程序解析时。
  5. 从 Zero-shot 开始,不够再 Few-shot,还不够再考虑 fine-tune
  6. 用正向指令。告诉模型「要做什么」,比列一堆「不要做什么」更稳。负向指令容易被忽略,或者变成过度回避。
  7. 代码生成用引导词。函数开头先写 import,SQL 先写 SELECT,能把模型直接送进正确轨道。
  8. 提供参考文本、把大任务拆小、明确输出长度和结构,用来压幻觉、控边界。

Academy 把它收成三步,也好记:先用动作动词说清任务,再给有用上下文,最后描述理想输出(语气、格式、长度、受众、约束)。

新模型上,写法变了

模型变强之后,策略从「写得更详细、更结构化」转成「写得更清晰、更结果导向、更精简」。GPT-5 系列的 prompting guide 和内部编码 agent 评估都指向同一件事:臃肿的 system prompt 常常是噪声。精简后,分数有时更高,token 也会明显下降。

建议从一个已经能用的 prompt 开始,一次只拿掉一组指令、示例或工具,再测效果有没有掉。每个指令只陈述一次。

复杂任务可以用这个骨架:

Role(角色)
→ Personality / 语气
→ Goal(目标)
→ Success criteria(成功标准)
→ Constraints(约束)
→ Output(格式)
→ Stop rules(何时停止 / 询问 / 回退)

消息角色也有优先级:developer / instructions 最高,其次 userassistant 最低。用 Markdown 或 XML 把 Identity、Instructions、Examples、Context 分区。

两类模型不要用同一套写法:

  • 推理模型:更像资深同事。给高层次目标、约束和输出合同,让它自己规划路径。中间步骤规定太死,往往适得其反。
  • 普通 GPT:更像初级同事。指令要更明确、更细。
  • Agent / 长流程:强调做到问题解决为止、提前规划、调工具前先说明意图、用 TODO 跟踪进度。

生产环境还要固定模型 snapshot,把 prompt 版本化进代码,用 evals 持续测,并把可复用前缀放前面,吃 prompt caching。Structured Outputs、Function Calling、RAG、Agent 框架会继续降低对「纯文本魔法」的依赖。

Meta Prompt 是什么,去哪用

普通 prompt 告诉模型「做什么」。Meta Prompt 告诉模型「如何写出、或改进一个好的 prompt」,有时也提供一层和具体内容无关的思考脚手架。

它有两层含义:

  1. OpenAI 官方落地:Playground 的 Generate / Optimize 背后,就是用 meta-prompt 按最佳实践生成或改写 system prompt。
  2. 更广义的研究和用法:用更强模型优化较弱模型的 prompt;或者给一个任务无关的推理框架,让模型知道「这一类问题该怎么想」。

官方入口:

自己跑也行:把官方 META_PROMPT 当 system message,用更强模型吃你的任务描述或旧 prompt。需要 OpenAI API 账户,Playground 会消耗 token。

官方 meta-prompt 的关键约束值得单独记:

  • 先充分理解任务目标、约束和期望输出
  • 已有复杂 prompt 只增强清晰度、补缺失,不做无谓大改
  • 推理必须在结论前。用户示例如果结论在前,要反转顺序
  • 尽量保留用户原文、示例、占位符
  • 结构化任务优先 JSON,不要无故用代码块包住
  • 输出结构固定:简洁任务指令 → 细节 → Steps → Output Format → Examples → Notes

评测后,怎么持续往更好的版本靠

核心不是「再写一个更长的 prompt」,而是 Evaluate Flywheel:分析 → 量化 → 改进 → 再循环。

flowchart LR
  A[Analyze 看差异] --> B[Measure 跑评测]
  B --> C[Improve 只改一处]
  C --> A

先有基线:代表性测试集 + 边界 case,grader 尽量同时有 LLM judge 和人工标注。再留一个 hold-out 集,防止把评测集背下来。一次只改一类变量:角色、格式、示例、约束、是否精简。每次改动都留 diff 和分数。

如果评测发现 B 比 A 好,不要凭感觉继续加规则,按这个顺序走:

  1. 先做深度 Diff。并排看 A 和 B,找出真正抬分的点:更清晰的成功标准、更好或更少的 few-shot、去掉矛盾指令、从过程规定改成结果导向、更明确的格式、针对某类失败的补丁。对照具体 case:哪些题 B 做对了、A 做错了。
  2. 用 Meta Prompt / Optimizer 做融合。把「B 为什么更好」和还没修好的失败案例一起喂进去,生成 C。目标是保住 B 的成功因子,修 A 暴露出的坑。
  3. 从当前最优版出发,一次只打一个补丁。立刻用同一测试集 + hold-out 重测。涨了就固化成新 baseline,没涨或掉了就回滚。
  4. 用失败案例驱动下一轮。整理成:input、当前错误输出、期望输出、错误类型。再丢给 Optimizer,比凭感觉大改准。
  5. 上线后继续转飞轮。真实流量失败补进评测集。也定期做 ablation:从好的版本里再删一点,看分数能不能保住。B 如果是因为更 lean 才赢,就优先走精简,而不是继续往里塞规则。

Optimizer 的输出不要直接上生产。必须再跑完整 eval,人工看过再发。换模型、甚至换同一个模型的 snapshot,最好重新 Optimize 一遍。

可以直接用的 Meta Prompt

新建 prompt 时,用官方风格这一版当 system message,再发任务描述:

Given a task description or existing prompt, produce a detailed system prompt to guide a language model in completing the task effectively.

# Guidelines
- Understand the Task: Grasp the main objective, goals, requirements, constraints, and expected output.
- Minimal Changes: If an existing prompt is provided, improve it only if it's simple. For complex prompts, enhance clarity and add missing elements without altering the original structure.
- Reasoning Before Conclusions: Encourage reasoning steps before any conclusions are reached. If the user provides examples where the reasoning happens afterward, REVERSE the order. NEVER START EXAMPLES WITH CONCLUSIONS.
- Clarity and Conciseness: Use clear, specific language. Avoid unnecessary instructions.
- Formatting: Use markdown for readability. DO NOT USE code blocks UNLESS SPECIFICALLY REQUESTED.
- Preserve User Content: Keep provided guidelines, examples, and placeholders as closely as possible.
- Output Format: Explicitly specify the output format. For structured tasks, bias toward JSON and do not wrap JSON in code blocks unless requested.

Return ONLY the completed system prompt, using this structure:

[Concise instruction describing the task]

[Additional details as needed]

# Steps
[optional]

# Output Format
[exactly how the output should be formatted]

# Examples
[optional, 1-3 high-quality examples]

# Notes
[optional edge cases]

已经有评测、且 B 更好时,换这一版:

你是 prompt 优化专家。请基于评测结果生成新的 system prompt。

我会给你:
1. 当前最好的版本 B
2. B 比旧版本更好的原因
3. B 仍然失败的案例
4. 期望再改进的点

要求:
- 保住 B 的成功因子
- 修掉仍然失败的模式
- 更清晰、更结果导向;能精简就精简
- 推理在结论前
- 明确输出格式
- 只返回新的 system prompt,不要解释

Current best prompt (Version B):
"""
{B}
"""

Why Version B was better:
- {diff 结论}

Remaining failure cases:
- Input: ...
  Bad output: ...
  Expected: ...

Desired improvements:
- ...

日常随手改一句,用短的就够:

按当前最佳实践改进下面的 prompt:
- 主指令放最前
- 写清输出格式
- 用正向指令
- 精简、结果导向
- 先推理,再给最终答案

只返回改进后的 prompt。

Original prompt:
{your prompt}

调用参数

场景 temperature top_p max_tokens 备注
数学、逻辑、结构化输出 0.0–0.3 0.9–1.0 按需,通常 512–2048 最高确定性
普通 CoT / 推理 0.3–0.6 0.95 1024–4096 平衡稳定和一点多样性
Self-Consistency 0.5–0.8 0.95–1.0 1024–4096 必须拉高温度,否则路径会撞车
创意写作、脑暴 0.8–1.0 0.95–1.0 2048–8192 增加多样性,减少重复
角色扮演、长文本 0.7–0.9 0.95 4096+ 风格稳定,同时留一点创造
结构化 JSON 0.0–0.2 1.0 按需 配合 Structured Outputs / json_object
批量 / 成本敏感 0.0–0.4 0.9 严格限制 优先速度和成本

大多数时候只调 temperature 就够,top_p 保持 1.0。生产环境同时设 max_tokensstop。强制 JSON 时不要只靠文字约定,用 API 的结构化输出。

官方入口

最终仍以自己的评测为准。模型、snapshot、任务分布一变,昨天最好的版本今天就不一定最好。