LLM Chain-of-Thought (CoT) 完全指南:从原理到 Prompt Engineering 最佳实践

一、CoT 的本质:一句话理解

CoT 就是给模型一张草稿纸 —— 把模型的内部隐式推理,转化为外部显式推理。

LLM 是逐 token 生成的(autoregressive),每一个新 token 的概率都依赖于前面所有已生成的 token。CoT 利用这个机制,让模型先把中间推理步骤"写出来"变成 token,这些 token 留在 context 中成为后续生成的输入,相当于给模型提供了"外部工作记忆"。

Autoregressive 的意思就是:模型每次只生成一个 token,而每一个新 token 的生成都依赖于前面所有已经生成的 token。

“Auto"是"自己”,“regressive"是"回归/依赖”。合起来就是"自己依赖自己之前的输出"。

用最直观的比喻理解:想象你在一个字一个字地写一篇文章。你写下第一个字的时候,脑子里只有题目。写第二个字的时候,你看了看第一个字,然后决定第二个字写什么。写第三个字的时候,你看了前两个字… 以此类推。你 永远不会一次性写出整篇文章 ,而是每一步都根据"已经写了什么"来决定"下一个写什么"。

LLM 做的就是完全相同的事情,只不过它写的单位不是"字",而是"token"。

用数学精确描述的话,LLM 生成一个完整序列的过程,本质上是在计算一个 条件概率链

P(整个输出) = P(token₁) × P(token₂|token₁) × P(token₃|token₁,token₂) × ...

展开来看每一步:

第1步:模型看到 [prompt]
       → 计算 P(token₁ | prompt)
       → 采样得到 token₁

第2步:模型看到 [prompt, token₁]
       → 计算 P(token₂ | prompt, token₁)
       → 采样得到 token₂

第3步:模型看到 [prompt, token₁, token₂]
       → 计算 P(token₃ | prompt, token₁, token₂)
       → 采样得到 token₃

...如此循环,直到生成结束符 <EOS>

注意关键点: 每一步都是一次完整的 Transformer 前向传播 。模型把当前所有已知的 token(prompt + 已生成的 token)全部送进 N 层 Transformer,得到下一个 token 的概率分布,然后从这个分布中采样出一个 token。

一个具体的例子:

假设 prompt 是"法国的首都是",模型的生成过程是这样的:

输入:[法国, 的, 首都, 是]
    → Transformer 前向传播 → 下一个 token 的概率分布:
      "巴" (0.92), "法" (0.03), "一" (0.01), ...
    → 采样 → "巴"

输入:[法国, 的, 首都, 是, 巴]
    → Transformer 前向传播 → 下一个 token 的概率分布:
      "黎" (0.97), "塞" (0.01), ...
    → 采样 → "黎"

输入:[法国, 的, 首都, 是, 巴, 黎]
    → Transformer 前向传播 → 下一个 token 的概率分布:
      "。" (0.85), "," (0.05), ...
    → 采样 → "。"

当"巴"被生成后,“黎"的概率从一个不确定的值飙升到 0.97——因为在训练数据中,“巴"后面几乎总是跟"黎”。这就是 autoregressive 的核心: 前面的输出极大地约束了后面的可能性

为什么理解这个概念如此重要?

因为我们今天讨论的所有 prompt engineering 技术,本质上都是在 操控这个逐步生成的过程 。


二、为什么 CoT 有效:底层原理

2.1 Transformer 的固定深度限制

Transformer 的层数 N 是一个固定的架构常数。无论问题多难,模型都只跑这 N 层就输出结果。每一层做的事情是"通过 attention 收集信息 + 通过 FFN 加工信息”,总计算深度固定为 N。

当一个任务需要的推理步骤数超过模型在 N 层内能完成的上限时,模型就会"力不从心"。这就是为什么 LLM 做简单数学很准确,但多位数乘法经常出错。

2.2 CoT 如何突破这个限制

不用 CoT 时,推理深度固定为 N 层(一次前向传播)。使用 CoT 后,每生成一步中间结果,这些 token 会成为下一次前向传播的输入 context,有效计算深度变为 K × N(K 步推理 × 每步 N 层)。

CoT 本质上是把一个固定深度的计算电路,变成了一个深度可以动态增长的计算电路。2023 年论文《Chain-of-Thought Empowers Transformers to Solve Inherently Serial Problems》从数学上严格证明了这一点。

2.3 从 Attention 机制理解

CoT 的每一步中间输出都成了后续步骤的 Key 和 Value。当模型在最后一步需要引用之前的计算结果时,它的 Query 可以直接 attend 到前面步骤中的具体数值位置。这比在隐藏层中从模糊的分布式表示中"回忆"要精确得多。


三、CoT 的三重价值

受益方价值说明
模型自身扩展计算深度突破固定 N 层的推理限制
开发者可调试性检查中间推理步骤,精确定位错误
终端用户可解释性看到"为什么",而不只是"是什么"

四、CoT 的实现方式

4.1 Zero-Shot CoT

不给示例,只用一句触发语:

"Let's think step by step."              ← 最经典,论文验证最有效
"请一步一步地思考这个问题。"
"Think through this carefully."
"Before answering, reason through the problem."

实战技巧:即使 prompt 主体是中文,CoT 触发语用英文往往效果更好。因为 LLM 训练数据中英文的逻辑推理文本占比远高于中文,模型对 “step by step” 的响应更强烈。

适用场景:任务种类多变,难以准备覆盖所有情况的示例时。

4.2 Few-Shot CoT

在 prompt 中给出几个"带推理过程的示例",让模型模仿:

问题:一个水池有两个进水管,A管每小时进3吨,B管每小时进5吨,
同时开两管,几小时能注满40吨的水池?

推理:
- A管速率:3吨/小时
- B管速率:5吨/小时
- 合计速率:3 + 5 = 8吨/小时
- 所需时间:40 ÷ 8 = 5小时
答案:5小时

问题:{new_question}
推理:

Few-Shot CoT 比 Zero-Shot CoT 更可靠,因为你不仅告诉模型"要推理",还展示了推理的格式和粒度

适用场景:你能提供明确优于模型默认行为的高质量示例时。

4.3 Structured CoT(工程化 CoT)

用 XML/JSON 等结构化标签组织推理过程,方便代码解析:

请严格按以下结构输出你的分析:

<thinking>
<symptom_extraction>[提取关键症状]</symptom_extraction>
<severity_assessment>[评估严重程度]</severity_assessment>
<possible_conditions>[列出可能病症]</possible_conditions>
</thinking>

<answer>[最终答案]</answer>

适用场景:AI 应用开发中需要分别处理推理过程和最终答案时。

4.4 Thinking 模型的内置 CoT

Claude Extended Thinking、OpenAI o1/o3、Gemini Thinking Mode 等模型,在训练阶段通过强化学习(RL)专门优化了推理能力。它们自动在 thinking 块中进行深度推理,不需要手动触发 CoT。

与 Prompt-based CoT 的关键区别

维度Prompt-based CoTThinking 模型
推理能力来源模仿训练数据中的推理模式经过 RL 专门优化的推理策略
触发方式需要 prompt 中显式触发自动进行
推理格式控制开发者可完全控制模型自主决定
推理质量依赖 prompt 设计和示例质量通常更强,尤其在复杂任务上

五、CoT Prompt Engineering 最佳实践

实践一:分离推理和最终答案

在生产环境中,推理过程需要存入日志用于调试和审计,最终答案返回给用户。必须用结构化标签分离两者:

请分析这个问题。

<thinking>
[在这里写出你的推理过程]
</thinking>

<answer>
[在这里给出最终答案]
</answer>

实践二:指定推理的维度和方向

不要只说"请推理",要给推理过程设定"路线图":

分析这段代码是否有问题。

请从以下维度逐一分析:
1. 首先检查逻辑正确性——代码是否实现了预期功能
2. 然后检查边界情况——空输入、极大值、并发等
3. 接着检查性能——时间复杂度和空间复杂度是否合理
4. 最后检查安全性——是否存在注入、越权等风险

对每个维度,先给出判断(有问题/无问题),再说明理由。

原理:如果不指定维度,模型可能在第一个发现的问题上展开大量篇幅,后面的维度因为 token 预算耗尽而被忽略。指定维度确保每个关键方面都被覆盖。

实践三:Self-Consistency(自洽性验证)

对高风险推理任务,让模型多次独立推理(需设置 temperature > 0),然后取多数答案。

核心逻辑:每次推理可能走不同的路径,但正确答案更可能被多条路径共同指向。

# 伪代码
answers = [model.generate(question, temperature=0.7) for _ in range(5)]
final_answer = majority_vote(answers)
confidence = count(final_answer) / 5

适用场景:成本翻倍但能提升 5-15% 准确率,仅用于高风险场景(医疗、金融、法律)。

实践四:给模型"反思"的机会

让模型在推理后自我检查:

第一步:写出你的推理过程和初步答案。

第二步:回顾你的推理,检查是否有以下问题:
- 是否有计算错误?
- 是否遗漏了某个条件?
- 结论是否合理?

如果发现问题,请修正并给出最终答案。

原理:反思阶段的 context 中已包含完整推理链,模型可以用新的一轮前向传播来"审视"之前的推理,类似人类做完数学题后验算。

实践五:Thinking 模型的策略调整

对 Claude Extended Thinking、OpenAI o1/o3 等 thinking 模型:

不要手动触发 CoT(“Let’s think step by step”)—— 这可能干扰模型已优化过的推理策略,反而降低效果。

要做的是清晰地描述任务和期望的输出格式:

分析以下代码中的所有安全漏洞。
对每个漏洞给出:漏洞类型、严重程度(高/中/低)、修复建议。
以 JSON 数组格式输出结果。

模型会自动在 thinking 块中做深度推理,你只需关注任务描述的清晰度。


六、Few-Shot CoT 的质量把控

6.1 差的示例比没有示例更糟糕

Few-shot 是一把双刃剑。模型通过 attention 机制进行模式匹配和复制,它不区分"好模式"和"坏模式",只会忠实模仿。

差的示例会造成三种伤害:

推理粒度天花板:示例只展示粗糙两步推理,模型也只做两步,即使问题需要五步。

推理方向误导:示例中的推理路径有跳步或逻辑漏洞,模型会学到这些坏习惯。

格式过度约束:示例全是某种特定格式,模型被锁定在该格式中,即使另一种格式更适合当前问题。

6.2 判断标准

用 Few-Shot CoT 的前提:你能提供明确优于模型默认行为的示例(如特定领域的专家级推理范例,或需要严格遵循的输出格式)。

用 Zero-Shot CoT 更适合:你不确定最优推理路径是什么,或任务种类多变。此时不给示例反而给了模型更大的自由度。

核心原则:如果你自己都不确定"标准答案的推理过程"该长什么样,就别给示例,让模型自己发挥。

6.3 如果必须用 Few-Shot,如何确保质量

推荐方法:“让模型帮你生成和筛选示例”。

  1. 让模型对一批问题做 Zero-Shot CoT
  2. 人工验证哪些推理过程是正确且高质量的
  3. 把验证通过的作为 Few-Shot 示例

这比从零手写示例更有效,因为模型生成的推理风格和它自己的"思维习惯"一致。


七、CoT 的局限和代价

代价说明
Token 消耗增加中间推理步骤消耗计算资源和 API 费用,可能从 50 token 膨胀到 300-500 token
延迟增加更多 token = 更长生成时间,影响实时应用的用户体验
不保证正确模型可以生成逻辑通顺但实际有错误的推理链(faithful reasoning 问题)
简单任务可能反效果对直接检索型问题,强制 CoT 浪费 token 且可能引入"想太多"的干扰

八、CoT 使用决策树

你在用 Thinking 模型(o1/o3、Claude Extended Thinking、Gemini Thinking)吗?
│
├── 是 → 不要手动触发 CoT
│        专注于清晰的任务描述和输出格式
│
└── 否 → 任务需要多步推理吗?
    │
    ├── 否 → 不用 CoT,直接回答
    │        (事实检索、翻译、创意写作等)
    │
    └── 是 → 你有高质量的推理示例吗?
        │
        ├── 是 → 用 Few-Shot CoT
        │        + 指定推理维度
        │        + 分离 thinking 和 answer
        │
        └── 否 → 用 Zero-Shot CoT
                 ("Let's think step by step")
                 │
                 └── 是高风险场景吗?
                     │
                     ├── 是 → 加上 Self-Consistency
                     │        + 反思检查
                     │
                     └── 否 → 基础 CoT 即可

九、与 Prompt Engineering 其他技术的关系

CoT 不是孤立的技术,它与 Prompt Engineering 的其他核心技术协同工作:

Clear Instructions + CoT:指定推理维度就是 Clear Instructions 在 CoT 场景中的应用。

Few-Shot + CoT:Few-Shot CoT 是 Few-Shot 和 CoT 的自然结合——示例中不仅展示输入输出,还展示推理过程。

CoT + 分隔符:用 XML 标签分离推理和答案,是分隔符技术在 CoT 场景中的应用。

CoT 与 Context Engineering 的关系:CoT 生成的推理 token 会占据 context window 空间。在 agent 长期运行的场景中,需要对历史推理过程进行压缩或摘要,避免 context window 溢出。这是 Context Engineering 的核心挑战之一。


十、关键论文参考

  1. Chain-of-Thought Prompting Elicits Reasoning in Large Language Models (Wei et al., 2022) - CoT 的奠基论文
  2. Large Language Models are Zero-Shot Reasoners (Kojima et al., 2022) - 发现 “Let’s think step by step” 的有效性
  3. Self-Consistency Improves Chain of Thought Reasoning (Wang et al., 2023) - 多次采样取多数的方法
  4. Chain-of-Thought Empowers Transformers to Solve Inherently Serial Problems (Feng et al., 2023) - 从理论上证明 CoT 突破固定深度限制