Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when investigating bugs in the project, test failures, or unexpected behavior in code to find root cause systematically
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 109% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 163% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 96% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 137% | 0% |
| case-22 | ✗→✓ | ▲ Improved | 141% | 0% |
使用系统化方法调查 bug、测试失败或意外行为,找到根本原因。
系统化 > 猜测
mermaidflowchart TD A[发现 Bug?] -->|是| D[sw-systematic-debugging] B[测试失败?] -->|是| D C[意外行为?] -->|是| D
当你面对多个失败时,先判断独立性,再选择 Skill:
| 情况 | 选择 | 理由 | |------|------|------| | 只有 1 个失败 | 本技能 | 系统化深度调查 | | 多个失败,但相关(修复一个可能修复其他) | 本技能 | 并行浪费。相关失败应一起调查,避免重复 | | 多个失败,独立(不同子系统、不同根因) | sw-parallel-debugging | 并行分派 Agent,每个调查一个独立问题 | | 多个失败,独立但有共享状态 | 本技能 | 顺序调查,避免 Agent 干扰 |
关键判断: 失败的根因是否可能相同?如果可能相同 → 用本技能一起调查。如果确定不同 → 用 sw-parallel-debugging。
mermaidflowchart TD Start([开始调试]) --> Reproduce[1. 重现问题<br/>建立基线] Reproduce --> Gather[2. 收集信息<br/>日志、错误、状态] Gather --> Form[3. 形成假设<br/>可能的原因] Form --> Test[4. 测试假设<br/>验证或排除] Test --> Confirm{假设确认?} Confirm -->|排除,新假设| Form Confirm -->|确认| Narrow[5. 缩小范围<br/>精确定位] Narrow --> Root[6. 确认根本原因<br/>找到确切原因] Root --> Fix[7. 修复并验证<br/>修复 + 测试] Fix --> Done([结束])
建立稳定基线:
环境信息清单:
markdown## 问题环境 **系统**: macOS 14.x / Ubuntu 22.04 **Python**: 3.11.x **相关库版本**: - xxx: 1.2.3 - yyy: 4.5.6 **重现步骤**: 1. 步骤 1 2. 步骤 2 3. 步骤 3 **预期结果**: xxx **实际结果**: yyy
收集证据:
信息收集命令:
bash# 查看日志 tail -f /var/log/app.log # 查看最近提交 git log --oneline -20 # 查看文件变更 git diff HEAD~5 # 查看环境 pip list | grep xxx python --version
形成假设:
列出可能的原因(按概率排序):
测试假设:
对每个假设:
假设测试表:
| 假设 | 验证方法 | 结果 | 结论 | |------|---------|------|------| | 最近提交引入 | git bisect | 问题在 commit abc123 | ✅ 确认 | | 依赖版本问题 | 降级测试 | 问题依旧 | ❌ 排除 | | 配置错误 | 对比配置 | 发现差异 | ✅ 确认 |
缩小范围:
使用二分法缩小问题范围:
1. 确定问题出现的范围
2. 检查中间点
3. 根据结果缩小到一半
4. 重复直到找到精确位置代码级别调试:
python# 添加日志点 import logging logging.debug(f"变量值: {variable}") # 或使用 pdb import pdb; pdb.set_trace() # 或使用 print(临时) print(f"DEBUG: 执行到这里,x = {x}")
根本原因确认:
在修复前,必须能回答:
添加日志:
pythonimport logging logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) logger.debug("进入函数 process_data") logger.debug(f"输入参数: {data}") logger.debug(f"处理结果: {result}")
日志级别:
使用 pdb:
pythonimport pdb def problematic_function(): x = 1 y = 2 pdb.set_trace() # 断点 z = x + y return z
pdb 命令:
n - 下一行s - 进入函数c - 继续执行p <var> - 打印变量l - 显示代码q - 退出Git bisect:
bash# 开始二分 git bisect start # 标记当前有问题的提交 git bisect bad # 标记已知的最后一个好的提交 git bisect good abc1234 # Git 会自动检出中间提交 # 测试后标记好/坏 git bisect good # 或 bad # 重复直到找到问题提交 # 结束二分 git bisect reset
对比正常和异常情况:
bash# 对比正常和异常输出的差异 diff <(normal_output) <(buggy_output) # 对比配置文件 diff config.good.yml config.bad.yml # 对比数据库状态 diff <(pg_dump db_good) <(pg_dump db_bad)
最小重现:
python# 提取最小重现代码 # 原始复杂代码... def minimal_reproduce(): # 最小输入 input_data = "..." # 关键代码路径 result = process(input_data) # 验证问题 assert result == expected, f"期望 {expected}, 实际 {result}" minimal_reproduce()
| 想法 | 现实 | |------|------| | "我知道问题在哪,直接修复" | 知道概念 ≠ 知道根本原因。没有证据的修复是猜测 | | "跳过重现,直接看代码" | 不能稳定重现的问题无法验证修复。先建立基线 | | "这个假设显然是对的" | 确认偏差:只寻找支持假设的证据。主动寻找反证 | | "先尝试修复看看" | 过早优化:在找到原因前尝试修复 = 可能掩盖真正问题 | | "差不多理解了,可以修" | 部分理解 = 症状治疗。必须能解释所有现象才能修复 | | "修复后不用验证" | 修复后必须验证。未验证的修复可能引入新问题 |
| 借口 | 现实 | |------|------| | "我经验丰富,直觉很准" | 直觉是起点,不是终点。系统化验证比直觉更可靠 | | "重现问题太麻烦" | 不能重现的问题无法验证修复。花时间在重现上是投资 | | "日志够多了" | 关键位置没有日志 = 调试盲区。战略性添加日志 | | "这个修复看起来对" | 看起来对的修复可能只解决症状。必须验证根本原因 | | "环境应该一样" | 开发和生产环境可能不同。记录完整环境信息 |
| 陷阱 | 说明 | 避免方法 | |------|------|---------| | 确认偏差 | 只寻找支持假设的证据 | 主动寻找反证 | | 相关≠因果 | A 发生在 B 前 ≠ A 导致 B | 验证因果关系 | | 过早优化 | 在找到原因前尝试修复 | 先理解,后修复 | | 日志不足 | 关键位置没有日志 | 战略性添加日志 | | 环境差异 | 开发和生产环境不同 | 记录完整环境 |
markdown## 调试报告 **问题**: 用户登录失败 **报告时间**: 2026-04-08 **调试时间**: 30 分钟 ### 现象 - 登录 API 返回 500 错误 - 错误信息:"Internal Server Error" - 影响:所有用户无法登录 ### 环境 - 系统: Ubuntu 22.04 - Python: 3.11.4 - 相关库: Flask 2.3.x, SQLAlchemy 2.0.x ### 重现步骤 1. 调用 POST /api/login 2. 传入有效用户名密码 3. 返回 500 错误 ### 调试过程 **阶段 1: 收集信息** - 查看日志发现 `IntegrityError: null value in column "last_login"` - 检查数据库发现 `last_login` 字段被设为 NOT NULL **阶段 2: 形成假设** 1. 数据库迁移问题 ✅ 2. 代码逻辑错误 ❌ 3. 配置问题 ❌ **阶段 3: 验证假设** - 检查迁移文件:发现最近迁移添加了 `last_login` 字段,默认值为 NULL - 检查模型代码:插入时没有设置默认值 **阶段 4: 根本原因** 数据库迁移添加了 NOT NULL 字段,但模型代码和迁移都没有设置默认值,导致插入失败。 ### 修复 1. 修改迁移文件,添加默认值 2. 修改模型,添加默认值 3. 重新运行迁移 ### 验证 - [x] 修复后登录正常 - [x] 添加回归测试 - [x] 部署到生产环境
前置 Skill:
后续 Skill:
相关 Skill:
Other measured skills in the registry, with their headline benchmark lift.