技能手册
13 / 27 AI 工程技能 · 8 分钟读完 · 更新于 2026 年 8 月 24 日

/diagnosing-bugs 技能

从一个失败的复现出发,诊断一个棘手的 bug。

下一篇

安装此技能

npx skills@latest add mattpocock/skills --skill=diagnosing-bugs

然后在你的编码 agent 里输入 /diagnosing-bugs 。

本页目录

它做什么

diagnosing-bugs 对一个棘手的 bug 或一次性能回归运行六阶段诊断:构建一个复现(repro)、把它最小化、给假设排序、插桩(instrumentation)、用回归测试修复、清理。

它不会让 agent 在一条**紧致的(tight)**反馈环(feedback loop)出现之前形成理论:一条点名的命令,已经跑过一次,在这个 bug 上变红、在修好时变绿。拿到一份 bug 报告,编码 agent 默认会读代码然后猜。这个技能阻止那种做法。如果没有一条能变红的命令,就没有第 2 阶段。那道唯一的关卡(gate)就是这个技能存在的目的。一旦反馈环存在,它之后的一切(二分、假设检验、插桩)都是机械性(mechanical)的工作。

什么时候用它

输入 /diagnosing-bugs,或者在任务合适时 agent 会自己去拿它。它由模型(model)调用,会在「diagnose」或「debug this」时触发,也会在报告某样东西坏了、在抛错、在失败或在变慢时触发。

在那些棘手的问题上用它:一个你第一眼看不出解法的 bug、一次间歇性偶发失败(flake)、一次在两个已知良好状态之间引入的回归。它故意做得慢而彻底,所以对于你想在一条消息里得到答案的问题,它是错误的工具。

你的处境该去哪里
一个具体的缺陷,你能把它描述成一个症状这个技能
一个慢的端点,或者一次有已知前后对照的时序回归这个技能。它有一条性能分支(先测一个基线,再二分)
「这个代码库里的瓶颈在哪里?」,没有具体症状不是这个技能。它诊断一个已知的失败,不做审计
一份来自别人的原始 bug 报告,尚未确认或整理先用 triage
为了回答一个设计问题而写的一次性代码,不是追查缺陷prototype
按测试先行构建一个已规划的行为tdd
在修好之后,问本来什么能阻止这个 bugretro,在同一场会话(session)里运行
没有一个好的接缝(seam)可以把 bug 锁住improve-codebase-architecture,由你自己启动

紧反馈环(tight loop)就是这个技能

第 1 阶段得到最多的投入,因为它是唯一困难的阶段。技能按大致偏好顺序列了构建反馈环的方法:

  1. 在能触及这个 bug 的任意接缝上,一个失败的测试。
  2. 针对运行中的开发服务器的一个 curl 或 HTTP 脚本。
  3. 带固定输入的 CLI 调用,与一份已知良好的快照做 diff。
  4. 一个无头浏览器脚本,对 DOM、控制台或网络做断言。
  5. 一次重放的捕获:把保存下来的请求、负载或事件日志,隔离地跑过那条代码路径。
  6. 一个一次性的运行装置:系统的一个最小子集,一次函数调用。
  7. 一个属性测试或模糊测试循环,用于「有时输出是错的」。
  8. 一个可以交给 git bisect run 的二分装置。
  9. 一个差分循环:同样的输入,旧版本对新版本。
  10. 一个人在回路(human-in-the-loop)的 bash 脚本,最后的手段。技能为此附带了 scripts/hitl-loop.template.sh:agent 运行脚本,你在自己的终端里跟着提示走,你的回答以可解析的输出返回。

一条反馈环不是目标。紧致才是:快(以秒计)、确定(每次运行给出同样的裁决)、精准(断言你的确切症状,而不是「没有崩溃」)、并且 agent 能不需要你在场就运行它。一条 30 秒的偶发失败反馈环,比没有好不了多少。对于只在有时候出现的 bug,目标不是一份干净的复现,而是更高的复现率:把触发器循环起来、并行化、加压力、注入 sleep,直到偶发失败率高到足以据此调试。

当 agent 构建不出这样一条反馈环时,技能会让它停下并说出来,列出它试过什么,并向你要环境(environment)访问权限、一份捕获的产物,或者添加临时插桩的许可。它绝不能照样继续去形成假设。

阶段之间的关卡

这些阶段是关卡,不是一张清单。agent 只有在某个具体条件为真时才能进入一个阶段。

关卡必须为真的事
进入第 2 阶段一条点名的命令,已经跑过并连同其输出一起贴出,而且能在这个 bug 上变红
进入第 3 阶段复现被重现并且被最小化:剩下的每一个元素都是重现这个 bug 所必需的
进入第 4 阶段存在 3–5 个排好序、可证伪的假设,每个都说明自己的预测,并在测试任何一个之前给你看过
进入第 5 阶段探针对应一个具体的预测,一次只动一个变量,每一条调试日志都带一个像 [DEBUG-a4f2] 这样的标签,于是一次 grep 就能把它们全部找出来清理
完成原始复现不再重现,插桩已经移除,而且提交信息点名了那个最终被证明正确的假设

第 5 阶段有一个例外。agent 在修复之前写回归测试,但仅当存在一道正确的接缝时才这么做:一道测试能在调用点按 bug 实际出现的方式,真正走一遍那个 bug 模式的接缝。当唯一可用的接缝太浅时,技能会让 agent 说出来,而不是写一个给人虚假信心的测试。缺失的接缝本身就是一条发现,agent 会把它记录下来,而不是藏起来。

常见问题

它会在一些快速问题上触发,而我只想要一个直接答案。 这是关于这个技能报告得最多的问题。尤其是在 GPT-5.6-Sol 上,用户报告说它会因为对一个问题的平白描述而触发:「模型反而触发了那个相当正式的 diagnosing-bugs 技能。然后它继续构建一个复现场景(常常是搭一个价值有限的模拟场景),之后才给我回复或建议。这造成相当长的回复延迟。」有四个人分别在 issue #578 上报告了同样的问题。被接受的修法是先从一个更轻的做法开始,只在问题需要时才进入完整诊断,但那个改动还没有发布。这个技能是按 Claude Code 的调用行为调校的,而一个激活阈值更低的模型会过于频繁地触发它。在修法发布之前,变通办法是说出你想要什么(「只回答这个,别诊断」),或者在你的运行环境(harness)里为它禁用模型调用。

我能把它指向一个代码库,问性能问题在哪里吗? 不能。它诊断一个你已经能点名的失败。它的性能分支用于一个有症状的回归(先建立一个基线测量,再二分,先测量后修复),不是用于主动扫描。一个做主动版本的技能曾被提议并关闭;现在没有技能做这件事。

它在写修复之前会停下来问我吗? 不会。只有第 3 阶段有一个人工检查点:排好序的假设列表会在测试任何一个之前给你看,而如果你不在,agent 会按它自己的排序继续。插桩和修复之间没有关卡,所以 agent 可能在你同意它的根因之前就开始写代码。issue #124 要求加上那道关卡,目前仍然开着。如果你想要它,就在调用这个技能的时候说出来。

我已经对这份 bug 报告跑过 /triage 了。这是重复的工作吗? 部分重复,而两个技能都没有说明这一点。正如一位读者所说:「Triage 的第 3 步本质上是 diagnosing-bugs 第 1–2 阶段的一个浅而有界的实例,但两个文件都没有提到对方。」Triage 做的是一段有界的「这真的是一个 bug 吗,表面在哪里」的检查;这个技能做的是彻底版本。先跑 triage 不会白费,因为它的验证常常给了你第 1 阶段的大部分原料。但要预期这个技能会把那项工作完整重做一遍,并且预期没有任何交叉引用会告诉你这一点。

它贴出来的复现输出会泄漏机密吗? 可能会。技能要求 agent 贴出调用方式及其输出,并要求像 HAR 文件、日志转储和核心转储这样的产物。没有任何指令告诉 agent 对它们做净化。issue #674 正是提出了这个问题(凭据、token、cookie 和个人数据被复制进一场聊天、一个 issue 或一个 PR(pull request)),并提议了一条脱敏护栏。它开着,尚未实现。目前把脱敏当作你自己的责任,尤其是在输出去往任何公开地方之前。

我的安全扫描器把这个技能标成了高风险。 Snyk 会标记它,而那个标记是误报。它是整套技能里唯一一个附带可执行 shell 脚本(hitl-loop.template.sh)的技能,同时还带有运行它以及 curl 一个开发服务器的指令。一个随技能发布的 .sh 文件、运行它的指令,再加上向外发起的 HTTP,足以触发一个静态扫描器。脚本本身大约 30 行 read -r -p 提示,会停下来等待人工输入。扫描器评估的是这个技能可能做什么,而不是一个已被证明的利用方式。

/diagnose 去哪了? v1.0.0 把它改名成了 /diagnosing-bugs。旧名字不再存在。任何串联 /diagnose 的东西(一个包装技能、一条保存的提示词)都需要更新。

它生效的标志

  • 它在提出哪怕一个理论之前,先给你看一条命令和它的红色输出。如果理论先到,那就是这个技能没有在运行。
  • 它重现的失败是你报告的那一个,而不是它在路上碰到的附近某个失败。
  • 它在开始猜测之前先缩小复现,并且能告诉你为什么还需要剩下的每一块。
  • 它在测试其中任何一个之前,先给你看一份排好序的 3–5 个假设的列表,每个假设都带一个你可以证伪的预测。
  • 它添加的每一条调试日志都带一个像 [DEBUG-a4f2] 这样的标签,而当它宣布完成时,对那个标签 grep 会返回空。
  • 提交或 PR 信息点名了哪个假设是对的。
  • 当它无法用一个测试把 bug 锁住时,它会说出来,而不是写一个浅测试。

它在体系中的位置

diagnosing-bugs 是一个随时可用的独立技能(standalone)。当某样东西坏了你就启动它,它在修复及其回归测试就位时结束。它不保留状态,也不需要事先配置。ask-matt 会把「有东西坏了」路由到这里。

有两个邻居要紧。retro 在它之后到来:修复一进来,就在同一场会话里运行它,问本来什么能阻止这个 bug,此时这场会话掌握的信息比开始时更多。diagnosing-bugs 自己从不调用 retro,因为 retro 是由用户调用的。triage 在它之前到来,用于那些以别人的原始报告形式出现的 bug,并把同样的前两个阶段做一个更浅的版本。


原文:aihero.dev/skills-diagnosing-bugs