Community编程与开发github.com

mattpocock/diagnosing-bugs

用于处理棘手Bug和性能回退的诊断循环。当用户说“诊断”/“调试这个”,或报告某些东西损坏/抛出错误/失败/缓慢时使用。

diagnosing-bugs 是什么?

该技能为AI代理(如Claude Code)提供了一套系统化的、分阶段的调试方法论,特别适用于那些难以复现或涉及性能回退的复杂Bug。其核心理念是“反馈循环优先”:在深入阅读代码或提出假设之前,代理必须首先构建一个快速、确定性的反馈循环来可靠地触发Bug。技能详细定义了6个强制阶段:构建反馈循环、复现并最小化、提出假设、检测、修复与回归测试、以及清理。它强调通过精心设计脚本或测试来获得紧密的“通过/失败”信号,避免在没有信号的情况下进行无根据的猜测。该技能支持多种平台和环境(CLI、HTTP、浏览器、日志重放等),并包含了处理非确定性Bug和性能问题的具体策略(如并行化、基线测量)。其最终目标是不仅要修复Bug,还要确保代码库中留下回归测试,并记录下正确的假设以帮助未来的调试者。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mattpocock/skills/tree/main/skills/engineering/diagnosing-bugs

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

诊断 Bug 的技艺

一套用于处理棘手 Bug 的规范。除非有明确理由,否则不要跳过任何阶段。

在探索代码库时,请先阅读 CONTEXT.md(如果存在),以建立相关模块的清晰心智模型,并检查你正在触及的区域的 ADR。

脱敏

此技能要求你展示命令、输出和捕获的产物。首先对每个秘密进行脱敏处理:用 <REDACTED> 替换。针对环境变量构建循环,以便凭据保留在环境中,而不是显示在输出中。捕获的产物可能包含认证头:只引用包含信号的行。

如果脱敏后的输出不足以诊断 Bug,请说明情况并询问用户。

阶段 1:构建反馈循环

这是技能的核心。 其他所有内容都是机械性的。如果你有一个紧密的针对该 Bug 的通过/失败信号(一个能针对这个 Bug 变红的信号),你就能找到原因;二分法、假设检验和代码插桩都只是消费这个信号。如果你没有这样一个信号,再多的代码审查也救不了你。

在此处花费不成比例的精力。要激进。要有创意。拒绝放弃。

构建反馈循环的方法,大致按此顺序

  1. 失败的测试,在能触及 Bug 的任何层:单元测试、集成测试、端到端测试。
  2. Curl / HTTP 脚本,针对正在运行的开发服务器。
  3. CLI 调用,使用固定的输入,并将 stdout 与已知正确的快照进行对比。
  4. 无头浏览器脚本 (Playwright / Puppeteer),驱动 UI 并在 DOM/控制台/网络上进行断言。
  5. 重放捕获的追踪。 将真实的网络请求/负载/事件日志保存到磁盘;通过隔离的代码路径重放它。
  6. 临时测试工具。 启动系统的一个最小子集(一个服务,模拟依赖),用单个函数调用就能执行 Bug 代码路径。
  7. 属性 / 模糊测试循环。 如果 Bug 是“有时输出错误结果”,运行 1000 个随机输入并寻找失败模式。
  8. 二分法测试工具。 如果 Bug 出现在两个已知状态(提交、数据集、版本)之间,自动化“在状态 X 启动,检查,重复”的过程,以便你可以用 git bisect run 执行它。
  9. 差异化循环。 对旧版本 vs 新版本(或两种配置)运行相同的输入,并比较输出。
  10. 人机交互 shell 脚本。 最后的手段。如果需要人类手动点击,用 scripts/hitl-loop.template.sh 脚本来驱动他们,使循环仍然结构清晰。捕获的输出会反馈给你。

构建了正确的反馈循环,Bug 就完成了 90% 的修复。

收紧循环

将循环视为一个产品。一旦你有了一个循环,就收紧它:

  • 我能让它更快吗?(缓存设置,跳过无关的初始化,缩小测试范围。)
  • 我能让信号更清晰吗?(针对具体症状进行断言,而不是“没有崩溃”。)
  • 我能让它更确定吗?(固定时间,种子化 RNG,隔离文件系统,冻结网络。)

一个 30 秒的不稳定循环几乎不比没有循环好;一个 2 秒的确定性循环是紧密的,是一个调试超能力。

非确定性 Bug

目标不是一个干净的复现,而是更高的复现率。循环触发 100 次,并行化,增加压力,缩小时间窗口,注入休眠。一个 50% 概率出现的 Bug 是可调试的;1% 则不是,所以持续提高复现率直到它可以被调试。

当你确实无法构建循环时

停下来并明确说明。列出你尝试过的方法。向用户请求:(a) 访问能复现问题的环境,(b) 一个经过脱敏处理的捕获产物(HAR 文件、日志转储、核心转储、带时间戳的屏幕录制),或 (c) 添加临时生产环境插桩的权限。在没构建出循环之前,不要继续提出假设。

完成标准:一个能变红的紧密循环

当循环紧密且具备变红能力时,阶段 1 完成:你可以命名一个命令(脚本路径、测试调用、curl 命令),你已经至少运行过它一次(展示调用和其输出,已脱敏),并且它满足:

  • 具备变红能力:它驱动实际的 Bug 代码路径,并就用户描述的确切症状进行断言,因此它可以针对此 Bug 变红,并在修复后变绿。不仅仅是“运行没有报错”;它必须能够捕获这个特定的 Bug。
  • 确定性:每次运行结果相同(对于不稳定 Bug:固定的、高复现率,如上所述)。
  • 快速:秒级,而不是分钟级。
  • 代理可运行:你可以无人值守地运行它;人机交互环节仅通过 scripts/hitl-loop.template.sh 存在。

如果你发现自己在这个命令存在之前就通过阅读代码来构建理论,请停下来:直接跳到假设正是此技能旨在防止的失败模式。 没有能变红的命令,就没有阶段 2。

阶段 2:复现 + 最小化

运行循环。观察它变红,Bug 出现。

确认:

  • 循环产生了用户描述的失败模式,而不是另一个恰好附近的失败。错误的 Bug = 错误的修复。
  • 失败可以在多次运行中复现(或者,对于非确定性 Bug,可以以足够高的速率复现以便调试)。
  • 你已经捕获了确切症状(错误消息、错误输出、缓慢时间),以便后续阶段可以验证修复是否真正解决了它。

最小化

一旦它变红,将复现缩小到仍然能使它变红的最简场景。一次一个地削减输入、调用者、配置、数据和步骤,每次削减后重新运行循环,只保留对失败起关键作用的部分。

为什么要费心:最小化复现缩小了阶段 3 中的假设空间(剩余的可疑部件更少),并成为阶段 5 中干净的回归测试。

当每个剩余元素都是关键性的时完成:移除其中任何一个都会使循环变绿。

在完成复现和最小化之前,不要继续。

阶段 3:假设

在测试任何一个假设之前,生成 3–5 个排好序的假设。单个假设生成会锚定在第一个看似合理的想法上。

每个假设必须是可证伪的:陈述它所做出的预测。

格式:“如果 是原因,那么 <改变 Y> 将使 Bug 消失 / <改变 Z> 将使 Bug 更严重。”

如果你无法陈述预测,那么这个假设只是一种感觉:放弃它或强化它。

在测试之前向用户展示排序后的列表。 他们通常拥有可以立即重新排序的领域知识(“我们刚刚部署了一个对 #3 的更改”),或者知道他们已经排除过的假设。这是一个廉价的检查点,能节省大量时间。如果用户不在,不要因此阻塞;继续使用你的排序进行工作。

阶段 4:插桩

每次探测必须对应阶段 3 中的一个具体预测。一次只改变一个变量。

工具偏好:

  1. 调试器 / REPL 检查,如果环境支持的话。一个断点胜过十个日志。
  2. 目标明确的日志,放在能区分假设的边界上。
  3. 绝不“记录所有内容然后 grep”。

给每个调试日志打上唯一前缀标签,例如 [DEBUG-a4f2]。最后的清理工作可以变成一个简单的 grep。没有标签的日志会保留;有标签的日志会被删除。

性能分支。 对于性能回退,日志通常是错误的。相反:建立一个基线测量(时间测试工具、performance.now()、分析器、查询计划),然后进行二分查找。先测量,再修复。

阶段 5:修复 + 回归测试

在修复之前编写回归测试,但仅当存在一个正确的切入点时。

正确的切入点是指测试能像在调用点发生的那样,锻炼真实的 Bug 模式。如果唯一可用的切入点太浅(单调用者测试,但 Bug 需要多个调用者;无法复制触发 Bug 的调用链的单元测试),那么那里的回归测试会提供虚假的信心。

如果不存在正确的切入点,这本身就是一个发现。 记录下来。代码库架构阻止了 Bug 被锁定。为此需要在下一阶段标记出来。

如果存在正确的切入点:

  1. 将最小化后的复现转化为在该切入点上的一个失败测试。
  2. 观察它失败。
  3. 应用修复。
  4. 观察它通过。
  5. 针对原始(未最小化)场景重新运行阶段 1 的反馈循环。

阶段 6:清理

在声明完成之前需要完成的工作:

  • 原始复现不再出现(重新运行阶段 1 的循环)
  • 回归测试通过(或记录不存在正确的切入点)
  • 所有 [DEBUG-...] 插桩已移除(使用前缀进行 grep 确认)
  • 临时原型已删除(或移至明确标记的调试位置)
  • 被证明正确的假设已记录在提交/PR 消息中,以便未来的调试者学习

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

mattpocock/ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

mattpocock/caveman

Ultra-compressed communication mode. Cuts token usage ~75% by dropping filler, articles, and pleasantries while keeping full technical accuracy. Use when user says "caveman mode", "talk like caveman", "use caveman", "less tokens", "be brief", or invokes /caveman.

mattpocock/claude-handoff

Hand the current conversation off to a fresh background agent that picks up the work immediately.

mattpocock/codebase-design

Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary.

mattpocock/design-an-interface

Generate multiple radically different interface designs for a module using parallel sub-agents. Use when user wants to design an API, explore interface options, compare module shapes, or mentions "design it twice".

mattpocock/diagnose

Disciplined diagnosis loop for hard bugs and performance regressions. Reproduce → minimise → hypothesise → instrument → fix → regression-test. Use when user says "diagnose this" / "debug this", reports a bug, says something is broken/throwing/failing, or describes a performance regression.

mattpocock/domain-modeling

Build and sharpen a project's domain model. Use when the user wants to pin down domain terminology or a ubiquitous language, record an architectural decision, or when another skill needs to maintain the domain model.

mattpocock/edit-article

Edit and improve articles by restructuring sections, improving clarity, and tightening prose. Use when user wants to edit, revise, or improve an article draft.

mattpocock/git-guardrails-claude-code

Set up Claude Code hooks to block dangerous git commands (push, reset --hard, clean, branch -D, etc.) before they execute. Use when user wants to prevent destructive git operations, add git safety hooks, or block git push/reset in Claude Code.

mattpocock/grilling

Grill the user relentlessly about a plan or design. Use when the user wants to stress-test a plan before building, or uses any 'grill' trigger phrases.

mattpocock/grill-me

Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when user wants to stress-test a plan, get grilled on their design, or mentions "grill me".

mattpocock/grill-with-docs

Grilling session that challenges your plan against the existing domain model, sharpens terminology, and updates documentation (CONTEXT.md, ADRs) inline as decisions crystallise. Use when user wants to stress-test a plan against their project's language and documented decisions.

mattpocock/handoff

Compact the current conversation into a handoff document for another agent to pick up.

mattpocock/implement

Implement a piece of work based on a PRD or set of issues.

mattpocock/implement-spec

Implement a specification in code.

mattpocock/improve-codebase-architecture

Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.

mattpocock/loop-me

Grill me about specs for the workflows I want to build, within this workspace.

mattpocock/migrate-to-shoehorn

Migrate test files from `as` type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace `as` in tests, or needs partial test data.

mattpocock/obsidian-vault

Search, create, and manage notes in the Obsidian vault with wikilinks and index notes. Use when user wants to find, create, or organize notes in Obsidian.

mattpocock/prototype

Build a throwaway prototype to flesh out a design — a runnable terminal app for state/business-logic questions, or several radically different UI variations toggleable from one route.

相关技能