# Systematic Debugging

> 当用户要求诊断或修复错误、测试失败、异常行为或性能退化时使用；永久修复前先建立可重复的问题验证路径，无法立即复现时建立线上证据采集路径。

- Skill: `ben2pc/systematic-debugging` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ben2pc/systematic-debugging`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ben2pc/systematic-debugging/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: ben2pc (https://skillmd.com/u/ben2pc)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/ben2pc/systematic-debugging

---


# 系统化调试

用证据定位根因，但让调查深度与问题复杂度匹配。简单问题快速验证；复杂问题逐步缩小；无法立即复现的线上问题先检查可获得的观测证据。

## 从当前请求判定授权范围

- **只诊断**：输出根因、证据与建议，不实施永久修复。
- **诊断并修复**：原始修复请求即为范围内修复授权，确认根因后继续实施并验证，不重复询问。
- 请求与已有上下文仍无法判断范围时才询问；修复授权不自动包含生产变更。
- 线上事故的回滚、关闭功能开关、降级或隔离流量属于**临时缓解**；只有用户已授权事故处置，或已有授权采用的运行手册覆盖该操作时才执行。可逆不等于已授权，只诊断请求不能转成生产操作；恢复后仍须定位根因。

## 1. 明确问题

从已有上下文确认：

- 实际发生了什么，预期是什么？
- 在什么环境、输入和条件下出现？
- 用户观察到的准确症状是什么？
- 已有哪些错误信息、日志、截图、性能数据或复现步骤？

信息充分时直接调查，不为走流程重复提问。证据不足且答案会改变调查方向时，再向用户确认。

## 2. 建立证据路径

### 可以立即复现

永久修复前，先建立一条**可重复的问题验证路径**。它可以是测试、命令、接口请求、浏览器操作或其他可执行步骤，但应当：

- 捕获用户报告的真实症状，而不是附近的另一个错误；
- 能重复运行，并明确判断问题是否仍然存在；
- 尽可能稳定、快速，并可由代理独立执行；
- 记录实际运行结果，不把“理论上能复现”当作证据。

初始路径不必是最小复现。先获得可靠信号，再按需收紧。

### 无法立即复现

低频、环境相关或只在线上出现的问题，改为建立**证据采集路径**：

1. 记录现象、影响范围、已知条件和已经排除的原因。
2. 明确当前要区分的假设，以及什么信号能支持或否定它们。
3. 优先读取已有日志、指标、链路、监控或报警；仍不足时，在授权范围内准备可检查的观测改动，放在最能区分假设的位置。部署或启用继续遵循目标环境权限，不因需要证据自行修改生产。
4. 说明真实观察窗口、等待信号和收到证据后的下一步。需要异步跟进时使用当前可用且已授权的调度能力；只有实际创建成功才称已安排，否则说明仍需如何跟进。

此时明确写出“根因尚未确认”；已建立采集路径不等于问题已修复，不为继续流程猜测根因。

## 3. 按证据选择诊断方法

下面是工具箱，不是固定检查清单。选择成本最低、最能区分当前假设的方法：

- **阅读现有证据**：完整阅读错误、调用栈、相关日志和性能数据。
- **检查近期变化**：查看相关提交、依赖、配置和环境差异。
- **针对性临时日志**：只记录能区分假设的数据流和组件边界，使用统一可搜索标识。
- **断点或交互式调试**：直接观察运行时状态，避免用大量日志间接猜测。
- **Git 二分定位**：已知正常和异常版本时，用 `git bisect` 定位首次引入问题的提交。
- **差异对比**：让相同输入经过正常版本与异常版本，比较输出、状态或性能。
- **请求或事件重放**：保存真实输入，在隔离环境中重放问题路径。
- **性能诊断**：先建立基线，再使用性能分析、时间测量或查询计划定位退化。
- **最小复现**：完整场景过慢、不稳定或变量过多时，逐步删除无关条件。

临时日志、监控和报警不得记录密钥、令牌、个人信息或完整敏感载荷。报警应对应可执行动作，避免形成长期噪声。

## 4. 形成并验证根因假设

- 假设必须能够被证据推翻，并说明它预测会观察到什么。
- 优先验证最能区分多个可能原因的信号。
- 一次只改变一个关键变量；失败后根据新证据更新判断，不叠加未经验证的修复。
- 沿错误数据和调用关系追到最初产生异常的位置，区分症状、直接原因与根因。
- 多次尝试持续暴露不同位置的共享状态或耦合时，暂停补丁式尝试，与用户讨论是否属于架构问题；不使用固定次数代替判断。

## 5. 修复与验证

仅在用户授权修复且根因已经确认后执行；进入永久修复实现时调用 `test-driven-development` 判断证据寿命，选择当前证据以及是否需要永久保护：

1. 只有永久保护门槛成立且存在能够覆盖真实问题的正确测试接缝时，才把问题固化为失败测试。
2. 不满足永久保护门槛或没有正确接缝时，记录这一限制，使用可重复的问题验证路径，不添加无法捕获真实问题的浅层测试。
3. 修复已经确认的根因，不混入无关重构。
4. 重新运行最初的问题验证路径，确认用户报告的原始症状消失。
5. 运行受影响范围的回归检查。
6. 删除临时日志、脚本和诊断代码；确有长期价值的观测项应明确保留理由。

## 输出

简单缺陷用现象、根因、修改和验证的短叙述即可。复杂调查按需补充问题验证或证据采集路径、关键证据链、未知项、剩余风险和等待条件，不强制固定章节。

只诊断时报告证据与建议，不把建议方案写成已完成修改；临时缓解、已建立采集路径和根因修复分别说明实际状态。

