Install
$ agentstack add skill-wenwuzhidao-mattpocock-skills-zh-diagnosing-bugs ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
诊断 Bug
一套应对疑难 bug 的纪律。只有在有明确理由时才跳过某个阶段。
在探索代码库时,阅读 CONTEXT.md(如果存在),以对相关模块建立清晰的心智模型,并检查你所触及区域的 ADR。
阶段 1 — 构建反馈回路
这才是本技能的核心。 其他一切都是机械性的。如果你拥有一个紧凑的、针对 bug 的通过/失败信号——一个会在这个 bug 上变红的信号——你就能找到病因;二分查找、假设检验和插桩都只是在消费这个信号。如果没有它,再怎么盯着代码看也救不了你。
在这里投入不成比例的精力。要激进。要有创意。拒绝放弃。
构建反馈回路的方法——大致按此顺序尝试
- 失败的测试,放在任何能触及 bug 的接缝上——单元、集成、e2e。
- Curl / HTTP 脚本,针对运行中的开发服务器。
- CLI 调用,使用固定输入(fixture),将 stdout 与一个已知良好的快照做 diff。
- 无头浏览器脚本(Playwright / Puppeteer)——驱动 UI,对 DOM/控制台/网络做断言。
- 重放捕获的 trace。 把真实的网络请求 / 载荷 / 事件日志保存到磁盘;在隔离环境中通过代码路径重放它。
- 一次性测试脚手架。 搭起系统的一个最小子集(一个服务,mock 掉依赖),用单次函数调用去触发 bug 的代码路径。
- 属性 / 模糊测试回路。 如果 bug 是「有时输出错误」,就跑 1000 个随机输入,寻找失败模式。
- 二分查找脚手架。 如果 bug 出现在两个已知状态(commit、数据集、版本)之间,就把「在状态 X 启动,检查,重复」自动化,这样你就能用
git bisect run跑它。 - 差分回路。 把同一个输入分别跑过旧版本 vs 新版本(或两套配置),对输出做 diff。
- HITL bash 脚本。 最后的手段。如果必须由人来点击,就用
scripts/hitl-loop.template.sh来驱动他们,让回路仍然是结构化的。捕获的输出会反馈给你。
构建对了反馈回路,bug 就已经解决了 90%。
收紧回路
把回路当作一个产品来对待。一旦你有了一个回路,就收紧它:
- 能让它更快吗?(缓存 setup,跳过无关的初始化,缩小测试范围。)
- 能让信号更锐利吗?(对具体症状做断言,而不是「没崩溃」。)
- 能让它更确定吗?(固定时间,给 RNG 播种,隔离文件系统,冻结网络。)
一个 30 秒且不稳定的回路,比没有回路强不了多少;一个 2 秒且确定的回路才叫紧凑——这是调试的超能力。
非确定性 bug
目标不是干净的复现,而是更高的复现率。把触发器循环 100×、并行化、加压、缩小时间窗口、注入 sleep。50% 复现率的 bug 是可调试的;1% 则不行——不断提高复现率,直到它可调试。
当你真的无法构建回路时
停下来并明确说明。列出你尝试过的一切。向用户请求:(a) 能复现问题的环境的访问权限,(b) 一份捕获的产物(HAR 文件、日志转储、core dump、带时间戳的屏幕录制),或 (c) 添加临时生产环境插桩的许可。在没有回路的情况下,不要继续提出假设。
完成标准——一个会变红的紧凑回路
当回路既紧凑又能变红时,阶段 1 才算完成:你能说出一条命令——一个脚本路径、一次测试调用、一个 curl——它是你已经至少运行过一次的(把调用和它的输出贴出来),并且它是:
- [ ] 能变红——它驱动真实的 bug 代码路径,并对用户的确切症状做断言,因此它能在这个 bug 上变红、在修复后变绿。不是「运行不报错」——它必须能够捕获这个特定的 bug。
- [ ] 确定的——每次运行都给出相同的判定(不稳定的 bug:如上所述,固定且高复现率)。
- [ ] 快速的——以秒计,而非以分钟计。
- [ ] 可由智能体运行——你能无人值守地运行它;只有通过
scripts/hitl-loop.template.sh才会有人介入回路。
如果你发现自己在这条命令存在之前就在读代码建立理论,停下——直接跳到假设正是本技能要防止的失败。 没有能变红的命令,就没有阶段 2。
阶段 2 — 复现 + 最小化
运行回路。看着它变红——bug 出现了。
确认:
- [ ] 回路产生的是用户所描述的失败模式——而不是碰巧就在附近的另一个失败。错的 bug = 错的修复。
- [ ] 该失败在多次运行中可复现(或者,对非确定性 bug 而言,以足够高的复现率复现,可供调试)。
- [ ] 你已捕获确切的症状(错误信息、错误输出、缓慢的耗时),以便后续阶段验证修复是否真的解决了它。
最小化
一旦它变红,就把复现收缩到仍会变红的最小场景。一次一个地裁掉输入、调用方、配置、数据和步骤,每裁一次就重新运行回路——只保留对失败起承重作用的部分。
为什么值得费这个功夫:最小复现缩小了阶段 3 的假设空间(剩下要怀疑的活动部件更少),并成为阶段 5 中干净的回归测试。
当每一个剩下的元素都起承重作用时即完成——移除其中任何一个都会让回路变绿。
在你完成复现且最小化之前,不要继续。
阶段 3 — 提出假设
在测试任何假设之前,先生成3–5 个排序的假设。单一假设的生成会把你锚定在第一个看似合理的想法上。
每个假设都必须是可证伪的:陈述它所做出的预测。
> 格式:「如果 是原因,那么 会让 bug 消失 / 会让它更严重。」
如果你说不出这个预测,那这个假设就只是一种感觉——丢弃它或把它磨锐利。
在测试前把排序好的清单展示给用户。 他们往往有能瞬间重新排序的领域知识(「我们刚给 #3 部署了一个改动」),或者知道他们已经排除的假设。廉价的检查点,节省大量时间。别为此阻塞——如果用户不在(AFK),就按你的排序继续。
阶段 4 — 插桩
每个探针都必须对应阶段 3 中的一个具体预测。一次只改变一个变量。
工具偏好:
- 调试器 / REPL 检查,如果环境支持。一个断点胜过十条日志。
- 有针对性的日志,放在区分各假设的边界上。
- 绝不「把所有东西都打日志然后 grep」。
给每条调试日志打上标签,用一个唯一前缀,例如 [DEBUG-a4f2]。这样最后的清理就变成一次 grep。没打标签的日志会残留;打了标签的日志会被清除。
性能分支。 对于性能回退,日志通常是错误的做法。相反:先建立一个基线测量(计时脚手架、performance.now()、性能分析器、查询计划),然后二分。先测量,后修复。
阶段 5 — 修复 + 回归测试
在修复之前先写回归测试——但仅当存在一个正确的接缝时。
正确的接缝是指测试在调用点上触发真实 bug 模式的那种接缝。如果唯一可用的接缝太浅(当 bug 需要多个调用方时却只有单调用方的测试,或者无法复现触发 bug 的调用链的单元测试),那里的回归测试会给出虚假的信心。
如果不存在正确的接缝,这本身就是一个发现。 记下它。代码库架构正在阻止 bug 被锁定。把这一点标记出来交给下一阶段。
如果存在正确的接缝:
- 把最小复现变成该接缝上的一个失败测试。
- 看着它失败。
- 应用修复。
- 看着它通过。
- 针对原始(未最小化的)场景重新运行阶段 1 的反馈回路。
阶段 6 — 清理 + 复盘
在宣布完成之前必须做到:
- [ ] 原始复现不再复现(重新运行阶段 1 的回路)
- [ ] 回归测试通过(或已记录接缝的缺失)
- [ ] 所有
[DEBUG-...]插桩都已移除(grep那个前缀) - [ ] 一次性原型已删除(或移到明确标记的调试位置)
- [ ] 在 commit / PR 消息中陈述最终被证明正确的那个假设——这样下一个调试者能学到东西
然后问:什么本可以预防这个 bug? 如果答案涉及架构变更(没有好的测试接缝、调用方纠缠、隐藏的耦合),就带着具体细节交给 /improve-codebase-architecture 技能。这个建议要在修复到位之后给出,而不是之前——你现在掌握的信息比开始时多。
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: WenWuZhiDao
- Source: WenWuZhiDao/mattpocock-skills-zh
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.