Chapter 05

思维链提示

让 AI 逐步展示推理过程,大幅提升复杂问题的解答准确率

Chain-of-Thought 是什么?

从直觉到推理

2022 年,Google Brain 研究员 Jason Wei 等人在论文《Chain-of-Thought Prompting Elicits Reasoning in Large Language Models》中证明:当在 prompt 中展示"逐步推理"的示例时,LLM 在复杂推理任务上的准确率大幅提升。这一发现被称为思维链(Chain-of-Thought, CoT)提示法。

核心直觉是:LLM 是一个 token-by-token 的预测机器。当它生成"步骤1...步骤2...步骤3...因此答案是X"时,每个中间步骤都成为后续推理的上下文,降低了跨步骤推理出错的概率。而当它直接生成答案时,所有推理必须在模型内部一次性完成,更容易出错。

标准 CoT vs Zero-shot CoT

标准 CoT
在 prompt 中提供带有推理过程的示例(Few-shot + CoT)。在示例中显式展示"让我逐步思考..."的推理链,引导模型对新问题采用相同的推理模式。效果最佳,但需要人工准备高质量示例。
Zero-shot CoT
只在问题末尾加上一句"让我们一步步思考"(Let's think step by step)。令人惊讶的是,这个简单的添加对许多模型都有显著效果。适合快速使用,无需准备示例。

Zero-shot CoT 的神奇效果

对比没有 CoT 和有 CoT 的效果:

无 CoT(直接回答)

小明有 5 个苹果,给了
小红 2 个,然后他妈妈
又给了他比他现在多
3倍的苹果。
小明现在有多少个苹果?

模型可能直接输出错误答案,如 "15 个"。

有 CoT

小明有 5 个苹果,给了
小红 2 个,然后他妈妈
又给了他比他现在多
3倍的苹果。
小明现在有多少个苹果?

让我们一步步思考:

模型将逐步计算:5-2=3,妈妈给了 3×3=9 个,3+9=12 个。

Few-shot CoT 示例设计

带推理链的示例

# 数学推理任务的 Few-shot CoT

问题:一家店里有 12 个苹果。下午卖出了 8 个,
进货了原来数量的一半。现在有多少个苹果?
思考过程:
- 初始苹果数:12 个
- 卖出后剩余:12 - 8 = 4 个
- 进货量(原来12个的一半):12 / 2 = 6 个
- 最终数量:4 + 6 = 10 个
答案:10 个

问题:一列火车以 60km/h 的速度行驶了 2.5 小时,
然后以 80km/h 的速度又行驶了 1.5 小时。
全程行驶了多少公里?
思考过程:
- 第一段路程:60 × 2.5 = 150 km
- 第二段路程:80 × 1.5 = 120 km
- 总路程:150 + 120 = 270 km
答案:270 km

现在解答:
问题:一个水池可以被 A 管单独注满需 4 小时,
被 B 管单独注满需 6 小时。两管同时开,
几小时可以注满水池?
思考过程:

自洽性采样(Self-Consistency)

多数投票提升准确率

自洽性是对 CoT 的重要改进:对同一个问题生成多个(通常 5-20 个)独立的推理链,然后通过多数投票选出最终答案。实验证明,这比单次 CoT 的准确率显著更高,尤其对于有固定正确答案的任务。

import openai
from collections import Counter

def self_consistency_solve(problem: str, n_samples: int = 5) -> str:
    """通过自洽性采样提升答案准确率"""
    prompt = f"""{problem}

让我们逐步思考,最后给出最终答案(格式:答案:XXX)"""

    answers = []
    for i in range(n_samples):
        response = openai.chat.completions.create(
            model="gpt-4o",
            messages=[{"role": "user", "content": prompt}],
            temperature=0.7  # 高温度确保多样性
        )
        text = response.choices[0].message.content

        # 提取最终答案
        if "答案:" in text:
            answer = text.split("答案:")[-1].strip().split("\n")[0]
            answers.append(answer)

    # 多数投票
    most_common = Counter(answers).most_common(1)
    return most_common[0][0] if most_common else "无法确定"
自洽性的成本与收益

自洽性需要调用 API N 次,成本增加 N 倍。建议只在以下情况使用:高价值决策任务、有标准答案的推理问题、准确率提升对业务有重要影响。对于开放性问题(如文案写作),自洽性投票意义不大。

CoT 在不同任务类型的应用

逻辑推理:公司决策分析

分析以下商业决策,逐步推导最优选择:

公司面临两个选项:
A. 将现有产品价格降低 20%,预计销量增加 35%
B. 推出高端版本,价格是现在的 1.5 倍,
   预计占现有用户的 15%

当前:月销量 10000 件,单价 100 元,利润率 30%

请逐步计算:
1. 当前月利润
2. 方案A的月利润
3. 方案B的月利润(假设不影响原有销量)
4. 综合考虑风险,给出建议

代码调试:逐步定位问题

下面这段 Python 代码有 Bug,请逐步分析:

```python
def find_max_subarray(arr):
    max_sum = 0
    current_sum = 0
    for num in arr:
        current_sum += num
        if current_sum > max_sum:
            max_sum = current_sum
        if current_sum < 0:
            current_sum = 0
    return max_sum

print(find_max_subarray([-3, -1, -4, -1, -5]))
# 期望输出:-1(最大子数组是[-1])
# 实际输出:0
```

请按步骤分析:
1. 代码逻辑是什么算法?
2. 算法在哪个假设上出了问题?
3. 给出修复方案

CoT 的工作原理与局限性

为什么 CoT 有效
LLM 是 token 级别的序列预测模型,每个输出 token 依赖前面所有 token 的上下文。当模型生成中间推理步骤时,这些步骤作为"计算草稿"被写入上下文,帮助后续推理"看到"前置结论,减少了需要在隐式注意力中完成的跨步骤跳跃。可以类比为人类在纸上打草稿解题,而非全靠心算。
CoT 适合的任务
多步骤数学计算、逻辑推理、代码分析、因果推断、规划类任务。这些任务的共同特点是:答案是从一系列中间步骤推导出来的,中间步骤的正确性决定最终答案。CoT 对大模型(70B+)效果尤其显著,对小模型效果有限甚至负面。
CoT 不适合的任务
简单事实检索("谁是中国第一任国家主席"不需要推理链)、创意写作(推理链会限制创造力)、情感分析(过度分析反而失真)。对于简单任务,CoT 反而会引入不必要的复杂度和 token 消耗。
CoT 的错误模式
模型会产生"看似合理但实则错误"的推理链(Plausible-sounding but wrong chains)。这比直接给出错误答案更危险,因为流畅的推理过程会增加用户对错误答案的信任度。因此 CoT 输出仍需要人工或程序验证,不能盲目信任。

进阶:结构化 CoT 模板

# 专业决策分析的结构化 CoT 模板
请使用以下框架分析这个问题:

问题:[描述]

**事实收集**
- 已知信息:
- 未知但重要的信息:

**假设与前提**
- 我做了哪些隐含假设?
- 哪些前提条件可能不成立?

**推理过程**
步骤1:
步骤2:
步骤3:

**结论与置信度**
- 结论:
- 置信度:X%(低/中/高)
- 主要不确定因素:

**建议**
常见误区:CoT 不等于"更长更好"

有些用户误以为推理链越长、步骤越多越好。实际上,冗余的推理步骤会引入更多出错机会。好的 CoT 应当步骤清晰、每步有实际信息增量,而不是用填充性文字堆砌长度。如果发现模型的推理链中出现"因此显然可知..."这样的跳跃性总结,往往是跳步推理的信号,需要提示词中要求"每步都必须基于上一步的结论"。

CoT 的变体技术

Least-to-Most Prompting(由易到难)
将复杂问题分解为子问题序列,从最简单的子问题开始逐步求解,每个子问题的答案作为下一个子问题的输入。两阶段提示:① 分解阶段:"将这个问题分解为需要依次解决的子问题列表";② 求解阶段:逐个求解子问题,每次将前面的答案作为上下文。适合数学证明、编程任务(先实现辅助函数,再实现主函数)。比标准 CoT 更结构化,但需要两轮 API 调用。
Tree of Thoughts(思维树)
不是线性推理链,而是树状搜索空间。每步生成多个候选推理分支,用模型自我评估每个分支的"有希望程度",选择最优分支继续扩展(类似 AlphaGo 的 MCTS)。实现复杂,需要多轮 API 调用和状态管理。适合需要探索多种可能性的任务(如创意写作、战略规划),但成本极高(单个问题可能需要 50+ 次 API 调用)。学术研究热点,生产环境较少用。
Program-Aided Language Models(代码辅助)
让模型生成 Python 代码来执行计算密集型推理步骤,而不是用自然语言描述计算过程。提示词:"用 Python 代码解决这个问题,将中间步骤写成变量"。模型输出代码后,实际执行代码得到结果。优势:数学计算 100% 准确(不会算错 237 × 89);劣势:需要代码执行环境,有安全风险(需要沙箱)。适合数学、数据分析任务。

本章小结

本章核心要点