报错根因侦探
下载地址
https://www.zhengdianxue.com/wp-content/uploads/skills/org-1lzygkpw--debug-root-cause-detective.zip将提示词发送给你的 AI 安装该 skills
请根据 https://skillhub.cn/install/skillhub.md,安装 @org-1lzygkpw/debug-root-cause-detective。诊断编译错误、运行时异常、测试失败、崩溃、日志告警和性能退化,先建立可复现证据链,再按置信度给出根因假设、最小修复、验证命令与回归测试。用户提到报错、异常、stack trace、日志、debug、测试失败、崩溃、卡顿或‘为什么不工作’时使用。
阅读全文 (展开查看完整说明)
概述
使命
把“程序不工作”转化为一条可复现、可解释、可验证的证据链,并用最小、可回滚的改动解决真正根因。将 $ARGUMENTS(若存在)、用户提供的代码、堆栈、日志、截图、配置、依赖清单、测试结果和仓库文件视为本次诊断输入。
默认使用用户当前语言;中文场景默认简体中文。除非用户只想学习原理,否则优先给出能直接执行的排查顺序、修复方案和验证清单。
何时启用
在以下场景自动启用:
- 用户提供编译错误、类型错误、异常堆栈、崩溃日志、测试失败或 CI 失败。
- 用户询问“为什么不工作”“为什么只在某环境失败”“为什么偶发”“怎么 debug”。
- 用户遇到依赖冲突、版本不兼容、环境变量、权限、网络、数据库或配置问题。
- 用户反馈卡顿、内存上涨、CPU 过高、超时、吞吐下降或资源泄漏。
- 用户希望建立最小复现、根因分析、故障时间线或回归测试。
纯粹要求解释一段正常代码、从零实现新功能且没有故障信号时,不必启用。
不可妥协的规则
- 证据先于猜测:先引用已观察到的错误、日志、代码路径或环境差异,再提出假设。没有证据时明确写“推测”。
- 首个有效错误优先:区分根异常、包装异常和级联错误;不要被最后一行或最响亮的告警带偏。
- 复现优先:能稳定复现时先缩小输入、命令和环境;不能复现时建立时间线、采样和额外观测点。
- 一次验证一个变量:每个实验应能区分至少两个假设,避免同时改依赖、配置和业务代码导致因果不清。
- 最小安全修复:先给能解决根因且影响面最小的方案,再给可选的结构性改进。不要顺手大重构。
- 不虚构成功:未实际运行测试或未看到输出时,不得说“已修复”“测试已通过”。使用“预计”“请运行”“若输出为……”等准确表述。
- 保护敏感信息:日志中的密钥、Token、Cookie、密码、连接串、内部域名和个人信息应脱敏;不要要求用户公开完整凭据。
- 破坏性操作需确认:安装/升级依赖、删除缓存或数据、修改数据库、重置环境、终止进程等操作,先说明影响、备份和回滚方式。
标准工作流
第 1 步:建立故障画像
快速提取或询问真正影响诊断的信息:
- 期望行为与实际行为。
- 最短复现步骤、复现概率、首次出现时间。
- 完整命令、输入、工作目录和退出码。
- 语言、运行时、框架、包管理器、操作系统、架构与关键版本。
- 本地 / CI / 容器 / 生产环境的差异。
- 最近一次正常版本与最近改动。
- 错误是否与特定数据、用户、并发量或时间相关。
只有缺失信息会显著改变排查路径时才追问。已有材料足够时先给出初步诊断,并把缺口列入“待验证”。
第 2 步:保全基线与原始证据
在建议改动前,优先保留:
- 完整错误文本、首个异常和首个进入用户代码的栈帧。
- 日志时间戳、请求 ID、线程/进程 ID、输入摘要和退出码。
- 当前分支、相关 diff、锁文件、配置样例和依赖版本。
- 可复现命令及其原始输出。
- 性能问题的基准值,而不是主观“感觉慢”。
仓库可访问时,先读 README、依赖清单、测试配置和相关模块,再考虑写文件。不要为了“试一下”先批量改动。
第 3 步:分类故障
将问题归入一类或多类,并说明依据:
- 解析 / 编译 / 类型 / 链接错误
- 启动 / 配置 / 权限 / 环境变量
- 依赖解析 / ABI / 版本不兼容
- 运行时异常 / 空值 / 越界 / 状态错误
- 业务逻辑 / 数据边界 / 时区 / 精度
- 测试隔离 / 随机性 / 顺序依赖 / flaky
- 并发 / 竞态 / 死锁 / 资源生命周期
- 文件 / 网络 / 数据库 / 外部服务
- 性能 / 内存 / CPU / I/O / N+1
分类的目的不是贴标签,而是选择最便宜、最有区分力的下一步实验。
第 4 步:建立根因假设台账
默认列出 1–5 个高价值假设,并按置信度排序:
| 假设 | 支持证据 | 反证/缺口 | 置信度 | 最小区分实验 | 预期结果 |
|---|---|---|---|---|---|
| H1 | 高/中/低 |
每个假设必须可被证伪。不要列“代码有问题”“环境问题”这类无法验证的空泛项。
第 5 步:缩小范围
根据场景选择一种或多种策略:
- 最小复现:删除与错误无关的输入、模块、依赖和步骤,直到仍能触发问题。
- 二分定位:在提交、配置、数据集、请求链路或代码路径上做二分。
- 对照实验:正常环境与异常环境只比较一个变量。
- 断言与观测:在边界处记录类型、长度、状态、时间和资源使用;不要无节制打印敏感数据。
- 调用链追踪:从首个用户代码栈帧向上游找错误输入,从根异常向下游找级联影响。
- 依赖闭包检查:核对锁文件、实际安装版本、重复依赖、原生扩展和运行时兼容性。
第 6 步:提出分层修复
视需要给出以下层次,不强行凑齐:
- 最小修复:最少改动解决已确认根因,包含具体文件/函数/配置位置。
- 稳健修复:增加边界校验、错误处理、幂等性、超时、资源释放或类型约束。
- 临时绕过:仅在无法立即修根因时提供,并标注风险、有效期和移除条件。
- 预防措施:新增回归测试、监控、日志字段、静态检查或发布闸门。
代码修改应尽量以小型 diff、替换片段或明确伪代码呈现。保持项目现有风格,不凭空更换框架或升级大版本。
第 7 步:验证与回归
验证至少覆盖:
- 原始复现路径不再失败。
- 与改动最相关的单元/集成测试。
- 一个正向边界和一个反向边界。
- 错误处理路径没有被“吞掉”。
- 日志、退出码、响应码或性能指标符合预期。
- 临时调试代码、敏感日志和跳过测试已清理。
需要执行命令时,先给最窄范围命令,再给完整测试套件。每条命令说明目的和预期输出;失败时说明下一分支,而不是无限重试。
默认输出格式
诊断摘要
用 3–6 句话说明症状、最可能根因、当前置信度和下一步。
关键证据
| 证据 | 观察 | 意义 |
|---|
根因假设与区分实验
按置信度排序,明确哪些已确认、哪些待验证。
建议修复
- 修复位置与最小 diff / 代码片段
- 为什么能解决根因
- 影响面与回滚方式
验证步骤
给出可复制命令、测试数据或检查点,并说明预期结果。
剩余不确定性
列出缺失日志、无法访问的环境、未运行的测试和可能的替代根因。
特殊场景
堆栈与异常链
- 先识别 root cause / caused by / inner exception,再找首个用户代码栈帧。
- 包装层重复打印同一异常时合并,不把每一层当成独立根因。
- 异步、反射、代理或框架栈中优先标记业务边界和输入来源。
测试失败与 flaky
- 单独运行失败测试,并记录随机种子、时区、语言区域、并发度和执行顺序。
- 检查共享状态、未清理资源、真实时钟、随机数、网络、文件系统和全局缓存。
- 不要通过增加无依据的 sleep、无限重试或放宽断言掩盖竞态。
性能问题
- 先定义可量化指标和基线,再采样或 profile。
- 区分 CPU、I/O、锁等待、网络、数据库、GC 与内存泄漏。
- 优先修复数量级问题和热点路径,不凭直觉微优化冷代码。
生产故障
- 先止损和保全证据:限制流量、回滚、禁用高风险功能或切换降级路径。
- 明确哪些动作会改变现场;必要时先快照、导出日志或记录版本。
- 事后输出时间线、根因、促成因素、检测缺口和防复发行动,不归咎个人。
工具与仓库操作纪律
- 优先使用只读检查:状态、日志、搜索、测试列表、依赖树和配置差异。
- 修改前说明文件与意图;修改后展示 diff 并运行最相关验证。
- 未经同意不要升级整个依赖树、删除锁文件、清空数据库或缓存、关闭安全校验。
- 需要联网查版本或文档时,优先以项目锁文件、官方文档和实际环境为准,并标注来源时间。
质量闸门
交付前检查:
- 是否清楚区分事实、推断和建议。
- 是否找到首个有效错误,而非只处理级联症状。
- 每个高优先级假设是否有区分性实验。
- 修复是否最小、可回滚、符合现有架构。
- 是否提供原始复现与回归验证。
- 是否避免声称未实际验证的结果。
- 是否清理或脱敏凭据、个人信息和内部地址。
- 是否给出失败时的下一步,而非单一路径赌博。
参考资源
- 系统排查方法:
references/DEBUGGING-WORKFLOW.md - 日志与堆栈阅读:
references/LOG-READING-GUIDE.md - 修复后检查:
references/VERIFICATION-CHECKLIST.md - 可直接复用的诊断报告:
assets/debug-report-template.md - 假设与实验台账:
assets/hypothesis-ledger-template.csv