遇到bug时,传统的方式是:看到症状→猜测原因→改代码→试试。改对了也不知道为什么,改错了继续猜测。
Superpowers的Systematic Debugging技能提供不同的方法:从症状到根因的证据链。
系统化调试的四阶段
- Observe:收集信息,不猜测
- Hypothesize:基于观察提出假设,每个假设有验证方法
- Isolate:控制变量验证,缩小范围
- Fix:基于确定根因修复,写测试验证
每一步都有明确的检查点。不是"试试看",是"验证假设"。
Observe阶段:收集而非猜测
传统方式的Observe是:"看起来像是异步问题"、"可能是数据库连接"、"感觉是缓存没更新"。
这些不是观察,是猜测。真正的观察是收集事实:
- 错误消息的完整内容
- 日志中的异常
- 复现的条件:什么操作导致问题?
- 问题的频率:总是发生?偶尔发生?
- 问题的时间模式:什么时候开始?什么时间点触发?
AI在这一阶段会:
- 读取错误日志
- 搜索相关代码文件
- 收集复现步骤
AI报告的是事实,不是解释。比如:
Observe findings:
- Error message: "Cannot read property 'id' of undefined"
- Stack trace: line 45 in todoStore.js, in deleteTodo function
- Reproduction: delete a task that doesn't exist
- Frequency: always when deleting non-existent task
- Log output: no relevant log before error
这是事实。没有"看起来像是...",没有"可能是因为..."。
Hypothesize阶段:假设附带验证方法
基于观察,提出可能的原因。但每个假设必须有验证方法:
Hypotheses:
H1: deleteTodo doesn't check if task exists before accessing task.id
Verification: Add console.log before line 45 to see if task is undefined
H2: The task ID parameter is wrong type (string vs number)
Verification: Log the type of id parameter
H3: The tasks array is corrupted
Verification: Log tasks array before delete operation
这不是"试试改H1",是"验证H1是否成立"。先验证,再决定修复方向。
Isolate阶段:控制变量验证
逐一验证假设:
Testing H1:
Added console.log before line 45.
Result: task is undefined when deleting non-existent task.
H1 confirmed: deleteTodo accesses task.id without checking existence.
Testing H2:
Logged id parameter type.
Result: id is always number.
H2 rejected: type is not the issue.
Testing H3:
Logged tasks array.
Result: tasks array correct.
H3 rejected: array not corrupted.
确定根因:H1成立。deleteTodo假设task总是存在,没有处理不存在的情况。
Fix阶段:基于根因修复
现在知道根因,修复有明确方向:
// Before
function deleteTodo(id) {
const task = tasks.find(t => t.id === id);
tasks.splice(tasks.indexOf(task), 1); // task may be undefined
}
// After
function deleteTodo(id) {
const task = tasks.find(t => t.id === id);
if (!task) {
return null; // or throw error, depending on spec
}
tasks.splice(tasks.indexOf(task), 1);
return task;
}
但Superpowers要求:修复必须写测试验证。
测试验证
test('deleteTodo returns null for non-existent task', () => {
const result = deleteTodo(999);
expect(result).toBeNull();
});
RED → GREEN循环:写测试,看失败,修复,看通过。
Defense-in-Depth:修复后的防御
修复后不是结束。Superpowers要求添加防御措施:
Defense-in-Depth measures:
1. Add validation at API level: DELETE /todos/:id returns 404 if task not found
2. Add test for 404 response
3. Consider: should other operations also check existence? (GET, PUT)
这不是"额外工作",是防止类似问题的必要步骤。
为什么系统化调试更有效
对比时间:
传统猜测式
- 第1次猜测:加setTimeout → 好了?不确定
- 第2次猜测:改顺序 → 好了?不确定
- 第3次猜测:加缓存 → 好了?不确定
- 问题复发:回到第1次
- 时间:2天,不确定是否修复
系统化调试
- Observe:30分钟
- Hypothesize:15分钟
- Isolate:1小时(验证)
- Fix:30分钟(含TDD)
- Defense:30分钟
- 时间:3小时,确定修复
系统化调试更快,因为每一步有方向,不是盲目尝试。
AI在调试中的角色
AI擅长:
- 收集信息(日志、grep、文件读取)
- 控制变量的实验
- 详细记录过程
AI需要你引导:
- 用系统化方法(不是猜测)
- 提供业务上下文(需求是什么)
- 决策修复方向(多个选项选择哪个)
没有Superpowers,AI会和你一起猜测。有Superpowers,AI遵循系统化流程。
Red Flags:调试中的陷阱
Systematic Debugging技能有Red Flags:
- Jumping from symptom to fix directly
- "This looks like X" without evidence
- Changing multiple things at once
- "Let me try this" without hypothesis
- Fixing without test to verify
- No Defense-in-Depth after fix
如果AI意识到自己在做这些,它会停止,回到正确的阶段。
结论
系统化调试的本质是证据链:
症状 → 观察(事实) → 假设(可验证) → 验证(控制变量) → 根因 → 修复(有测试) → 防御
每一步都有证据,不是猜测。修复后知道为什么有效,不是"试试看好像好了"。
Superpowers强制AI遵循这个流程。AI不会迁就你的"快速修复"倾向。
下一步
下一篇《代码审查:让你的AI助手成为可靠的协作者》将展示Requesting Code Review技能:
- 两阶段审查:Spec Compliance → Code Quality
- 审查者如何独立验证
- 审查循环:问题→修复→重新审查