Skip to content

11.3 Bug 猎杀与根因分析

复现 → 定位 → 修复 → 回归,一套不靠猜的调试流程。

读完你能做什么:用真实证据而非猜测来定位 bug,并防止"修了表面漏了根因"。


核心原则

根因分析是幻觉高发区(见 04.3 的类型 5:推理跳跃)。Claude 容易从"看到现象"直接跳到"我觉得是 X 导致的",而 X 只是它的推测。

对策贯穿全程:每一步都要真实证据,区分"观察到的"和"推断的"。


第 1 步:复现(不复现不修)

text
> 不要急着看代码。先帮我稳定复现这个 bug。
  1. 根据报告,写出精确的复现步骤
  2. 实际执行这些步骤,确认能触发
  3. 如果无法稳定复现,告诉我还需要什么信息
  在能稳定复现之前,不要开始猜测原因。

为什么:不能复现的 bug,修了也无法验证是否真修好。复现是一切的前提。


第 2 步:收集证据(观察,不推断)

text
> 现在收集证据,只记录你实际观察到的,不要推断:
  1. 完整的错误信息和堆栈(实际跑出来的,不是回忆的)
  2. 出错时的输入和状态
  3. 相关的日志
  4. 用 git log 看看相关代码最近的改动

用 [观察] 标注每条实际看到的事实,暂时不要下结论。

第 3 步:定位(二分 + 证据)

text
> 基于证据定位根因。要求:
  1. 每个假设都标注 [假设],并说明"如果成立会观察到什么"
  2. 用二分法缩小范围:加日志/断点,实际运行观察,逐步缩小
  3. 每次运行的实际结果标 [观察]
  4. 不要跳到结论——每个推断必须有观察支撑

找到根因后,用一句话说清:根本原因是什么,它如何导致了观察到的现象。

二分定位的实操

text
> 这个函数从输入到出错经过 5 个处理阶段。
  在每个阶段后加一行日志打印关键变量,实际运行,
  告诉我数据在哪一阶段开始不对。不要猜,用日志证据。

第 4 步:区分根因与触发条件

最容易出错的一步。

text
> 明确区分:
  - 触发条件:什么情况下会暴露这个 bug(表面)
  - 根本原因:为什么代码在这种情况下会错(本质)

  举例:
  触发条件 = "订单量超过 1000 时报错"
  根本原因 = "分页逻辑用了 int16 存计数,溢出了"

  只修触发条件(比如限制订单量)不算真修复。
  告诉我你要修的是根因还是触发条件。

第 5 步:修复(先写复现测试)

text
> 修复前,先写一个能复现这个 bug 的测试(现在应该是失败的)。
  然后修复,让测试通过。

<anti_cheat>
不要改测试迁就实现,不要 skip。
修复必须针对根因,如果你只能修触发条件,明确告诉我。
</anti_cheat>

先写复现测试保证了两件事:一是证明你真的理解了 bug,二是防止未来回归。


第 6 步:回归验证

text
> 修复后:
  1. 复现测试通过(贴输出)
  2. 跑完整测试套件,确认没有连带破坏其他功能
  3. 手动复现原始 bug 的步骤,确认不再触发
  4. 想一想:这个根因还可能在别处以类似形式存在吗?如果有,一并检查

第 4 点很有价值 —— 同一个根因(比如"到处都用 int16 存计数")可能潜伏在多个地方。


完整流程模板

text
<task>
排查并修复这个 bug:[粘贴报告]
</task>

<workflow>
1. 复现:写出复现步骤并实际验证能触发。不能复现就停下要信息。
2. 收证据:只记录 [观察] 到的(堆栈、输入、日志、近期改动),不推断。
3. 定位:二分法 + 日志,每个 [假设] 都要 [观察] 支撑,缩小到根因。
4. 区分:明确根因 vs 触发条件。
5. 修复:先写复现测试,再修根因。
6. 回归:复现测试过 + 全套件过 + 手动验证 + 检查同类问题。
</workflow>

<constraints>
- 每步用真实证据,不猜
- 区分 [观察] 和 [推断]
- 修根因,不是掩盖症状
</constraints>

<anti_cheat>
禁止改断言/skip 测试/硬编码。修复针对根因。
</anti_cheat>

疑难 bug 用 Opus + 高 effort

难以定位的 bug(并发、内存、间歇性)值得上最强配置:

bash
claude --model opus --effort high

并善用 /debug

text
> /debug 从现在开始捕获日志。这个 bug 是间歇性的,我会尝试触发它。

独立验证根因

对重要的根因结论,用独立子代理交叉验证(防确认偏误):

text
> 你的结论是"根因是 X"。派 verifier 子代理独立验证这个结论,
  只给它结论和证据,不要给它你的推理过程。

06.4 验证型子代理


常见错误

错误后果对策
不复现就开始猜修了无法验证先稳定复现
从现象直接跳结论修错地方每步要证据
只修触发条件根因还在,换个场景复发区分根因/触发
不写复现测试无法证明修好,未来回归先写复现测试
修完不查同类同样的坑别处还有第 6 步查同类

延伸阅读

基于 VitePress 构建 · 内容采用原作者授权