← Back to skills
extension
Category: Development & EngineeringAPI key requirement unconfirmed

bug-investigator

面向软件故障调查与根因分析的技能,用于通过证据收集、假设验证和因果分析定位软件故障根因。

personAuthor: keyingshuzhihubgithub

Bug Investigator|故障调查技能

先调查,再修复;先证据,再结论。

  • 中文名称:故障调查技能
  • 标识:bug-investigator
  • 版本:0.1.0
  • 作者:Keying Dev

1. 技能目标

Bug Investigator 用于调查软件系统中的异常、故障和非预期行为,并基于可验证证据定位根因。

本技能的核心任务不是立即修改代码,而是回答:

  1. 发生了什么?
  2. 正常情况下应该发生什么?
  3. 故障出现在哪个环节?
  4. 当前有哪些可靠证据?
  5. 存在哪些候选原因?
  6. 哪个原因最符合现有证据?
  7. 哪些结论已经确认?
  8. 哪些仍然只是推测?
  9. 还缺少什么证据?
  10. 下一步最合理的处理方式是什么?

核心原则:

先调查,再修复;先证据,再结论。

不要因为发现错误就立即修改代码。


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 收集证据

围绕当前故障收集最相关的信息。

优先级通常为:

  1. 可复现行为;
  2. Runtime 实际状态;
  3. 源代码和执行路径;
  4. 日志与 Stack Trace;
  5. 实际生效配置;
  6. 测试和控制实验;
  7. 依赖与环境;
  8. 项目文档;
  9. 工程推断。

证据优先级不是绝对规则,应根据具体问题调整。

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 不以“必须找到一个根因”作为唯一完成条件。

以下情况均可以结束一次调查:

  1. 根因已经通过证据确认;
  2. 已形成高可能原因,并明确剩余验证项;
  3. 已排除主要候选原因,但当前证据不足,结论为未知;
  4. 已确定继续调查所需的外部证据;
  5. 已形成足够可靠的诊断结果,可以安全移交后续实现流程。

完成质量取决于:

结论与证据是否匹配。

而不是报告长度或是否给出了确定答案。