系统化调试流程
定义
系统化调试流程,是文中对 systematic-debugging 这项 skill 的概括,指一套被强制执行的调试顺序:在任何修复动作之前,必须先完成根因调查,然后依次进入模式分析、单假设验证、实现修复。
它的核心不是“教你更多 debug 技巧”,而是禁止调试者进入“先猜一个原因、先改一下试试”的默认模式。文中把这种纪律写成一条铁律:
NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST
也就是:没有根因调查,就不允许开始修复。
在本文档中的语境
在Superpowers的工作流里,这套流程被描述为价值最容易被低估的 skill 之一。它服务的不是新功能设计,而是当开发或执行过程中遇到 bug、异常、断链、行为不符合预期时,强制 AI 或工程师脱离“猜着改”的循环。
文中明确对比了两种模式:
- 普通模式:报错后把错误贴给 Claude,让它猜“可能是 X”,改完不对再猜“可能是 Y”,来回反复。
- 系统化调试模式:必须先找到根因,再提出修复。
按照文中给出的数据,普通系统调试平均耗时约 2-3 小时,而采用 systematic-debugging 时常见耗时是 15-30 分钟。文中给出的解释是:默认模式靠猜测推进,而系统化调试用流程强行切断猜测链条。
因此,它与AI编程任务细粒度计划拆解、AI编程Agent工程纪律文本分发机制属于同一类工程纪律:不是扩展模型能力,而是限制模型和人类的随意性。
四阶段顺序
系统化调试流程有四个阶段,而且必须按顺序执行。前一阶段没有完成,不允许进入下一阶段。
- 根因调查
- 模式分析
- 单假设验证
- 实现修复
这个顺序本身就是流程的关键机制。它要求先证明“问题为什么发生”,再验证“这个解释是否成立”,最后才动代码修复,而不是把修复当成探索手段。
Phase 1:根因调查
第一阶段的目标不是立即解决问题,而是先把“发生了什么、稳定如何发生、在哪个边界断掉”弄清楚。
文中要求这一阶段至少覆盖以下动作:
- 完整阅读错误信息:不是扫一眼报错标题,而是把错误全文读完,包括上下文、调用链、异常位置、附带提示。
- 稳定复现步骤:必须把问题变成可重复出现的现象,不能依赖“偶尔出一次”的模糊印象。
- 检查最近的 git 变更:优先排查最近提交、最近修改文件、最近改动路径,因为问题往往与最新变化直接相关。
- 多组件系统在边界处加入诊断日志:如果问题跨越多个组件、服务或模块,不是在一处盲猜,而是在每个边界打诊断日志。
- 先运行一次收集证据,再分析哪里断了:日志不是为了“感觉更安心”,而是为了先得到实际链路证据,再定位具体断点。
这里有一个很重要的边界:Phase 1 不是“看完报错顺便改一下试试”。在这个阶段,重点是采集证据,而不是引入新的修改变量。
对多组件系统,文中的要求尤其严格:应当在每个组件交界处记录输入、输出或状态,让系统跑一次,再依据证据判断到底是请求没发出、数据没到达、格式不匹配,还是中间链路被截断。
Phase 2:模式分析
完成根因调查后,第二阶段不是立刻提出补丁,而是回到同一个代码库里寻找“类似但能正常工作的实现”。
文中的要求包括:
- 找到同一个 codebase 中相似且能跑通的代码路径。
- 把正常实现与出问题实现进行逐项对比。
- 每一个差异,不管多小,都要列出来。
- 不允许主观地说“这个小差异应该没关系”然后忽略。
- 同时理解该实现依赖的前置条件、上下游假设和约束。
这一阶段的核心,不是借鉴“风格”,而是找“模式”。也就是说,系统化调试假设:同一个代码库里已经有可工作的近似解,问题代码与正确代码之间的差异,往往就是根因的重要线索。
文中特别反对一种常见做法:只凭经验挑几个“看起来重要”的不同点。它要求把所有差异显式列出,再通过证据判断哪些差异相关,而不是靠主观预筛。
因此,模式分析既是对根因调查结果的补强,也是对后续假设验证的输入。它把“我觉得这里不对”转成“这里和已知正确实现相比,具体差了哪些条件”。
Phase 3:单假设验证
第三阶段开始进入解释与实验,但仍然不能直接堆叠修改。这里的原则是:一次只验证一个明确假设。
文中的要求非常具体:
- 先写下一个具体假设,形式接近:“我认为 X 是根因,因为 Y。”
- 这个假设必须说明“怀疑对象”和“怀疑理由”,不能只是“试试看会不会好”。
- 然后做一次最小变更验证,只引入足以验证该假设的最小修改。
- 如果验证失败,更换新的假设。
- 不要叠加修改,也不要在第一个假设失败后继续往同一份改动里再塞第二个、第三个猜测。
这是系统化调试最核心的“单变量实验”原则。它把调试从“连续试错”变成“受控实验”:每次改动只服务于一个解释,这样结果才有可解释性。
边界也很明确:如果一次提交里同时改了日志、参数、依赖注入、调用顺序、容错逻辑,那么即使问题消失了,你也不知道到底是哪一个因素起作用;如果问题没消失,也不知道否定的是哪个猜测。系统化调试认为这种做法会把定位工作越做越乱。
Phase 4:实现修复
只有在前面的调查、对比、假设与验证已经完成之后,才进入真正的修复阶段。
这一阶段文中要求:
- 先写一个能复现问题的失败测试。
- 只改一处,避免把多个修复动作混在一起。
- 如果连续 三次修复 都没有解决问题,必须停下来。
- 停下来后要讨论:这是不是已经不是局部 bug,而是架构层面的问题。
这里的“先写失败测试”非常关键,它把修复从“看上去好了”变成“有明确回归保护”。只有先把问题固定成失败用例,后续修复是否成功才有可验证标准。
“只改一处”则延续了上一阶段的单变量原则:真正提交修复时,也不要同时引入一堆无关重构、顺手优化或附带清理,否则一旦结果异常,又会回到无法解释的状态。
三次失败规则
文中特别强调,Phase 4 里最实用的设计就是三次失败规则。
含义不是“永远不能做第四次修改”,而是:如果已经尝试了三次修复仍未解决问题,就不能继续凭惯性做第四次、第五次猜测式修复,必须先停下来,重新讨论问题是不是出在更高层级的模式或架构上。