关于 debug-investigator
debug-investigator 是面向开发者的系统化调试技能,适用于调查不易定位的缺陷。它通过可复现的反馈循环、证据驱动的假设和回归检查来组织排查。
主要功能
- 01记录症状与环境
- 02构建确定性复现循环
- 03生成并验证排序假设
- 04使用 Git 二分与埋点
- 05验证回归测试边界
适用场景
- 01调查间歇性故障
- 02追踪缺少明确堆栈的错误
- 03分析性能回退
- 04定位引入缺陷的代码变更
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mathews-tom/ armory --skill debug-investigator安装后在 Claude Code 中输入/debug-investigator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CHANGELOG.mdLICENSEevals/cases.yamlreferences/bisection-guide.mdhypothesis-templates.mdinstrumentation-points.mdlog-analysis.mdstacktrace-patterns.mdreferences/upstream/provenance.md详细介绍
原文在翻译后有更新,译文可能不是最新。
调试调查员
结构化调试方法,以假设驱动的调查取代临时探索。记录症状,构建确定性的反馈循环,分析证据 (堆栈跟踪、日志、状态),生成按优先级排序的假设,设计二分查找策略, 确定插桩点,并生成最小复现,同时记录每一步,避免重复走入死胡同。
何时使用此技能,而非原生调试: 基础模型可以原生处理简单明了的调试问题(清晰的 堆栈跟踪、明显的错误)。对于需要系统调查的不明显 bug,请使用此技能: 间歇性故障、没有清晰堆栈跟踪的 bug、性能回退,或需要使用 git 二分查找和假设排序的问题。
参考文件
| 文件 | 内容 | 加载时机 |
|---|---|---|
references/stacktrace-patterns.md | 异常分类、回溯阅读、常见 Python/JS 错误特征 | 出现堆栈跟踪或异常时 |
references/hypothesis-templates.md | Bug 类别目录、概率排序、确认/反驳测试 | 始终 |
references/bisection-guide.md | git bisect 工作流、二分查找调试、缩小范围的技巧 | Bug 在某次更改后出现时 |
references/log-analysis.md | 日志模式提取、异常检测、时间线关联 | 有日志输出时 |
references/instrumentation-points.md | 策略性日志放置、断点策略、状态检查技巧 | 需要制定调查计划时 |
前置条件
- git — 用于二分查找和历史分析
- 可访问源代码 — 无法调试不透明二进制文件
- 可复现的环境 — 或至少有错误输出(堆栈跟踪、日志)
项目上下文
深入调查之前,请检查仓库本地的 Agent 上下文:
docs/agents/domain.md中有关CONTEXT.md、CONTEXT-MAP.md和 ADR 查找规则的信息CONTEXT.md或相关上下文的本地词汇表,以了解领域术语docs/adr/和上下文本地的 ADR,了解故障区域附近的决策
在假设、复现名称和预防建议中使用项目词汇表。如果仓库中没有这些文件,照常继续; 不要因上下文设置而阻止调试。
工作流
阶段 1:记录症状
修改代码前,记录可观察到的问题:
- 发生了什么? — 准确描述观察到的行为。“程序崩溃了”不够具体。“使用有效的会话令牌调用
get_current_user()时,auth.py第 42 行引发KeyError('user_id')”才具有可操作性。 - 预期会发生什么? — 定义预期行为。若未知,请明确说明。
- 可复现性 — 总是发生、间歇性发生(注明频率),还是仅发生一次?间歇性 bug 需要采用不同于确定性 bug 的策略。
- 发生时间 — 何时开始出现?与近期更改进行关联:
git log --oneline -20。 如果 bug 在某个特定提交后出现,二分查找是最快的途径。 - 环境 — Python 版本、操作系统、依赖项版本,以及正常环境与故障环境之间的配置差异。
阶段 2:建立反馈循环
在对假设排序或修改生产代码之前,为报告的问题建立快速、确定性的通过/失败信号。循环必须复现用户遇到的症状,而不是相近的问题。
按以下顺序尝试这些切入点:
- 在能够触及该问题的最小公共接口处编写失败测试。
- 使用固定样例输入调用 CLI 或脚本,并断言输出。
- 针对本地服务发送 Curl 或 HTTP 请求,并断言响应、日志或状态。
- 对 UI 问题使用浏览器自动化,并断言 DOM、控制台和网络行为。
- 通过真实代码路径重放跟踪记录、事件载荷、HAR 或日志样例。
- 编写一次性测试框架,启动触发该路径所需的最小子系统。
- 对间歇性故障使用属性测试、模糊测试或压力测试循环。
- 当问题出现在已知正常和异常的修订版本之间时,使用
git bisect run测试框架。
继续之前,先改进循环:
- 缩小设置范围并缓存开销较大的样例,让循环运行得更快。
- 断言确切症状,让循环更精准。
- 固定时间、种子、文件系统路径和网络访问,让循环更具确定性。
- 对间歇性问题,通过重复运行、并发、压力测试或时序探测提高复现率,直到故障频繁到足以进行调试。
如果无法建立可信的循环,请停止并说明尝试过哪些方法。请求缺失的材料:环境访问权限、捕获的载荷、日志、带时间戳的屏幕录制,或临时插桩的权限。不要继续尝试推测性修复。
阶段 3:证据分析
形成假设之前,先检查所有可用证据:
-
堆栈跟踪解读 — 如果存在回溯,请从底向上阅读。最后一帧是错误显现的位置,但原因通常在前面的几帧中。确认:
- 异常类型和消息
- 错误的起源帧与抛出帧
- 任何熟悉的模式(参见
references/stacktrace-patterns.md)
-
日志模式提取 — 搜索日志中的:
- 时间异常(时间戳顺序错乱、间隔)
- 重复错误(同一错误成批出现)
- 未完成的状态转换
- 与外部事件的关联(部署、配置变更)
-
状态检查 — 如果系统正在运行,请检查:
- 故障点的变量值
- 数据库状态(缺失的行、意外的值)
- 配置值(环境变量、配置文件)
- 外部依赖状态(API 可用性、数据库连接)
-
代码差异分析 — 如果问题是最近出现的:
git diff HEAD~5— 有哪些变更?- 重点检查错误调用链涉及的文件
- 查找拼写错误、变量名错误、缺失的空值检查
阶段 4:生成假设
生成排序后的假设——没有假设,绝不开始修复:
-
列出 3–5 个假设,按可能性排序。每个假设必须包含:
- 对问题所在的明确判断
- 支持该判断的证据
- 可以证实该判断的证据(可运行的测试)
- 可以推翻该判断的证据
-
按可能性排序,依据如下:
- 与近期变更的接近程度(大多数问题都出在新代码中)
- 简单性(先考虑拼写错误,再考虑竞态条件)
- 与证据的契合度(该假设能否解释所有症状?)
-
常见问题类别(参见
references/hypothesis-templates.md):- 状态问题:值错误、未初始化、缓存过期
- 逻辑问题:差一错误、运算符错误、条件反转
- 集成问题:API 契约不匹配、序列化错误
- 并发问题:竞态条件、死锁、资源耗尽
- 环境问题:缺少依赖、配置错误、版本不匹配
阶段 5:调查计划
设计具体步骤来测试每个假设:
- 优先测试 H1 — 始终先测试最有可能的假设。设计一个操作来确认或否定它。
- 二分查找 — 如果 bug 出现在某次更改之后,且 H1 不成立:
- 确定已知正常和已知异常的提交
- 运行
git bisect start <bad> <good> - 为每个提交定义测试命令
- 工作流请参阅
references/bisection-guide.md
- 隔离 — 一次移除一个变量:
- 简化输入数据
- 禁用功能或插件
- 用硬编码值替换外部调用
- 在干净的环境中运行
- 插桩 — 添加有针对性的日志记录或断点:
- 调用链中函数的入口和出口处
- 状态变更前后
- 决策点(if/else 分支)处
- 请参阅
references/instrumentation-points.md
阶段 6:执行
执行调查计划,并根据新证据更新假设:
- 一次测试一个变量 — 同时更改多个内容会导致结果无法解读。
- 记录结果 — 记录每项测试揭示的内容,即使结果是否定的。记录无果的调查路径可避免重复尝试失败的方法。
- 更新概率 — 每次测试后重新排列假设的优先级。如果 H1 被否定,则将 H2 作为新的优先项。
- 知道何时升级处理 — 如果所有假设都已排查,说明 bug 属于你尚未考虑的类别。退一步,重新检查各种假设。
阶段 7:记录解决方案
找到根本原因后:
- 根本原因 — 实际问题究竟是什么,具体说明。
- 修复 — 更改了什么,以及原因。
- 预防 — 如何防止问题再次发生(测试、lint 规则、类型检查等)。
- 经验教训 — 总结适用于此特定 bug 之外的经验。
输出格式
## Debug Investigation: {Brief Description}
### Symptom
**Observed:** {What is happening — precise description}
**Expected:** {What should happen}
**Reproducibility:** {Always | Intermittent (~N% of attempts) | Once}
**First noticed:** {Date/time or triggering event}
**Environment:** {Relevant versions and configuration}
### Evidence Analysis
#### Stacktrace
- **Exception:** {type}: {message}
- **Origin:** {file}:{line} in {function}
- **Call chain:** {caller} → {caller} → {failure point}
- **Key insight:** {What the traceback reveals about the cause}
#### Logs
- **Anomaly:** {What is unusual}
- **Timeline:** {When the anomaly started}
- **Correlation:** {Related events}
#### Code Changes
- **Recent commits:** {relevant commits since last known-good state}
- **Files in error path:** {which changed files appear in the traceback}
### Hypotheses
| # | Hypothesis | Likelihood | Confirming Test | Refuting Test |
|---|------------|------------|-----------------|---------------|
| H1 | {Specific claim} | High | {What to check} | {What would disprove} |
| H2 | {Specific claim} | Medium | {What to check} | {What would disprove} |
| H3 | {Specific claim} | Low | {What to check} | {What would disprove} |
### Investigation Plan
#### Step 1: Test H1 — {action}
- **Command/action:** {specific step}
- **If confirmed:** {next action — fix}
- **If refuted:** proceed to Step 2
#### Step 2: Bisection
- **Good commit:** {hash}
- **Bad commit:** {hash}
- **Test:** {command to verify each commit}
- **Command:** `git bisect start {bad} {good}`
#### Step 3: Isolation
- **Remove:** {variable to eliminate}
- **Expected change:** {what should happen}
### Instrumentation Points
1. {file}:{line} — log {variable/state} to observe {what}
2. {file}:{line} — breakpoint to inspect {what}
### Minimal Reproduction
```{language}
# Minimal code that triggers the bug
{code}
解决方案
根本原因: {问题所在} 修复: {更改内容 — 文件:行号、差异摘要} 预防: {新增的测试、lint 规则、类型注解等} 经验教训: {可推广到此 bug 之外的内容}
## Configuring Scope
| Mode | Scope | Depth | When to Use |
|------|-------|-------|-------------|
| `quick` | Single error | H1 test + fix | Clear stacktrace, obvious cause |
| `standard` | Full investigation | 3 hypotheses + bisection plan | Default for non-obvious bugs |
| `deep` | Systemic analysis | 5+ hypotheses + instrumentation + reproduction | Intermittent bugs, no stacktrace, production issues |
## Calibration Rules
1. **Hypotheses before code changes.** Never start modifying code without at least one
explicit hypothesis. "Let me try this" is not debugging — it's guessing.
2. **One variable at a time.** Each investigation step should change exactly one thing.
If you change two things and the bug disappears, you don't know which fixed it.
3. **Document dead ends.** Failed hypotheses are valuable — they narrow the search space.
Record what was tested and what was learned.
4. **Simplest explanation first.** Test typos, wrong variable names, and missing imports
before considering race conditions, compiler bugs, or cosmic rays.
5. **Feedback loop before hypotheses.** If you cannot reproduce the bug with a controlled
pass/fail signal, any fix is speculative. Invest in the loop first.
6. **Root cause, not symptoms.** A fix that addresses the symptom (adding a null check)
without understanding the root cause (why was it null?) leaves the real bug alive.
## Error Handling
| Problem | Resolution |
|---------|------------|
| No stacktrace available | Focus on log analysis and state inspection. Use instrumentation to generate diagnostic output. |
| Bug is intermittent | Add persistent logging at key decision points. Run under stress (high load, concurrent requests) to increase reproduction rate. |
| Cannot reproduce locally | Compare environments systematically: versions, config, data, timing. Use `docker` or VM to mirror production. |
| Multiple hypotheses equally likely | Design a single test that distinguishes between them. Binary decision: "If X, then H1; if Y, then H2." |
| Fix attempted but bug persists | The hypothesis was wrong. Revert the fix, update hypothesis rankings, and proceed to the next hypothesis. Do not stack fixes. |
| Bug is in a dependency | Confirm with a minimal reproduction that uses only the dependency. Check issue trackers. Pin to last known-good version while awaiting upstream fix. |
## When NOT to Investigate
Push back if:
- The error message already contains the fix ("missing module X" → install X)
- The issue is a known environment setup problem (wrong Python version, missing env var)
- The "bug" is actually a feature request or design disagreement — redirect to ADR or discussion
- The code is not under the user's control (third-party SaaS, managed service) — file a support ticket instead
- The user wants to debug generated/minified code — debug the source, not the output