上一篇我们理解了大模型的底层机制——它是一个逐 token 预测的概率机器。那么问题来了:怎么让这个概率机器给出你想要的答案?

答案就是 Prompt Engineering。

Prompt Engineering 的本质是:用更好的输入,引导模型的概率分布偏向正确的方向。 你给模型的上下文越精准,它"预测"出好答案的概率就越高。

这篇文章覆盖 Prompt Engineering 最核心的 6 个技巧,从简单到复杂递进。每个技巧我都会给出具体示例,说明什么时候用、怎么用、有什么坑。

Prompt Engineering 技巧全景图


1. Zero-shot Prompting:“直接问”

最简单的用法——不提供任何示例,直接给模型一个指令。

Prompt: "将以下英文翻译成中文:The cat sat on the mat."
输出: "猫坐在垫子上。"

什么时候用? 模型已经很擅长的任务:翻译、摘要、格式转换、常识问答。

怎么写好 Zero-shot Prompt? 关键是把指令写清楚。对比两种写法:

❌ 差的 Prompt: "帮我看看这段代码"
✅ 好的 Prompt: "请审查以下 Python 函数,指出潜在的 bug 和性能问题,
    并给出修改建议。按严重程度从高到低排列。"

好的 Prompt 明确了:做什么(审查 bug + 性能)、什么语言(Python)、输出格式(按严重程度排列)。模型不需要"猜"你想要什么。


2. Few-shot Prompting:“给几个例子”

当模型对任务不太确定时,给它几个输入→输出的示例,帮它"理解"你要什么。

Prompt:
将商品评论分类为"正面"或"负面"。

评论: "这个手机拍照效果很好,电池也耐用"
分类: 正面

评论: "屏幕太小了,看着眼睛累"
分类: 负面

评论: "物流很快,但包装有点简陋"
分类: 正面

评论: "质量太差了,用了一周就坏了"
分类: ?

输出: 负面

为什么有效? Few-shot 利用了模型的 In-Context Learning 能力——不需要微调,只要在 Prompt 里给出示例,模型就能"学会"任务模式。

给几个例子合适? 一般 3~5 个就够了。太多会浪费 Context Window,太少模型可能抓不住规律。示例要覆盖典型场景,最好包含边界情况。

进阶技巧:示例的顺序会影响结果。模型对最后一个示例最敏感(recency bias),所以把最"标准"的示例放在最后。


3. Chain-of-Thought(CoT):“让模型想一步再回答”

这是 Prompt Engineering 最重要的技巧之一。核心思想:要求模型展示推理过程,而不是直接给答案。

不用 CoT 的情况

Prompt: "一个商店进了 23 箱苹果,每箱 12 个。卖了 156 个后又进了 8 箱。
         现在有多少个苹果?"
输出: "216"(直接猜了一个数,大概率是错的)

使用 CoT

Prompt: "一个商店进了 23 箱苹果,每箱 12 个。卖了 156 个后又进了 8 箱。
         现在有多少个苹果?请一步一步推理。"

输出:
第一步:23 箱 × 12 个/箱 = 276 个
第二步:卖了 156 个 → 276 - 156 = 120 个
第三步:又进了 8 箱 → 8 × 12 = 96 个
第四步:120 + 96 = 216 个
答案是 216 个。

这里答案恰好对了,但关键不在答案本身——推理过程让模型"走对了路"。对于更复杂的题目,不用 CoT 的正确率可能只有 20%,用了 CoT 能提升到 70%+。

最简单的 CoT 触发语

你不需要每次都写详细的推理指令。研究发现,只要加一句 “Let’s think step by step”(或中文的"请逐步推理"),就能显著提升模型在数学、逻辑推理任务上的表现。

什么时候用 CoT?

  • 数学计算、逻辑推理、代码调试 → 必用
  • 简单翻译、格式转换、常识问答 → 不需要(加了反而啰嗦)

4. Self-Consistency:“多跑几次,投票选答案”

这个技巧解决一个核心问题:模型有时运气好答对,有时运气差答错。怎么让它更稳定?

Self-Consistency 的做法是:

  1. 对同一个问题,用 CoT 让模型生成多个不同的推理路径(比如 5 次)
  2. 对最终答案做投票——出现次数最多的答案作为最终结果
问题: "一个班有 40 个学生,60% 是女生。如果 5 个男生转学走了,
       班上还有多少男生?"

第 1 次推理: 40×40%=16个男生 → 16-5=11 → 答案: 11
第 2 次推理: 40-40×0.6=16男生 → 16-5=11 → 答案: 11
第 3 次推理: 40×(1-0.6)=16 → 16-5=11 → 答案: 11
第 4 次推理: 女生40×0.6=24, 男生40-24=16 → 16-5=11 → 答案: 11
第 5 次推理: 60%是女生→40%是男生→16人→减5→11 → 答案: 11

投票结果: 11(5/5 一致)→ 最终答案: 11

这个例子比较简单,5 次都一致。但在更难的问题上,5 次可能出现 3 次答对、2 次答错的情况,投票后选多数票就能纠正偶发错误。

代价:需要多次调用 API,成本和延迟都会增加。适合准确率要求高、但单次不够稳定的场景。


5. System Prompt:“给模型一个角色”

System Prompt 是模型在处理你的对话之前先"读到"的一段指令。它定义了模型的角色、行为规则和输出风格。

System Prompt:
你是一位资深 Python 开发工程师,专注于代码质量和性能优化。
回答时要:
1. 先指出最关键的问题
2. 给出具体代码示例
3. 解释为什么这样改更好
不要使用过于基础的编程概念解释,假设提问者有 1 年以上编程经验。

为什么有效? System Prompt 相当于给模型"设定了一个人设"。在这个人设下,模型的概率分布会偏向该角色的回答风格——更专业、更聚焦、不废话。

System Prompt 的设计原则

  • 明确角色:不是"你是一个助手",而是"你是一位有 10 年经验的 DevOps 工程师"
  • 明确约束:告诉模型什么该做、什么不该做
  • 明确格式:期望的输出结构是什么样的

常见误区:System Prompt 写得太长太杂,反而让模型"不知道该听哪条"。保持在 200~500 字以内效果最好。


6. Structured Output:“让输出可编程”

当你需要程序化地处理 LLM 的输出时(比如在 Agent 中解析工具调用结果),让模型输出结构化格式非常重要。

Prompt:
分析以下用户反馈,以 JSON 格式输出:
{
  "sentiment": "positive/negative/neutral",
  "key_issues": ["问题1", "问题2"],
  "urgency": "high/medium/low"
}

用户反馈: "你们的 APP 加载速度太慢了,特别是商品详情页,
           经常要等 5 秒以上。客服回复倒是挺快的。"

输出:
{
  "sentiment": "negative",
  "key_issues": ["APP加载速度慢", "商品详情页响应慢"],
  "urgency": "high"
}

在 Agent 开发中的重要性:Agent 需要解析 LLM 的输出并执行后续动作(调用工具、更新状态等)。如果输出是自由文本,解析就不可靠。JSON 或 XML 格式让解析变得确定和可靠。

现在很多模型原生支持 Function Calling / Tool Use,本质上就是内置了结构化输出能力。第二阶段会详细讲这个。


实用技巧汇总

把上面 6 个技巧整理成一张速查表:

技巧适用场景一句话描述
Zero-shot模型已擅长的任务直接给清晰指令
Few-shot需要模型"学会"模式给 3~5 个示例
CoT数学/逻辑/推理加一句"请逐步推理"
Self-Consistency需要高准确率多次推理 + 投票
System Prompt定义角色和风格设定模型"人设"
Structured Output需要程序化解析要求 JSON/XML 输出

组合使用效果最好。一个成熟的 Prompt 通常长这样:

[System Prompt] 你是资深代码审查工程师...
[Few-shot] 示例审查: ...
[CoT] 请逐步分析每个潜在问题...
[Structured Output] 以 JSON 格式输出结果...

下一步

这篇文章覆盖了 Prompt Engineering 的核心技巧。在 Agent 开发中,System Prompt 用来定义 Agent 的行为规范,Structured Output 用来解析 Agent 的决策,CoT 用来提升 Agent 的推理质量——这些技巧你会反复用到。

下一篇我们讲一个特别的话题:推理模型(Reasoning Models)。OpenAI 的 o1/o3、DeepSeek-R1 这些模型,不需要你写 CoT Prompt 就能自主进行长链推理。它们是怎么做到的?和传统 Prompt Engineering 的关系是什么?


推荐资源

动手练习本文所有技巧的最佳起点: