名称: 故障排除 描述: | 使用结构化故障排除方法进行系统化的调试和问题诊断 适用于任何领域 - 技术问题、过程故障、系统问题或一般障碍。当用户报告错误、描述故障、遇到意外行为或需要帮助诊断根本原因时使用。触发词包括“调试这个”、“故障排除”、“为什么这个不工作”、“遇到错误”、“有什么问题”或任何问题描述。 允许工具: “*”
故障排除与调试技能
引导用户通过系统化的问题诊断和解决,使用适用于任何领域的结构化方法。
快速启动工作流程
当故障排除请求到达时,遵循这个系统化方法:
- 理解 - 什么是期望与实际,何时开始,什么变化
- 收集 - 收集诊断信息(日志、错误、环境、重现步骤)
- 假设 - 列出可能原因按概率排序
- 设计 - 创建隔离变量的测试
- 测试 - 系统化执行,记录结果
- 识别 - 区分症状与根本原因
- 验证 - 确认修复解决问题
- 文档 - 记录解决方案供未来参考
何时使用此技能
激活用于涉及以下请求:
- “调试这个…” / “故障排除…”
- “为什么这个不工作…” / “遇到错误…”
- “有什么问题…” / “如何修复…”
- 任何问题描述或故障报告
- 意外行为或失败
- 性能问题或退化
- 间歇性问题
问题理解阶段
基本首要问题
在深入解决方案前,收集关键上下文:
问题描述:
- 你试图做什么?(期望行为)
- 实际发生什么?(实际行为)
- 你看到什么错误消息或症状?
- 你能一致重现吗?
时间线:
- 这是何时开始的?
- 它曾经正常工作过吗?
- 最近什么变化了?(代码、配置、环境、数据、依赖)
范围:
- 这每次都发生还是间歇性?
- 这对每个人都发生还是只对某些用户?
- 这在所有环境都发生还是只在特定环境?
环境:
- 什么系统/平台/版本?
- 配置是什么?
- 依赖及其版本是什么?
重现:
- 重现的确切步骤是什么?
- 你能提供一个演示问题的最小示例吗?
- 最简单的失败案例是什么?
问题类型分类
分类以指导故障排除方法:
按一致性:
- 一致 - 每次都发生(更容易调试)
- 间歇 - 有时发生(更难,通常定时/竞争条件)
- 渐进 - 随时间恶化(资源泄漏、退化)
按历史:
- 回归 - 以前工作,最近坏了(什么变化了?)
- 从未工作 - 新功能/设置(设计或设置问题)
按范围:
- 通用 - 到处发生(可能代码/逻辑问题)
- 环境相关 - 在特定环境发生(配置、依赖、资源)
- 用户特定 - 对特定用户发生(权限、数据、状态)
按领域:
- 代码/逻辑 - 软件错误、算法错误
- 配置 - 设置、参数、环境变量
- 数据 - 输入验证、损坏、格式问题
- 基础设施 - 网络、存储、资源、服务
- 集成 - API失败、服务依赖
- 人工过程 - 工作流、通信、缺失步骤
分类帮助优先假设和诊断方法。
诊断信息收集
日志和错误分析
错误消息:
- 复制确切的错误文本(不要转述)
- 注意提供的错误代码/类型
- 识别堆栈跟踪或错误位置
- 查找嵌套/链式错误(根本原因通常更深)
日志检查:
- 检查时间戳(问题何时发生)
- 查找失败时间附近的错误、警告、异常条目
- 通过日志追踪请求/操作ID
- 检查模式(重复错误、序列)
- 回顾失败前的日志(系统在做什么)
系统状态:
- 资源使用(CPU、内存、磁盘、网络)
- 进程/服务状态
- 最近的重启或崩溃
- 系统事件日志
环境文档
捕获完整环境图片:
版本:
- 应用程序/服务版本
- 运行时/解释器版本(Node、Python、Java等)
- 操作系统版本
- 依赖版本(库、包)
- 数据库/缓存版本
配置:
- 配置文件及其值
- 环境变量
- 功能标志或切换
- 与默认不同的设置
基础设施:
- 网络拓扑
- 服务端点和连接性
- 防火墙/安全规则
- 负载均衡器、代理
- DNS配置
重现案例开发
目标:找到最小可重现示例(MRE)
过程:
- 从清洁状态记录确切步骤
- 剥离非必要步骤
- 最小化数据/输入到最简单案例
- 尽可能移除依赖
- 验证是否仍能重现
良好重现案例:
- 任何人都能跟随步骤看到相同问题
- 最小(最少步骤、最小数据)
- 自包含(如可能无外部依赖)
- 确定性(一致重现)
参见 references/information-gathering.md 获取详细技术。
假设生成
形成可测试假设
生成可能性:
- 头脑风暴什么可能导致观察到的症状
- 考虑每个问题类型(代码、配置、数据、基础设施)
- 回顾此领域的已知失败模式
- 不要自我审查 - 列出所有合理的
按概率排序:
- 最可能的原因优先
- 考虑基础率(常见与罕见失败)
- 考虑最近变化
- 按证据强度加权
使假设可测试:
- “如果X是原因,那么Y应该为真”
- 设计具体测试以确认/反驳
- 确保测试实际可执行
示例假设(排序):
- 高概率:最近配置变更引入拼写错误 → 检查配置与先前版本
- 中概率:依赖版本不匹配 → 验证所有依赖匹配工作环境
- 低概率:硬件故障 → 运行诊断,检查系统日志中硬件错误
常见失败模式
代码/逻辑:差一错误、空/未定义、类型不匹配、逻辑错误、未处理边缘案例、竞争条件
配置:拼写错误、错误环境变量、权限、路径问题、缺失设置
数据:无效格式、空值、损坏、编码问题、模式不匹配
基础设施:网络连接性、端口冲突、资源不足、权限、服务、防火墙
集成:API变化、过期凭证、速率限制、超时、版本不兼容
参见 references/hypothesis-generation.md 和 references/domain-specific-patterns.md 获取全面模式。
系统化测试
科学方法原则
一次改变一个变量:
- 每个测试修改单个因素
- 确切知道改变了什么
- 记录变更和结果
- 测试间重置到基线
验证假设:
- 不要假设任何工作
- 测试每个层(能访问服务吗?在响应吗?认证工作吗?)
- 质疑“明显”事物
- 从已知良好基线建立信心
隔离变量:
- 移除不必要组件
- 在受控环境测试
- 禁用功能以缩小范围
- 使用最小配置
记录一切:
- 测试了什么
- 改变了什么
- 发生了什么(确切结果)
- 得出的结论
- 下一步
使用 scripts/hypothesis_tracker.py 维护调查日志。
二分法故障排除
概念:将问题空间分成两半,确定哪半包含问题,重复。
应用:
- 版本二分:哪个提交引入了错误?(git bisect)
- 配置缩小:50个配置设置中哪个导致问题?
- 数据范围:数据集中哪些记录导致失败?
- 代码部分:哪个函数/模块有错误?
- 时间范围:问题何时开始发生?
过程:
- 识别搜索空间边界(工作 ↔ 损坏)
- 测试中点
- 确定哪半包含问题
- 对较小范围重复
- 继续直到隔离到特定元素
示例 - 配置调试:
- 开始:所有50个配置设置(损坏)
- 禁用一半(25个设置) → 仍损坏
- 问题在禁用的一半
- 禁用那些的一半(12-13个) → 工作!
- 问题在最近禁用的一组
- 继续缩小…
- 结果:隔离到单个有问题设置
使用 scripts/binary_search_helper.py 获取交互式指导。
差异诊断
比较工作与非工作案例以识别差异:
比较:
- 配置
- 环境
- 数据输入
- 依赖
- 定时/序列
- 系统状态
查找:
- 什么在失败案例中存在但不在工作案例中
- 两者之间有什么不同
- 什么版本不同
- 什么设置不同
技术:
- 从已知良好案例开始
- 逐步使其更像失败案例
- 当引入失败时停止
- 那个变化是原因
根本原因分析
5个为什么技术
通过重复问“为什么”深挖(通常5次):
示例:
- 问题:网站宕机
- 为什么? 数据库连接失败
- 为什么? 连接池耗尽
- 为什么? 连接未释放
- 为什么? 代码在错误路径中缺失connection.close()
- 为什么? 开发者不知道finally块
- 根本原因:缺失错误处理培训,缺失代码审查清单
指南:
- 每个“为什么”应基于事实(不推测)
- 当达到可操作根本原因时停止
- 可能需要多于或少于5个为什么
- 专注于过程/系统原因,不指责人
区分症状与根本原因
症状:问题的可观察表现 根本原因:问题存在的根本原因
示例:
- 症状:应用程序崩溃
- 症状:内存不足错误
- 症状:缓存模块中内存泄漏
- 根本原因:未实现缓存驱逐策略
测试:修复这会防止所有问题实例吗?
- 如果否 → 是症状,继续深挖
- 如果是 → 可能是根本原因
验证:
- 修复根本原因
- 测试所有症状消失
- 验证问题不复发
参见 references/diagnostic-frameworks.md 获取鱼骨图和FMEA。
故障排除原则
核心原则:
-
修复前重现 - 如果不能重现,就不能验证修复
-
一次改变一个事物 - 否则不知道什么修复了它
-
验证假设 - “它应该工作” ≠ “它确实工作”
-
从简单解释开始 - 奥卡姆剃刀(常见问题是常见的)
-
遵循数据 - 相信日志/证据而非直觉
-
从已知良好基线工作 - 建立什么工作,然后构建
-
边做边文档 - 你未来的自己会感谢你
-
知道何时停止 - 时间框调查,如果卡住则升级
-
避免确认偏见 - 也寻找证据反驳你的假设
-
治疗疾病,非症状 - 修复根本原因,不只是可见症状
领域特定指导
软件/代码:语法错误、逻辑错误、运行时错误、并发问题、内存问题
- 使用调试器、添加日志、橡皮鸭调试、审查变化、检查拼写错误
系统/基础设施:网络、权限、服务、端口、资源、配置
- 检查服务状态、测试连接性、审查日志、验证配置、检查资源
过程/工作流:缺失步骤、未满足依赖、通信间隙、定时问题
- 映射实际与期望过程、识别交接、检查前提条件
参见 references/domain-specific-patterns.md 获取按领域的全面诊断方法。
常见反模式避免
❌ 一次改变多个事物 - 不知道什么修复了它 ❌ 假设而不验证 - “上周工作”不意味着现在工作 ❌ 跳过重现 - 不能验证修复而不先重现 ❌ 只追求喜爱假设 - 确认偏见蒙蔽你 ❌ 放弃间歇问题 - 通常最关键 ❌ 忘记文档 - 他人会重复你的工作 ❌ 治疗症状而非根本原因 - 抑制错误不修复问题 ❌ 指责用户 - 过早停止调查 ❌ 匆忙解决方案 - 过早修复浪费时间
解决方案验证
实施修复后:
-
测试重现案例 - 现在工作吗?
-
测试边缘案例 - 修复在所有场景工作吗?
-
回归检查 - 修复破坏了其他东西吗?
-
性能检查 - 修复引入了性能问题吗?
-
监控生产 - 观察复发或副作用
-
与用户验证 - 确认问题从他们角度解决
文档
为未来文档:
故障排除日志:
- 问题描述
- 调查步骤
- 测试的假设
- 每个测试的结果
- 识别的根本原因
- 实施的解决方案
使用 assets/templates/troubleshooting_log_template.md
根本原因分析报告:
- 执行摘要
- 问题陈述
- 事件时间线
- 根本原因分析(5个为什么、鱼骨图)
- 纠正行动
- 预防措施
使用 assets/templates/rca_report_template.md
重现步骤:
- 最小重现示例
- 前提条件
- 逐步指令
- 期望与实际结果
使用 assets/templates/reproduction_steps_template.md
何时升级
知道何时求助:
- 已穷尽合理假设
- 问题超出你领域专长
- 问题时间关键且调查耗时太长
- 需要你没有的访问/权限
- 问题出现在外部系统
- 你在循环中(重复相同假设)
升级前:
- 文档尝试过什么
- 分享重现案例
- 提供所有诊断信息
- 解释你的假设和推理
- 建议需要的帮助
使用支持资源
此技能中附加资源:
- references/diagnostic-frameworks.md:5个为什么、鱼骨图、FMEA、二分法、比较分析
- references/information-gathering.md:日志分析、错误解释、环境文档
- references/hypothesis-generation.md:失败模式、假设排序、测试设计
- references/domain-specific-patterns.md:按领域的常见问题(软件、系统、硬件、过程、数据)
- scripts/hypothesis_tracker.py:跟踪假设和测试结果
- scripts/binary_search_helper.py:交互式二分法指导
- assets/templates/:调查日志、RCA报告、重现案例的文档模板
参考这些以获取特定技术的深入指导。
记住:最好的调试器是方法化、耐心和系统化的。抵制跳到解决方案的冲动。遵循数据。文档化你的过程。答案将通过系统化消除揭示自己。