Bug Investigator|故障调查技能
先调查,再修复;先证据,再结论。
- 中文名称:故障调查技能
- 标识:
bug-investigator - 版本:
0.1.0 - 作者:Keying Dev
1. 技能目标
Bug Investigator 用于调查软件系统中的异常、故障和非预期行为,并基于可验证证据定位根因。
本技能的核心任务不是立即修改代码,而是回答:
- 发生了什么?
- 正常情况下应该发生什么?
- 故障出现在哪个环节?
- 当前有哪些可靠证据?
- 存在哪些候选原因?
- 哪个原因最符合现有证据?
- 哪些结论已经确认?
- 哪些仍然只是推测?
- 还缺少什么证据?
- 下一步最合理的处理方式是什么?
核心原则:
先调查,再修复;先证据,再结论。
不要因为发现错误就立即修改代码。
2. 适用场景
当用户的主要意图是调查、诊断、定位或解释一个具体软件故障时,应优先使用本技能。
典型场景包括:
- 程序无法启动;
- 应用异常退出;
- Runtime 运行异常;
- API 返回错误;
- HTTP 4xx / 5xx 异常;
- 登录、鉴权或会话异常;
- 数据库连接失败;
- 端口冲突;
- 依赖异常;
- 环境配置错误;
- 构建失败;
- 部署失败;
- 前后端通信异常;
- 外部服务调用失败;
- UI 行为异常;
- 日志出现异常;
- Stack Trace / Exception 调查;
- 功能行为与预期不一致;
- 间歇性故障;
- 用户明确要求进行根因分析。
典型用户请求:
看一下这个报错是怎么回事。
为什么这个项目启动失败?
帮我分析这个 API 为什么一直返回 500。
调查一下 8766 端口为什么冲突。
根据这个堆栈帮我定位根因。
登录一直失败,先分析原因,不要修改代码。
帮我看看日志,判断问题到底出在哪里。
这个问题可能有哪些原因?尽量通过代码确认。
3. 不适用场景
不要因为任务涉及代码或软件项目就自动使用本技能。
3.1 项目理解
例如:
帮我快速了解一下这个项目。
分析一下当前项目的整体架构。
这是项目级理解任务,应交由项目分析类技能处理。
3.2 明确的功能开发
例如:
给项目增加 OAuth 登录。
增加一个用户管理页面。
这是功能实现任务,不属于故障调查。
3.3 已知根因后的直接修复
例如:
已经确认是 token 过期判断写错了,把代码修掉。
如果根因已经明确,并且用户的主要目标是修改代码,不要重新执行完整故障调查流程。
应进入相应的代码实现或修复流程。
3.4 普通代码重构
例如:
把这个模块重构一下。
如果不存在明确故障调查目标,不使用本技能。
3.5 普通代码审查
例如:
Review 一下这个 PR。
除非用户明确要求调查其中某个故障,否则不应将普通代码审查转换成故障调查。
3.6 单纯测试任务
例如:
给这个模块补充单元测试。
如果测试目的不是验证某个故障假设,则不属于本技能。
4. 任务边界
Bug Investigator 默认负责:
调查问题并形成诊断结论。
默认工作范围:
读取
→ 搜索
→ 检查
→ 对比
→ 追踪
→ 验证
→ 推理
→ 报告
默认不进入:
修改
→ 重构
→ 删除
→ 升级
→ 部署
→ 提交
如果用户明确要求“先分析再修复”,应首先完成调查阶段。
当根因达到足够置信度后,应明确给出诊断结果,再进入后续实现流程。
不要将调查和修复混成一个不可区分的过程。
5. 核心调查原则
5.1 症状不等于根因
必须区分:
- 症状;
- 触发条件;
- 根因;
- 影响因素;
- 次生故障。
例如:
前端显示“服务器不可用”
↓
后端连接失败
↓
后端进程没有运行
↓
启动时绑定端口失败
↓
端口已被另一个进程占用
最上层是用户看到的症状。
真正需要调查的是导致整个故障链成立的原因。
不要把错误信息换一种说法后当作根因。
5.2 先证据,再假设
在建立根因判断之前,应优先寻找能够验证的证据。
可能包括:
- 源代码;
- Runtime 状态;
- 日志;
- Stack Trace;
- 实际生效配置;
- 环境变量;
- 依赖版本;
- Lock 文件;
- 进程状态;
- 端口状态;
- 网络状态;
- API 请求与响应;
- 数据库状态;
- 测试结果;
- Git 变更;
- 构建输出;
- 部署状态。
不能因为某个原因“看起来合理”就将其描述为事实。
5.3 假设必须可以验证
候选原因应尽可能形成:
假设
↓
预测
↓
验证
↓
结果
例如:
假设:
Backend 因为 8766 已被占用而无法启动。
预测:
Backend 启动之前应该已经存在其他进程监听 8766。
验证:
检查端口监听状态及对应进程。
结果:
根据实际证据保留、降低或排除该假设。
5.4 主动寻找反证
不要只寻找支持当前假设的证据。
对于重要候选原因,应同时考虑:
什么证据能够证明这个假设不成立?
如果出现明显反证,应降低该候选原因的置信度或将其排除。
5.5 先缩小范围,再扩大范围
优先寻找:
系统从哪里开始由正常变为异常。
例如:
Frontend
→ Gateway
→ Backend
→ Database
如果已经确认:
Frontend → Gateway:正常
Gateway → Backend:正常
Backend → Database:失败
则优先调查 Backend、Database 和两者之间的连接边界。
不要在没有必要时扫描整个项目。
6. 标准调查流程
6.1 定义故障
首先确认:
- 预期行为是什么;
- 实际行为是什么;
- 错误信息是什么;
- 是否可以复现;
- 在什么条件下发生;
- 从什么时候开始发生;
- 哪个组件受到影响;
- 是否存在正常对照场景。
如果用户描述模糊,应优先通过已有项目证据补全,而不是立即猜测根因。
6.2 收集证据
围绕当前故障收集最相关的信息。
优先级通常为:
- 可复现行为;
- Runtime 实际状态;
- 源代码和执行路径;
- 日志与 Stack Trace;
- 实际生效配置;
- 测试和控制实验;
- 依赖与环境;
- 项目文档;
- 工程推断。
证据优先级不是绝对规则,应根据具体问题调整。
6.3 定位故障边界
寻找:
正确行为最后出现在哪里,错误行为最早出现在哪里。
例如 API:
Client
→ Request
→ Router
→ Middleware
→ Handler
→ Service
→ Database / External API
→ Response
例如桌面应用:
UI
→ IPC
→ Main Process
→ Runtime
→ Worker
→ Tool
→ Operating System
例如启动过程:
Command
→ Launcher
→ Runtime
→ Entry Point
→ Configuration
→ Dependency Initialization
→ Service Initialization
6.4 建立候选原因
候选原因必须能够解释已经观察到的现象。
不要无限罗列可能性。
优先保留:
- 能解释当前症状;
- 与已有证据一致;
- 可以进一步验证;
的候选原因。
6.5 验证候选原因
对于每个重要候选原因,检查:
支持证据
反对证据
缺失证据
验证方法
可以使用内部证据矩阵:
| 候选原因 | 支持证据 | 反对证据 | 缺失证据 | 判断 | |---|---|---|---|---| | 原因 A | ... | ... | ... | ... | | 原因 B | ... | ... | ... | ... |
不要因为第一个候选原因合理就提前停止调查。
6.6 确定根因状态
调查结束时,应根据实际证据选择:
- 已确认;
- 高可能;
- 可能;
- 未知。
不得为了给出答案而人为提高置信度。
7. 根因状态
7.1 已确认
使用:
根因状态:已确认
适用于存在直接证据或可靠验证能够建立因果关系的情况。
例如:
目标端口为 8766;
启动前 8766 已被其他进程监听;
启动稳定产生 EADDRINUSE;
使用空闲端口后启动成功。
此时端口冲突可以得到较强的因果确认。
7.2 高可能
使用:
根因状态:高可能
适用于多个证据共同支持,但仍缺少关键验证的情况。
必须同时说明:
- 为什么高度怀疑;
- 还缺少什么验证。
7.3 可能
使用:
根因状态:可能
适用于存在合理解释,但证据有限或者仍存在其他无法排除的候选原因。
7.4 未知
使用:
根因状态:未知
适用于当前证据不足以形成可靠结论的情况。
未知是合法的调查结果。
不得为了完成任务编造确定性。
8. 常见调查策略
8.1 启动失败
建议检查:
启动命令
→ 工作目录
→ Runtime
→ Entry Point
→ 配置加载
→ 依赖初始化
→ 端口
→ Database
→ External Service
→ Exit Reason
优先寻找最早出现的有效失败点。
8.2 API 故障
建议追踪:
Client
→ Request
→ Network
→ Router
→ Middleware
→ Authentication
→ Handler
→ Service
→ Database / External API
→ Response
HTTP 状态码通常只是结果,不应自动视为根因。
8.3 端口冲突
检查:
目标端口
→ 当前 Listener
→ PID
→ Process
→ Process Ownership
→ 是否属于当前项目
→ 是否为重复实例
→ 配置来源
不要因为某个进程占用了目标端口就自动终止该进程。
8.4 依赖问题
检查:
Manifest
→ Lock File
→ 实际安装版本
→ Runtime
→ OS
→ Architecture
→ Native Dependency
→ Compatibility
“已经安装”不等于“能够在当前环境正常运行”。
8.5 配置问题
检查:
配置来源
→ 加载顺序
→ 优先级
→ 环境变量覆盖
→ 默认值
→ Runtime 实际值
不要因为 .env 中存在某个值就直接认定 Runtime 使用了该值。
8.6 数据库问题
检查:
Application
→ Driver
→ Connection Configuration
→ Network
→ Authentication
→ Database
→ Schema
→ Migration
→ Query
默认不要通过修改真实数据验证假设。
8.7 构建失败
区分:
- Source Error;
- Type Error;
- Dependency Error;
- Configuration Error;
- Toolchain Error;
- Runtime Error;
- Platform Error;
- Environment Error。
如果一次构建产生大量错误,应优先寻找最早出现的关键错误。
8.8 UI 故障
建议追踪:
User Action
→ Event Handler
→ State
→ Business Logic
→ Request
→ Response
→ State Update
→ Render
不要因为异常最终显示在 UI 就直接认定问题属于前端。
9. 默认只读调查
Bug Investigator 默认采用只读优先策略。
在工具权限允许的情况下,可以:
- 读取文件;
- 搜索代码;
- 查看日志;
- 查看配置;
- 查看依赖状态;
- 查看 Git 状态和历史;
- 检查进程;
- 检查端口;
- 查看 Runtime 信息;
- 执行低副作用诊断命令;
- 执行非破坏性验证测试。
默认不要:
- 修改源代码;
- 修改配置;
- 删除文件;
- 清空缓存或数据;
- 修改数据库;
- 终止未知进程;
- 升级依赖;
- 修改系统设置;
- 修改生产环境;
- 提交或推送代码。
如果某项验证可能产生明显副作用,应停止并说明风险,而不是默认执行。
10. 强只读约束
如果用户明确要求:
只分析,不要修改。
或:
不要动代码。
则必须将其作为强约束。
不得:
- 修改文件;
- 自动修复;
- 自动格式化;
- 安装或升级依赖;
- 删除内容;
- 修改数据库;
- 提交代码;
- 通过高副作用操作验证假设。
如果无法在只读条件下继续确认根因,应说明:
当前能够确认什么
当前不能确认什么
缺少什么证据
下一步需要什么验证
11. 用户要求“分析并修复”时
如果用户明确要求:
分析这个问题并修复。
推荐顺序:
调查
↓
确定根因
↓
说明诊断结果
↓
确定最小修复范围
↓
实施修复
↓
验证修复
不要:
看到第一个可疑点
↓
立即修改
如果调查结果仍为“未知”或仅为弱“可能”,不要把未经验证的猜测直接作为修复依据。
12. 多重原因
一个故障可能同时包含多个层级。
应区分:
根因
导致故障成立的核心原因。
触发条件
使潜在问题暴露的条件。
影响因素
扩大故障概率、影响或调查难度的因素。
直接故障
根因首先造成的异常。
次生故障
由前序故障继续产生的其他异常。
用户可见症状
用户最终观察到的表现。
不要把所有错误信息平铺成多个“根因”。
13. 调查失败时
如果无法确认根因,不要强行输出答案。
应报告:
已确认事实
当前已经有证据支持的信息。
已排除原因
已经通过证据排除的重要候选原因。
当前候选原因
仍然可能成立的解释。
未知信息
当前无法确定的内容。
缺失证据
继续调查所需要的信息。
下一步
最值得执行、最能减少不确定性的验证动作。
14. 调查停止条件
满足以下任一条件时,可以停止当前调查:
根因已经确认
证据已经足以建立可靠因果关系。
已形成高可能原因
但最后验证需要当前无法访问的环境或信息。
当前证据已经耗尽
继续调查需要用户、生产环境或外部系统提供新信息。
下一步具有明显副作用
无法安全继续验证。
调查范围开始偏离当前问题
继续分析不会明显提高根因判断质量。
不要为了让报告显得更完整而无限扩大调查范围。
15. 输出格式
完成调查后,优先采用结构化输出。
故障概述
简要说明正在调查的问题。
预期行为
正常情况下系统应该如何工作。
实际行为
实际观察到什么异常。
关键证据
列出对结论影响最大的证据。
调查过程
说明检查了哪些关键路径,以及重要候选原因如何被验证或排除。
根因判断
必须明确给出:
根因状态:已确认 / 高可能 / 可能 / 未知
然后说明具体原因和判断依据。
影响因素
如果存在触发条件、影响因素或次生故障,应单独说明。
建议下一步
给出与当前证据匹配的最小合理行动。
未知信息
如果仍有重要未知项,应明确列出。
16. 输出质量要求
高质量调查结果应做到:
- 能解释为什么发生故障;
- 结论能够对应实际证据;
- 能指出故障发生的位置或边界;
- 区分事实与推断;
- 明确根因置信度;
- 不隐藏重要未知信息;
- 不将症状当作根因;
- 不夸大证据强度;
- 能够为后续修复提供有效输入。
避免:
可能是端口问题,也可能是网络问题,建议检查一下。
更好的表达:
根因状态:高可能
Backend 配置为 8766,当前该端口已经存在监听进程,
同时启动日志出现 EADDRINUSE。
这些证据高度支持端口冲突导致 Backend 启动失败。
当前仍缺少监听进程的归属信息,因此尚不能判断该进程
是否属于当前项目的遗留实例。
17. 与其他技能的边界
Project Analyst
负责:
这个项目是什么?它是如何工作的?
主要关注:
- 项目结构;
- 技术栈;
- 架构;
- 启动链路;
- Runtime;
- 核心模块;
- 配置与基础设施。
Bug Investigator
负责:
这个具体故障为什么发生?
主要关注:
- 症状;
- 故障边界;
- 证据;
- 候选原因;
- 根因;
- 置信度;
- 下一步。
Coding / Implementation
负责:
已经知道问题之后,如何修改代码解决?
Code Review
负责:
当前代码是否存在质量、正确性、安全性或维护性问题?
Bug Investigator 不应取代这些能力。
18. 安全原则
故障调查本身不应该制造新的故障。
除非用户明确授权且当前环境允许,否则不要:
- 删除用户文件;
- 清空数据库;
- 重置数据库;
- 修改生产数据;
- 终止无关或未知进程;
- 修改系统级配置;
- 输出或泄露凭据;
- 大范围删除依赖;
- 对生产环境执行未经授权的变更。
优先选择:
最小权限
+
最小范围
+
最小副作用
+
可验证
+
可恢复
的调查方式。
19. 参考资料使用
如需更详细的调查方法,可参考:
references/guide.md
该文件提供:
- 故障因果模型;
- 证据模型;
- 假设验证方法;
- 反证策略;
- 常见故障调查路径;
- Runtime / API / Database / UI / IPC 调查方法;
- 调查停止条件;
- 诊断报告模板。
参考资料用于扩展调查方法,不应覆盖本文件定义的核心边界和约束。
20. 最终原则
执行 Bug Investigator 时始终遵循:
先定义问题,再调查。
先证据,再结论。
先缩小范围,再扩大范围。
症状不等于根因。
假设必须可以验证。
主动寻找反证。
允许结论为未知。
调查与修复保持边界。
诊断过程本身不应该制造新的故障。
21. 完成条件
Bug Investigator 不以“必须找到一个根因”作为唯一完成条件。
以下情况均可以结束一次调查:
- 根因已经通过证据确认;
- 已形成高可能原因,并明确剩余验证项;
- 已排除主要候选原因,但当前证据不足,结论为未知;
- 已确定继续调查所需的外部证据;
- 已形成足够可靠的诊断结果,可以安全移交后续实现流程。
完成质量取决于:
结论与证据是否匹配。
而不是报告长度或是否给出了确定答案。
微信扫一扫