Skip to content

3.3.3 Chain of Thought:让 AI "想一想"再回答

经过本节学习,你将掌握

  • Chain of Thought(CoT)的定义和原理
  • 两种触发 CoT 的方式
  • CoT 真正有效的场景(基于最新研究)
  • 如何写出有效的 CoT 提示词
  • CoT 的局限性和注意事项

什么是 Chain of Thought

Chain of Thought(思维链,简称 CoT)的核心思想是:让 AI 把推理过程写出来,而不是直接给答案

就像数学考试要求「写出解题步骤」一样,当 AI 被要求展示思考过程时,往往能得到更准确的答案。

❌ 直接问:
这个函数的时间复杂度是多少?

✅ 用 CoT:
请分析这个函数的时间复杂度。
首先,识别代码中的循环结构;
然后,分析每个循环的执行次数;
最后,计算总的时间复杂度。

核心洞见:CoT 并非万能

"Chain of Thought 主要在数学和符号推理任务上有显著效果,对其他类型任务的收益有限。" —— 2024 年论文《To CoT or not to CoT?》

这个研究结论很重要。它告诉我们:

任务类型CoT 效果原因
数学计算✅ 显著提升需要多步推理,步骤分解有帮助
逻辑推理✅ 明显提升复杂逻辑需要逐步梳理
代码分析✅ 有帮助涉及多层嵌套和条件判断
文本生成⚠️ 收益有限创意任务不需要严格推理
简单分类❌ 可能更慢增加不必要的步骤

实践建议:不要对所有任务都用 CoT,只在需要推理的场景使用。

两种触发方式

方式一:魔法咒语

最简单的方式,只需在提示词末尾加一句话:

请分析这段代码的性能瓶颈。
Let's think step by step.

或者中文版:

请分析这段代码的性能瓶颈。
让我们一步一步来思考。

这种方式简单,但 AI 的推理步骤可能不够结构化。

方式二:显式步骤分解

更可控的方式,直接告诉 AI 该怎么分步:

请分析这段代码的性能瓶颈。

分析步骤:
1. 首先,识别代码中的循环和递归结构
2. 然后,找出可能的重复计算
3. 接着,检查数据结构的选择是否合理
4. 最后,给出优化建议及预期效果

这种方式的输出更结构化,适合需要特定分析角度的场景。

差提示词 vs 好提示词

场景:分析表单验证逻辑

❌ 差提示词

这个表单验证逻辑有问题吗?

function validateForm(data) {
  if (data.email && data.password && data.password.length >= 6) {
    if (data.email.includes('@')) {
      return true;
    }
  }
  return false;
}

问题:AI 可能只给一个笼统的结论,遗漏一些边界情况。

✅ 好提示词(使用 CoT)

请审查这个表单验证函数,检查是否有遗漏的验证场景。

function validateForm(data) {
  if (data.email && data.password && data.password.length >= 6) {
    if (data.email.includes('@')) {
      return true;
    }
  }
  return false;
}

分析步骤:
1. 首先,列出这个函数当前检查了哪些条件
2. 然后,思考常见的表单验证需要检查什么
3. 接着,对比找出遗漏的验证项
4. 最后,给出改进建议

好提示词的 AI 输出

分析过程:

1. 当前检查的条件:
   - email 存在且非空
   - password 存在且非空
   - password 长度 >= 6
   - email 包含 @ 符号

2. 常见表单验证需要检查:
   - email 格式完整性(@前后都要有内容,要有域名后缀)
   - password 强度(大小写、数字、特殊字符)
   - 防止 SQL 注入和 XSS
   - 空白字符处理

3. 遗漏的验证项:
   - email 格式不完整:"@" 或 "a@" 或 "@b" 都能通过
   - password 只检查长度,没检查强度
   - 没有处理首尾空格
   - 没有验证 email 的域名后缀(如 .com)

4. 改进建议:
   - 使用正则表达式验证 email 格式
   - 添加密码强度检查
   - 对输入做 trim() 处理

适用场景决策表

场景是否使用 CoT理由
计算时间/空间复杂度✅ 使用需要分析循环嵌套
审查代码逻辑✅ 使用需要考虑多个分支和边界
设计数据库表结构✅ 使用需要分析实体关系
调试错误原因✅ 使用需要逐步排查
简单代码格式转换❌ 不用直接转换即可
写一段文案❌ 不用创意任务不需要严格推理
重命名变量❌ 不用任务过于简单

实战示例:待办清单项目

小李想让 AI 帮他分析一个 Bug:任务删除后,有时候页面没有更新。

CoT 提示词

我的待办清单应用有一个 Bug:删除任务后,页面有时候不更新。

以下是相关代码:

// 任务列表状态
const [tasks, setTasks] = useState([]);

// 删除任务
const deleteTask = (id) => {
  tasks.splice(tasks.findIndex(t => t.id === id), 1);
  setTasks(tasks);
}

请帮我分析问题原因。

分析步骤:
1. 首先,理解 React 状态更新的机制
2. 然后,检查这段代码的状态更新方式
3. 接着,找出导致不更新的原因
4. 最后,给出修复方案

AI 输出

分析过程:

1. React 状态更新机制:
   React 通过对比新旧状态的引用来决定是否重新渲染。
   如果状态对象的引用没变,React 认为状态没有改变。

2. 当前代码的问题:
   - splice() 直接修改了原数组
   - setTasks(tasks) 传入的还是同一个数组引用
   - React 对比发现引用相同,不触发重新渲染

3. 问题根因:
   直接修改原数组(mutation)而非创建新数组(immutation)

4. 修复方案:
   使用 filter 创建新数组:
   
   const deleteTask = (id) => {
     setTasks(tasks.filter(t => t.id !== id));
   }

   或者使用展开运算符:
   
   const deleteTask = (id) => {
     const newTasks = [...tasks];
     newTasks.splice(newTasks.findIndex(t => t.id === id), 1);
     setTasks(newTasks);
   }

Concise CoT:简洁版

如果你希望节省 token,可以用简洁版 CoT:

请简要分析这个函数的时间复杂度,用 2-3 句话说明推理过程,然后给出结论。

研究表明,Concise CoT 可以减少约 50% 的输出长度,同时保持大部分推理准确性。

CoT 的局限性

局限表现应对方法
增加输出长度Token 消耗增加 20-80%用 Concise CoT 或限制字数
某些任务反而变差简单任务强行分步可能出错根据场景选择是否使用
推理可能出错某一步错了,后续全错配合 Self-Critique 检查

可复制模板

代码分析 CoT 模板

markdown
请分析以下代码的 [分析目标:性能/安全性/可维护性]:

[代码]

分析步骤:
1. 首先,[第一步分析角度]
2. 然后,[第二步分析角度]
3. 接着,[第三步分析角度]
4. 最后,给出结论和建议

问题排查 CoT 模板

markdown
问题描述:[问题现象]

相关代码/配置:
[代码或配置]

请帮我分析问题原因。

排查步骤:
1. 首先,理解正常情况下应该如何工作
2. 然后,检查当前代码的执行流程
3. 接着,定位可能导致问题的环节
4. 最后,给出修复方案

简洁 CoT 模板

markdown
请分析 [任务]。
用 2-3 句话说明你的推理过程,然后给出结论。

本节要点

CoT 的本质:让 AI 展示推理过程,而非直接给答案

有效场景:数学计算、逻辑推理、代码分析、问题排查

两种触发方式:魔法咒语(简单)vs 显式步骤分解(可控)

不要滥用:简单任务不需要 CoT,反而会降低效率

Concise CoT:在需要节省 token 时使用简洁版

下一节,我们学习如何让 AI 探索多条路径——Tree of Thoughts。