引言
2022 年 5 月,东京大学和 Google 的研究者在 arXiv 上发表了一篇论文,标题平淡无奇:《Large Language Models are Zero-Shot Reasoners》,但它的核心发现令人震惊:只需在提示词后面加上一句「Let's think step by step」,大语言模型在数学推理任务上的准确率就能从 17% 飙升到 78%。
一句话,四个英文单词,在数学推理基准上把模型的表现提高了 4.5 倍。
这不是魔法——这是**思维链(Chain of Thought)**的力量。它属于一种更广泛的技术:少样本学习(Few-Shot Learning)——通过在上下文中给出示例来教模型如何完成任务。
JW1999-
Jason Wei
思维链提示(Chain-of-Thought Prompting)的提出者,现就职于 Meta 超级智能实验室
"生成中间推理步骤可以显著提升大语言模型在复杂推理任务上的表现。"
零样本、单样本、少样本
渐进式理解
Zero-Shot(零样本):
只给指令,不给示例
用户:判断以下评论是正面还是负面:
"这家餐厅太好吃了!"
模型:正面
One-Shot(单样本):
给一个示例
用户:
示例:评论 "难吃到哭" → 负面
判断:评论 "这家餐厅太好吃了!" → ?
模型:正面
Few-Shot(少样本):
给多个示例
用户:
示例1:评论 "难吃到哭" → 负面
示例2:评论 "还会再来" → 正面
示例3:评论 "一般般" → 中性
判断:评论 "这家餐厅太好吃了!" → ?
模型:正面为什么 Few-Shot 有效?
模型在预训练时见过大量文本,但它不知道此时此刻你想要什么格式、什么风格、什么逻辑。示例就像是一份「微型说明书」,告诉模型「我要的是这样的」。
Few-Shot 的本质:
不是在「教」模型新知识
而是在「对齐」模型的行为——告诉它你要什么
模型本来就会做很多事
Few-Shot 帮它选对了方向代码实战
Zero-Shot
python
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "user", "content": """将以下产品评论分类为正面/负面/中性:
"电池续航还可以,但屏幕在阳光下看不清,总体来说凑合用。"
分类:"""}
]
)
# 输出可能不稳定:有时"中性",有时"负面"Few-Shot with Examples
python
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "user", "content": """将以下产品评论分类为正面/负面/中性。
评论:"太棒了!超出了我的预期。" → 正面
评论:"垃圾,千万别买。" → 负面
评论:"还行吧,不好不坏。" → 中性
评论:"用了一个月就坏了。" → 负面
评论:"电池续航还可以,但屏幕在阳光下看不清,总体来说凑合用。" → """}
]
)
# 输出稳定:"中性"(因为示例教会了模型"凑合"类 = 中性)用 API 的 messages 格式做 Few-Shot
python
messages = [
{"role": "system", "content": "你是评论分类助手。"},
# 示例 1
{"role": "user", "content": "评论:太棒了!超出了我的预期。"},
{"role": "assistant", "content": "正面"},
# 示例 2
{"role": "user", "content": "评论:垃圾,千万别买。"},
{"role": "assistant", "content": "负面"},
# 示例 3
{"role": "user", "content": "评论:还行吧,不好不坏。"},
{"role": "assistant", "content": "中性"},
# 真实请求
{"role": "user", "content": "评论:电池续航还可以,但屏幕在阳光下看不清,总体来说凑合用。"},
]
response = client.chat.completions.create(
model="gpt-4o",
messages=messages
)示例选择的艺术
选什么示例?
好示例的特征:
✓ 代表性:覆盖典型场景
✓ 多样性:不同的输入模式
✓ 清晰性:示例之间的区分度高
✓ 正确性:示例的答案必须正确
坏示例的特征:
✗ 太相似:三个示例都是正面评论 → 模型倾向都输出"正面"
✗ 太简单:模型本来就会 → 浪费 token
✗ 有歧义:示例本身的答案有争议
✗ 太多:超过 5-6 个示例,边际收益递减示例数量的权衡
| 示例数 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 0 | 最省 token | 输出不稳定 | 简单任务 |
| 1 | 方向明确 | 格式可能不精确 | 格式简单的任务 |
| 2-3 | 平衡效果好 | 占用一定 token | 大多数场景 |
| 5+ | 非常稳定 | token 成本高 | 格式复杂的任务 |
| 10+ | 收益递减 | 成本高,可能干扰 | 极少需要 |
示例顺序的影响
研究表明:最后几个示例的影响最大(近因效应)
示例序列:A → B → C → [真实输入]
模型最「记得」C 的模式
模型最「容易忘」A 的模式
建议:
- 最典型的示例放最后
- 边界情况的示例放中间
- 格式示例放最前面思维链:让模型「说出思考过程」
Zero-Shot CoT
python
# 不加 CoT
"What is 15% of 87?" → 模型可能直接给错误答案
# 加 CoT
"What is 15% of 87? Let's think step by step."
# 模型输出:
# "Step 1: 15% = 0.15
# Step 2: 0.15 × 87 = 13.05
# Answer: 13.05"Few-Shot CoT
python
messages = [
{"role": "user", "content": "What is 20% of 45?"},
{"role": "assistant", "content": """20% = 0.20
0.20 × 45 = 9
Answer: 9"""},
{"role": "user", "content": "What is 15% of 87?"},
# 模型会模仿示例的推理格式
]为什么 CoT 有效?
没有 CoT:
问题 → [模型内部的黑盒推理] → 答案(可能错)
有 CoT:
问题 → Step 1 → Step 2 → ... → 答案(更可能对)
原因:
1. 生成中间步骤 = 更多的「思考时间」= 更好的推理
2. 你可以检查中间步骤来定位错误
3. 数学上,更多 token = 更多计算 = 更强的推理能力
类比:
你被问 "378 × 492 = ?"
直接说答案 → 很可能猜错
写出计算过程 → 大概率算对Few-Shot 的局限
什么时候 Few-Shot 效果不好:
✗ 任务需要真正的知识更新(示例教不了新知识)
✗ 任务太复杂,几个示例不够
✗ 示例之间有冲突
✗ 上下文窗口不够(示例太多)
什么时候 Few-Shot 不需要:
✓ 任务很简单,Zero-Shot 就够
✓ 模型已经过微调(Fine-tuning)
✓ 可以用 Structured Outputs 强制格式本节小结
| 概念 | 要点 |
|---|---|
| Zero-Shot | 只给指令,不给示例——最省 token |
| Few-Shot | 给 2-5 个示例,显著提升输出稳定性 |
| 示例选择 | 多样性 > 数量,典型示例放最后 |
| Chain of Thought | 让模型输出推理过程,准确率大幅提升 |
| 「Let's think step by step」 | 一句话将推理准确率从 17% 提升到 78% |
思考题
- 为什么示例的顺序会影响模型的输出?这和上下文窗口中信息的位置有什么关系?
- 「Let's think step by step」为什么对数学推理有效,但对情感分析可能没什么帮助?
- 如果你有 100 个高质量的示例,应该全部放进上下文吗?为什么?