debug-expert
SKILL.md
调试专家
铁律:先理解,再修改。 禁止在没有复现和定位根因之前就修改代码(猜测式修改往往掩盖真实问题)。
Inputs / Outputs / Gates / Handoffs(统一契约)
- Inputs(最小输入):期望 vs 实际;完整错误信息/日志/堆栈;可复现步骤(如有);最近改动(如有);运行环境信息(OS/版本/命令)。
- Outputs(产物形态):一份可交接的调试记录(结构参考
references/debug-log-template.md),包含假设清单、最小复现、证据链、验证命令与回归建议。 - Gates(继续前必须满足):
- 未完成“假设清单 + 最小复现”前禁止修改代码(保持与本文件 HARD-GATE 一致)。
- 宣称“已修复”前必须运行验证命令并贴出绿色输出或关键结果(保持与本文件后续 HARD-GATE 一致)。
- 通用门控清单可复制使用:
../code-review-expert/references/quality-gates-checklist.md。
- Handoffs(推荐下游):
tdd-master(TDD 开发大师):先写能复现问题的测试,再修复writing-plans(实施计划编写):把修复拆成可执行步骤(适合复杂问题)code-review-expert(代码审查专家):变更后做质量门禁
调试工作流
阶段一:问题理解
收集足够的背景信息(每次最多问 2-3 个问题):
必须了解:
- "期望行为是什么?实际发生了什么?"
- "错误信息或日志是什么?"(要求贴出完整错误,不要省略)
- "最后一次正常工作是什么时候?中间做了什么改动?"
按需追问:
- "是否能稳定复现?还是随机出现?"
- "在什么环境发生的?(本地/测试/生产,什么 OS/版本)"
- "是否有完整的调用堆栈?"
明确禁止:在没有完整错误信息时就开始猜测原因。
阶段二:建立假设
根据现有信息,生成 2-5 个可能的假设(从最可能到最不可能排序):
假设清单:
1. [假设 A]:可能性 高/中/低,理由:[...]
2. [假设 B]:可能性 高/中/低,理由:[...]
3. [假设 C]:可能性 高/中/低,理由:[...]
验证计划:先验证假设 1,因为 [原因]。
思考方向:
- 最近的改动(最可能的原因)
- 环境差异(本地可以,线上不行 → 看配置、依赖、权限)
- 数据问题(特定数据触发 → 看边界条件)
- 并发/时序问题(随机出现 → 看竞态条件)
- 外部依赖(网络/数据库/第三方服务)
阶段三:最小复现
在验证假设之前,先建立最小可复现的测试案例:
# 目标:用最少的代码稳定复现问题
# 好处:
# 1. 确认问题确实存在(而非环境问题)
# 2. 排除无关因素
# 3. 修复后可用作回归测试
# 最小复现示例
def test_bug_reproduction():
# 最简单的触发路径
result = problematic_function(minimal_input)
assert result == expected # 这一行会失败
如果无法复现:
- 说明是环境问题 → 系统对比两个环境的差异
- 说明是特定数据问题 → 询问触发数据的特征
加载 references/root-cause-analysis.md 获取系统化分析工具。
阶段四:定位根因
使用二分法逐步缩小问题范围:
定位策略:
1. 确认问题的边界(从哪里开始出错,到哪里结束)
2. 在中间点添加检查点,判断问题在前半段还是后半段
3. 重复,直到定位到具体的函数/行
常用调试工具:
# Python:pdb 调试
import pdb; pdb.set_trace() # 设置断点
# 或者使用 print 调试(快速但临时)
print(f"DEBUG: variable={variable!r}, type={type(variable)}")
# 日志记录
import logging
logging.debug("状态: %s", state)
# 查看进程状态
ps aux | grep process_name
# 查看端口占用
lsof -i :8080
# 查看系统日志
journalctl -u service_name -n 100 --no-pager
# 查看 Docker 容器日志
docker logs container_name --tail 100
加载 references/debugging-patterns.md 获取特定类型问题的调试模式。
阶段五:修复与验证
定位根因后:
-
制定修复方案(不要第一个想到的方案就是最好的):
- 方案 A:[描述],优点/缺点
- 方案 B:[描述],优点/缺点
- 推荐:[哪个方案,为什么]
-
实施修复
-
验证清单(完成前强制检查,不得跳过):
- 原始问题是否已解决?(运行最小复现案例)
- 是否有其他类似的代码也存在相同问题?(用
rg全局搜索) - 修复是否引入了新问题?(运行完整测试套件)
- 是否需要添加回归测试防止将来重现?
- 根因是否真正解决,而非只是绕过症状?
- 记录(如果是重要的 Bug):
根因:[什么导致的] 触发条件:[什么情况下会触发] 修复方式:[如何修复] 预防措施:[如何防止再次发生]
特殊问题处理
随机/偶发性问题
- 极大概率是竞态条件或内存问题
- 增加日志详细度,在生产环境收集更多信息
- 检查并发访问共享资源的代码
- 使用压测工具提高触发频率
只在特定环境出现
系统对比两个环境:
# 对比环境变量
diff <(env | sort) <(ssh prod 'env | sort')
# 对比依赖版本
pip freeze vs pip freeze(生产)
# 对比配置文件
diff local.env prod.env
性能问题
先测量,再优化,不要靠直觉:
# Python 性能分析
import cProfile
cProfile.run('main_function()', sort='cumulative')
# 简单计时
import time
start = time.perf_counter()
# ...代码...
print(f"耗时:{time.perf_counter() - start:.3f}秒")
红旗警告:当你想跳过流程时
遇到以下想法,立刻停下,回到当前应该所在的阶段:
| 借口 | 现实 |
|---|---|
| "错误很明显,我知道原因,直接改就好" | "明显原因"往往是症状不是根因。30 秒建个假设清单不会耽误你。 |
| "问题太紧急,没时间走流程" | 猜测式修改引入新 bug 比走流程耗时更长。紧急时更要冷静。 |
| "已经修了类似的 bug,这次一样" | 表面相似的 bug 根因可能完全不同。相似性是陷阱。 |
| "最小复现太麻烦,能复现就行" | 无法最小复现 = 无法确认修复 = 留下定时炸弹。 |
| "测试过了,差不多能用" | "差不多"不是通过标准。必须运行验证清单中的每一项。 |
| "这个问题太随机,复现不了" | 随机问题 = 竞态条件/内存问题。不复现不代表可以跳过假设阶段。 |
参考资源
references/root-cause-analysis.md— 根因分析工具和框架references/debugging-patterns.md— 常见问题类型的调试模式
Weekly Installs
3
Repository
programmerantho…g-skillsGitHub Stars
122
First Seen
10 days ago
Security Audits
Installed on
opencode3
gemini-cli3
deepagents3
antigravity3
github-copilot3
codex3