跳转至

诊断 Bug

它的作用

diagnosing-bugs 针对难解缺陷或性能回归执行六阶段诊断:构建复现、最小化它、对假设排序、插桩、用回归测试修复、清理。

它不会让代理在存在紧密反馈循环之前形成理论:一个已命名命令,已经运行过一次,在这个缺陷上变红,修复后变绿。给定一份缺陷报告,编码代理默认会阅读代码并猜测。本技能会阻止这种行为。如果不存在能变红的命令,就没有阶段 2。这个单一关卡正是本技能的目的。一旦循环存在,之后的一切(二分、假设测试、插桩)都是机械化的。

何时使用它

输入 /diagnosing-bugs,或者当任务符合时,代理会自行使用它。它由模型调用,并在 “diagnose” 或 “debug this” 上触发,或在报告某物损坏、抛出异常、失败或缓慢时触发。

在困难问题上使用它:你一眼无法解决的缺陷、间歇性偶发故障、在两个已知正常状态之间引入的回归。它故意缓慢且彻底,因此对于你希望一条消息内得到答案的问题,它是错误的工具。

你的情况 去哪里
一个可以用症状描述的具体缺陷 本技能
一个慢端点,或已知前后对比的耗时回归 本技能。它有性能分支(测量基线,然后二分)
“这个代码库里的瓶颈在哪里?”,没有具体症状 不是本技能。它诊断一个已知故障,不做审计
来自他人的原始缺陷报告,尚未确认或整理 先做 triage
用于回答设计问题的临时代码,而不是追踪缺陷 prototype
以测试优先方式构建计划中的行为 tdd
缺陷修复后,询问什么本可以防止它 retro,在同一会话中运行
不存在能锁定缺陷的良好接缝 improve-codebase-architecture,由你自己启动

紧密循环就是本技能

阶段 1 获得最多努力,因为它是唯一困难的阶段。本技能列出构建循环的方式,大致按偏好顺序:

  1. 在能触及缺陷的任何接缝处的失败测试。
  2. 针对运行中开发服务器的 curl 或 HTTP 脚本。
  3. 带有测试夹具输入的 CLI 调用,并与已知正常快照做差异比较。
  4. 对 DOM、控制台或网络进行断言的无头浏览器脚本。
  5. 重放捕获:保存的请求、载荷或事件日志,在隔离的代码路径中运行。
  6. 临时测试框架:系统的最小子集,一个函数调用。
  7. 属性或模糊测试循环,用于“有时输出错误”。
  8. 可以交给 git bisect run 的二分测试框架。
  9. 差异循环:相同输入,旧版本对比新版本。
  10. 人在环 bash 脚本,最后手段。本技能为此附带 scripts/hitl-loop.template.sh:代理运行脚本,你在终端中跟随提示,你的答案以可解析输出返回。

任意 循环不是目标。紧密意味着:快速(秒级)、确定性(每次运行相同判定)、精准(断言你的确切症状,而不是“没有崩溃”),并且可由代理在你不在时运行。一个 30 秒的不稳定循环几乎不比没有好。对于只偶尔出现的缺陷,目标不是干净的复现,而是更高的复现率:循环触发器、并行化、增加压力、注入休眠,直到偶发率高到足以进行调试。

当代理无法构建一个时,本技能告诉它停止并说明,列出它尝试过什么,并向你请求 环境 访问权限、捕获的工件,或添加临时插桩的许可。无论如何,它都不应继续形成假设。

阶段之间的关卡

阶段是关卡,而不是检查清单。除非某个特定条件为真,代理不能进入一个阶段。

关卡 必须为真的条件
进入阶段 2 一个已命名命令,已经运行并连同其输出粘贴出来,且能在这个缺陷上变红
进入阶段 3 复现已建立并且已最小化:每个剩余元素都是复现缺陷所必需的
进入阶段 4 存在 3–5 个已排序、可证伪的假设,每个都说明其预测,并在测试任何假设之前展示给你
进入阶段 5 探针映射到特定预测,一次一个变量,每个调试日志都有类似 [DEBUG-a4f2] 的标签,因此一次 grep 就能找到它们全部以便清理
完成 原始复现不再复现,插桩已移除,并且提交信息指明最终被证明正确的假设

阶段 5 有一个例外。代理在修复之前编写回归测试,但仅当存在正确接缝时:测试在调用点处验证真实缺陷模式。如果唯一可用的接缝太浅,本技能告诉代理说明这一点,而不是编写一个带来虚假信心的测试。缺失的接缝本身就是一个发现,代理会记录它而不是隐藏它。

常见问题

它会在快速问题上触发,而我只是想要直接答案。 这是本技能被报告最多的问题。尤其是在 GPT-5.6-Sol 上,用户报告它在对问题的普通描述上触发:“模型反而触发了相当正式的 diagnosing-bugs 技能。然后它会继续构建一个复现场景(通常构建一个价值有限的模拟场景),之后才给我回复或建议。这导致了相当大的回复延迟。”四个不同的人在同一 issue #578 上报告了相同问题。已接受的修复是先从更轻量的方法开始,只有当问题需要时才转向完整诊断,但该变更尚未发布。本技能针对 Claude Code 的调用行为调优,而激活阈值更低的 模型 会过于频繁地触发它。在修复发布之前,变通方法是说明你想要什么(“just answer this, don't diagnose”),或在你的 运行框架 中禁用它的模型调用。

我可以把它指向一个代码库,然后问性能问题在哪里吗? 不行。它诊断的是你已经能明确指出的单个故障。它的性能分支用于带有症状的回归问题(先建立基线测量,然后二分查找,先测量后修复),而不是用于主动扫描。针对主动版本的技能曾被提出并关闭;目前没有技能能做到这一点。

它在编写修复之前会停下来询问我吗? 不会。只有第 3 阶段有人工检查点:在测试任何假设之前,会向你展示按优先级排序的假设列表;如果你不在场,代理会按它自己的排序继续。在插桩和修复之间没有关卡,因此代理可能在你认可其根本原因之前就开始编写代码。问题 #124 要求增加该关卡,目前仍处于打开状态。如果你希望有该关卡,在调用技能时说明即可。

我已经对这个 bug 报告运行过 /triage。这是同样的工作吗? 部分是,而且两个技能都没有说明这一点。正如一位读者所说:“Triage 的第 3 步本质上是一个浅层、有边界的 diagnosing-bugs 第 1–2 阶段实例,但两个文件都没有提到对方。” Triage 执行一次有边界的“这是否真的是 bug,以及表面是什么”检查;这个技能执行彻底版本。先运行 triage 不会白费,因为它的验证通常会提供第 1 阶段的大部分原始材料。但请预期这个技能会完整重做那部分工作,并且不要指望有交叉引用来告诉你这一点。

它粘贴的复现输出会泄露机密吗? 可能会。该技能要求代理粘贴调用及其输出,并请求 HAR 文件、日志转储和核心转储等工件。没有任何指令要求代理对其进行脱敏。问题 #674 正是提出了这一点(凭据、令牌、Cookie 和个人数据被复制到聊天、问题或 PR 中),并建议增加脱敏护栏。它仍处于打开状态且未实现。目前请将脱敏视为你的职责,尤其是在输出进入任何公开位置之前。

我的安全扫描器将此技能标记为高风险。 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 是一个可随时使用的独立技能。当某些东西损坏时你启动它,当修复及其回归测试就位时它结束。它不保存状态,也不需要预先设置。ask-matt 将“某处坏了”路由到这里。

两个相邻技能很重要。retro 在它之后:一旦修复就位,就在同一会话中运行它,询问什么本可以防止该 bug,此时会话比开始时拥有更多信息。diagnosing-bugs 本身从不调用 retro,因为 retro 由用户调用。triage 在它之前,用于以他人原始报告形式到达的 bug,并对相同的前两个阶段执行更浅层的版本。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 skills13/skills