打破循环 - 深度 Bug 分析
当调试完成后,使用此工具进行深度分析,以打破“修复 Bug → 遗忘 → 重复”的循环。
分析框架
从以下 5 个维度分析刚刚修复的 Bug:
1. 根源类别
此 Bug 属于哪个类别?
| 类别 | 特征 | 示例 |
|---|---|---|
| A. 缺少规范 | 没有关于如何做的文档 | 新功能缺少检查清单 |
| B. 跨层契约 | 层与层之间的接口不明确 | API 返回的格式与预期不符 |
| C. 变更传播失败 | 修改了一处,遗漏了其他处 | 修改了函数签名,遗漏了调用点 |
| D. 测试覆盖率缺口 | 单元测试通过,集成测试失败 | 单独运行正常,组合时出问题 |
| E. 隐式假设 | 代码依赖于未记录的假设 | 时间戳是秒还是毫秒 |
2. 修复失败的原因(如适用)
如果在成功之前尝试了多次修复,分析每次失败:
- 表层修复:修复了症状,而非根本原因
- 范围不完整:找到了根本原因,但没有覆盖所有情况
- 工具限制:grep 未找到,类型检查不够严格
- 思维模型:一直盯着同一层,没考虑跨层问题
3. 预防机制
哪些机制可以防止此类问题再次发生?
| 类型 | 描述 | 示例 |
|---|---|---|
| 文档 | 写下来,让大家知道 | 更新思考指南 |
| 架构 | 从结构上使错误不可能发生 | 类型安全封装 |
| 编译时 | 严格的类型检查,没有漏洞 | 签名变更导致编译错误 |
| 运行时 | 监控、告警、扫描 | 检测孤儿实体 |
| 测试覆盖 | 端到端测试、集成测试 | 验证完整流程 |
| 代码审查 | 检查清单、PR 模板 | “你检查了 X 吗?” |
4. 系统性扩展
此 Bug 揭示了哪些更广泛的问题?
- 类似问题:哪里还可能存在这个问题?
- 设计缺陷:是否存在根本性的架构问题?
- 流程缺陷:开发流程是否有改进空间?
- 知识缺口:团队是否缺失某些理解?
5. 知识沉淀
将洞察固化到系统中:
- 更新
.trellis/spec/guides/思考指南 - 更新相关的
.trellis/spec/文档 - 创建问题记录(如适用)
- 为根本修复创建功能工单
- 根据需要更新检查指南
输出格式
请按以下格式输出分析:
## Bug 分析:[简短描述]
### 1. 根源类别
- **类别**: [A/B/C/D/E] - [类别名称]
- **具体原因**: [详细描述]
### 2. 修复失败的原因(如适用)
1. [第一次尝试]: [失败原因]
2. [第二次尝试]: [失败原因]
...
### 3. 预防机制
| 优先级 | 机制 | 具体行动 | 状态 |
|--------|------|----------|------|
| P0 | ... | ... | TODO/DONE |
### 4. 系统性扩展
- **类似问题**: [列出可能出现类似问题的地方]
- **设计改进**: [架构层建议]
- **流程改进**: [开发流程建议]
### 5. 知识沉淀
- [ ] [需要更新的文档/需要创建的工单]
核心理念
调试的价值不在于修复 Bug,而在于让此类 Bug 永远不再发生。
三个层次的洞察:
- 战术层:如何修复当前 Bug
- 战略层:如何防止此类 Bug
- 哲学层:如何扩展思维模式
30 分钟的分析可节省未来 30 小时的调试时间。
思考框架:贝叶斯推理
当多个根源都似乎合理且证据不完整时,根据新证据按比例更新你的信念,而不是固守最初的假设。
步骤 1:确立先验概率
在调查之前,陈述你的看法及理由:
| 假设 | 先验概率 | 推理 |
|---|---|---|
| H1: [原因 A] | 40% | 这种模式最常见 |
| H2: [原因 B] | 30% | 考虑到环境,合理 |
| H3: [其他] | 30% | 其他情况 |
先验概率之和必须为 100%。如果无法分配概率,请先调查。
步骤 2:观察证据
记录你发现的情况——要具体说明可靠性:
- 你确切观察到了什么?
- 可靠性如何?(测试输出 > 日志消息 > 用户报告 > 直觉)
- 多个假设都能解释这个证据吗?
步骤 3:更新信念
对于每个假设,问:如果此假设为真,观察到这个证据的可能性有多大?
更新的方向比精确计算更重要:
- 证据被 H1 强烈预测 → H1 概率增加
- 证据与 H2 矛盾 → H2 概率降低
- 所有假设下证据等可能 → 无更新
步骤 4:寻找区分性证据
不要收集更多同类证据。找到那些在顶尖假设之间差异显著的证据。
如果 H1 和 H3 接近:"如果 H1 为真,我会看到什么而 H3 为真时看不到?"然后检查。
步骤 5:说明置信度
| 置信度 | 行动 |
|---|---|
| 90%+ | 继续修复并监控 |
| 70-90% | 继续修复,添加后备检查 |
| 50-70% | 先验证假设,再承诺修复 |
| <50% | 需要更多证据,不要猜测 |
当证据不完整时,永远不要表达绝对的确定性。使用“很可能”、“合理但不太可能”、“值得调查”。
常见谬误
| 谬误 | 示例 | 纠正 |
|---|---|---|
| 忽视基础比率 | "测试失败 → 代码出错" | 测试因其他原因失败的频率如何? |
| 确认偏差 | "肯定是竞态条件,我来找竞态的证据" | 主动寻找反对你首要假设的证据 |
| 锚定效应 | "上次是缓存问题,这次可能还是缓存" | 根据当前上下文确立先验概率,而不是昨天的 Bug |
分析后:立即行动
重要:完成上述分析后,你必须立即:
-
更新 spec/guides - 不要只是列出待办事项,要实际更新相关文件:
- 如果是跨平台问题 → 更新
cross-platform-thinking-guide.md - 如果是跨层问题 → 更新
cross-layer-thinking-guide.md - 如果是代码复用问题 → 更新
code-reuse-thinking-guide.md - 如果是特定领域问题 → 更新
backend/*.md或frontend/*.md
- 如果是跨平台问题 → 更新
-
同步模板 - 更新
.trellis/spec/后,同步到src/templates/markdown/spec/ -
提交 spec 更新 - 这是主要产出,而不仅仅是分析文本
如果分析只停留在聊天记录中,它就毫无价值。价值在于更新后的规格文档。