什么是 Chain-of-Thought
2022 年 Google Brain 发表的论文证明:让模型在给出答案前先写出推理步骤,准确率会显著提高。这个简单发现催生了整个 CoT 提示工程体系。
普通提示:
问:Roger 有 5 个网球,买了 2 罐(每罐 3 个),现在有多少?
答:11 ← 直接输出,无推理
CoT 提示:
问:[同题] 请一步步思考。
答:Roger 开始有 5 个。
买了 2 × 3 = 6 个新球。
5 + 6 = 11 个。
答案是 11。 ← 推理后输出
为什么 CoT 有效?
将复杂问题分解成多个中间步骤,每个步骤都在 LLM 的能力范围内。就像人类在草稿纸上演算一样,中间步骤为下一步提供了正确的"起点"。
CoT 的规模效应
研究发现 CoT 对小模型(<10B)效果有限甚至负面,对大模型(>100B)效果显著。o1/R1 等推理模型将 CoT 能力内化为训练目标,突破了这个限制。
Zero-shot CoT:最简单的触发词
2022 年 Kojima 等人发现:在问题末尾添加 "Let's think step by step" 就能显著提升推理准确率,无需任何示例。
import anthropic
client = anthropic.Anthropic()
def zero_shot_cot(problem: str) -> str:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{
"role": "user",
"content": f"{problem}\n\n请一步步思考,然后给出最终答案。"
}]
)
return response.content[0].text
# 有效的 Zero-shot CoT 触发词
triggers = [
"Let's think step by step.", # 英文通用
"请一步步分析这个问题。", # 中文通用
"Think carefully before answering.", # 更谨慎
"Show your reasoning process.", # 显示过程
]
Few-shot CoT:用示例教会推理风格
当 Zero-shot CoT 不够时,提供 2-8 个带推理过程的示例,引导模型模仿你期望的推理方式:
FEW_SHOT_COT_PROMPT = """解题示例:
Q: 一个水箱可以储存 500 升水,现在已装了 60%,再装 50 升后是多少升?
A: 分析:
当前水量 = 500 × 60% = 300 升
加水后 = 300 + 50 = 350 升
最终答案:350 升
Q: 一个工人每天工作 8 小时,月薪 6400 元,时薪是多少?
A: 分析:
每月工作天数 = 22 天(标准)
每月总工时 = 22 × 8 = 176 小时
时薪 = 6400 ÷ 176 ≈ 36.4 元
最终答案:约 36.4 元/小时
现在请解答:
Q: {question}
A: 分析:"""
Few-shot 示例设计原则
示例的推理风格要与你希望模型采用的格式一致。示例数量通常 3-5 个效果最好,太多会占用上下文空间。示例要覆盖不同类型的子问题。
Self-Consistency:多路径投票
单次 CoT 存在随机性。Self-Consistency(Wang et al. 2023)通过多次采样取多数票来提高可靠性:
from collections import Counter
def self_consistency(problem: str, n_samples: int = 5) -> str:
answers = []
for _ in range(n_samples):
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=512,
temperature=0.7, # 适当随机性产生多样路径
messages=[{
"role": "user",
"content": f"{problem}\n\n请一步步思考。最后一行只写最终数字答案。"
}]
)
text = response.content[0].text
answer = extract_final_answer(text) # 提取最后一行答案
answers.append(answer)
# 多数投票
counter = Counter(answers)
majority_answer = counter.most_common(1)[0][0]
confidence = counter[majority_answer] / n_samples
print(f"投票结果: {dict(counter)}, 置信度: {confidence:.0%}")
return majority_answer
Tree-of-Thought:树状搜索
Self-Consistency 是并行的多路径,Tree-of-Thought(Yao et al. 2023)则是主动探索+评估+剪枝的树状搜索:
问题
│
├─ 思路 A(LLM 评估分:7/10)
│ ├─ 继续 A1(分:8/10)→ 继续展开...
│ └─ 继续 A2(分:4/10)→ 剪枝,放弃
│
├─ 思路 B(LLM 评估分:9/10)← 最优
│ └─ 继续 B1(分:9/10)→ 最终答案
│
└─ 思路 C(LLM 评估分:3/10)→ 剪枝,放弃
def tree_of_thought(problem: str, breadth: int = 3, depth: int = 3) -> str:
# 1. 生成多个初始思路
thoughts = generate_thoughts(problem, n=breadth)
for step in range(depth):
# 2. 评估每个思路的价值
scored = [(t, evaluate_thought(problem, t)) for t in thoughts]
# 3. 保留最高分的 top-k 思路(剪枝)
thoughts = [t for t, s in sorted(scored, key=lambda x: -x[1])[:breadth]]
# 4. 展开继续推理
thoughts = expand_thoughts(problem, thoughts)
# 返回最佳路径的答案
return extract_best_answer(problem, thoughts)
ToT 的成本
Tree-of-Thought 需要多次 LLM 调用(breadth × depth 次),成本是普通 CoT 的 5-20 倍。仅在问题真正需要探索多条路径时才使用,例如复杂的代码规划、数学证明等。
Least-to-Most:从简到难分解
对于复杂问题,先问"要解决这个问题,需要先解决哪些子问题",然后逐步构建:
LEAST_TO_MOST = """
第一步:将问题分解为更简单的子问题。
列出所有需要先解决的子问题(从最简单开始):
问题:{problem}
子问题分解:"""
# 先获取子问题,再逐一解决,最后综合
sub_problems = get_sub_problems(problem)
solutions = [solve_sub_problem(sp) for sp in sub_problems]
final = synthesize_answer(problem, solutions)
本章小结
Zero-shot CoT 简单有效(加一句话),Few-shot CoT 教会推理风格,Self-Consistency 用投票提高可靠性,ToT 用树搜索解决复杂问题。下一章解析 DeepSeek-R1 如何用强化学习训练推理能力。