诊断 Bug
SkillDev toolsGuides your agent through a disciplined diagnosing bugs skill workflow to find root causes of crashes, errors, and slowdowns.
Available today. Use it from your connected AI after setup.
No other account needed.
Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
Then ask your AI: use the 诊断 Bug skill
About this skill
A diagnostic loop for tricky bugs and performance regressions. Use when the user says "diagnose"/"debug this", or reports that something is crashing, erroring, misbehaving, or slow.
What this skill tells your AI
The instructions your AI receives, as published by devcxl/mattpocock-skills-zh in skills/engineering/diagnosing-bugs/SKILL.md and read by ahel’s review.
针对棘手 bug 的一条纪律:只有显式说明正当理由时才能跳过某个阶段。
在探索代码库时,读取 CONTEXT.md(如果存在)以获得相关模块的清晰心智模型,并查看你所触及区域的 ADR。
脱敏
本技能会让你展示命令、输出和捕获的产物。先脱敏所有秘密:用 <REDACTED> 替换。针对环境变量构建循环,这样凭证留在环境中而不是出现在你展示的内容里。捕获的产物可能携带认证头:只引用携带信号的若干行。
如果脱敏后的输出不足以诊断 bug,要明确说明,并请用户提供更多材料。
Phase 1:构建反馈循环
这才是这个技能本身。 其它一切都只是机械动作。如果你对这个 bug 有一条紧密的通过/失败信号(一条会针对_这个_ bug 变红的信号),你就能找到根因;二分、假设检验、插桩都只是这条信号的消费者。如果你没有这条信号,盯着代码看到天荒地老也救不了你。
在这一步投入不成比例的精力。要激进。要有创意。绝不放弃。
构建反馈循环的若干方式(大致按此顺序)
- 失败测试:在能触及 bug 的任何 seam 上写——unit、integration、e2e。
- Curl / HTTP 脚本:针对正在运行的 dev server。
- CLI 调用:使用固定输入,把 stdout 与已知正常快照做 diff。
- 无头浏览器脚本(Playwright / Puppeteer):驱动 UI 并断言 DOM/console/network。
- 重放已捕获的 trace。 把真实的网络请求 / payload / 事件日志落盘,单独通过代码路径重放。
- 一次性 harness。 拉起系统最小子集(一个服务、mock 掉依赖),用一次函数调用就能触发 bug 代码路径。
- 属性 / fuzz 循环。 如果 bug 是"有时输出不对",跑 1000 个随机输入,观察失败模式。
- 二分 harness。 如果 bug 出现在两个已知状态(commit、数据集、版本)之间,自动化"以状态 X 启动、检查、重复",便于
git bisect run。 - 差分循环。 把同一输入分别跑过老版本和新版本(或两种配置),对比输出。
- HITL bash 脚本。 最后的手段。如果必须由人来点击,就用
scripts/hitl-loop.template.sh来驱动_他们_,这样循环仍是结构化的。捕获到的输出再反馈给你。
把反馈循环做对了,bug 已经解决了 90%。
收紧循环
把循环当作产品。一旦你有了_一条_循环,就收紧它:
- 能不能让它更快?(缓存初始化、跳过无关 init、缩小测试范围。)
- 能不能让信号更尖锐?(针对具体症状做断言,而不是"没有崩溃"。)
- 能不能让它更确定?(固定时间、播种 RNG、隔离文件系统、冻结网络。)
30 秒的 flaky 循环只比没有循环强一点点;2 秒、确定性的循环才是真正紧凑的——是调试的超能力。
非确定性 bug
目标不是干净的复现,而是更高的复现率。把触发条件循环跑 100 轮,并行化、增加压力、收紧时窗、注入 sleep。一个 50% 复现率的 flaky bug 是可调试的;1% 不行,所以持续把复现率抬到可调试为止。
当你真的建不出循环时
停下来,并明确说出来。列出你尝试过的所有办法。请用户提供:(a) 能复现该 bug 的环境的访问权限,(b) 一份脱敏后的捕获产物(HAR 文件、日志 dump、core dump、带时间戳的录屏),或 (c) 允许你在生产环境加临时插桩的授权。不要在没有循环的情况下进入空谈理论。
完成判据:一条紧凑、能变红的循环
Phase 1 完成的标志是循环紧凑且能变红:你能点出一条命令(脚本路径、一次测试调用、一条 curl),并至少已经实际跑过一次(给出调用与已脱敏的输出),并且它满足:
- 能变红(Red-capable):驱动真正的 bug 代码路径,并对用户描述的精确症状做断言——所以它能对这个 bug 变红,而修复后变绿。不是"不报错";它必须能_抓住这个具体 bug_。
- 确定性:每次跑都得到同样的判定(flaky bug:按上文固定到高复现率)。
- 快速:秒级,不是分钟级。
- Agent 可跑:你可以在无人值守时跑;只有通过
scripts/hitl-loop.template.sh时才在环里放一个人。
如果你在写出这条命令之前就已经开始读代码、构建理论,停下:跳过假设直接行动正是本技能要防止的失败模式。 没有能变红的命令,就没有 Phase 2。
Phase 2:复现 + 最小化
跑循环。看着它因 bug 出现而变红。
确认:
- 循环产生的是用户所描述的失败模式,而不是恰好在附近的另一种失败。找错 bug = 修错 bug。
- 该失败在多次运行中可复现(或对非确定性 bug 而言,复现率高到可以基于它调试)。
- 你已经捕获到精确症状(错误信息、错误输出、慢的耗时),以便后续阶段可以验证修复确实对症。
最小化
一旦它变红,就把复现例子收缩到仍然会变红的最小场景。逐个裁剪输入、调用者、配置、数据和步骤,每次裁剪后重新跑循环,只保留对失败承重的部分。
为什么要做:最小化的复现例子压缩了 Phase 3 的假设空间(剩下来需要怀疑的活动部件更少),同时在 Phase 5 中又成为干净的回归测试。
完成的标志是剩下的每个元素都承重:移除任何一项都会让循环变绿。
在复现并最小化都完成之前,不要进入下一阶段。
Phase 3:列假设
在测试任何假设之前,生成3–5 个排序后的假设。只生成单个假设会锚定在第一个看似合理的想法上。
每个假设必须可证伪:明确陈述它做出的预测。
格式:"如果 是原因,那么 <改变 Y> 会让 bug 消失 / <改变 Z> 会让它更严重。"
如果说不清预测,那这只是 vibe:丢掉或重新打磨它。
在测试之前把排序后的列表展示给用户。 他们经常拥有些能瞬间重新排序的领域知识("我们刚部署了一个改动到 #3"),或者知道他们已经排除掉的假设。这是个廉价的检查点,但能省下大量时间。别阻塞在用户身上;如果用户 AFK,就按你自己的排序继续推进。
Phase 4:插桩
每一次探测都必须对应 Phase 3 中某个具体的预测。一次只改一个变量。
工具偏好:
- Debugger / REPL 检查:环境支持的话就用。一个断点胜过十条日志。
- 针对性日志:放在能区分假设的边界处。
- 永远不要"全部打日志再 grep"。
为每条调试日志打上唯一前缀,例如 [DEBUG-a4f2]。最后的清理就变成一次 grep。不带前缀的日志会活下来,带前缀的会死掉。
性能分支。 对性能回归,日志通常不合适。改为:先建立基线测量(计时 harness、performance.now()、profiler、查询计划),再做二分。先测,再修。
Phase 5:修复 + 回归测试
把回归测试写在修复之前,但前提是存在正确的 seam。
正确的 seam 是指测试能在调用现场触发的位置真实复现 bug 模式。如果唯一可用的 seam 太浅(单调用方测试,但 bug 需要多个调用方;unit 测试无法复现触发 bug 的整条链路),那里的回归测试只会带来虚假信心。
如果不存在正确的 seam,这就是发现本身。 记下来。代码库架构正在阻止 bug 被锁定。把这标记到下一阶段。
如果存在正确的 seam:
- 把最小化的复现例子变成该 seam 上的一个失败测试。
- 看着它失败。
- 实施修复。
- 看着它通过。
- 重新跑 Phase 1 反馈循环,验证原始(未最小化的)场景。
Phase 6:清理
宣布完成前必须做的事项:
- 原始复现已不再复现(重跑 Phase 1 循环)
- 回归测试通过(或者 seam 缺失已记录在案)
- 所有
[DEBUG-...]插桩已移除(grep该前缀) - 一次性原型已删除(或移到显式标记为 debug 的位置)
- 真正成立的假设写进了 commit / PR 信息,方便下一个调试者学习
Signals
- GitHub stars
- 406
- Forks
- 33
- Last commit
- Sep 2026
Advanced
- Item type
- skill
- Key
diagnosing-bugs-devcxl- Source
- github.com/devcxl/mattpocock-skills-zh