跳到主要内容

指南:Bug 修复

何时使用调试工作流

当你有一个需要诊断和修复的特定 bug 时,使用 /debug(或用自然语言说 "fix bug"、"fix error"、"debug")。该工作流提供结构化、可重现的调试方法,避免常见的修复表象而非根因的陷阱。

调试工作流支持所有供应商(Gemini、Claude、Codex、Qwen)。步骤 1-5 内联运行。步骤 6(类似模式扫描)在扫描范围较广(10+ 文件或多领域错误)时可能委派给 debug-investigator 子智能体。


Bug 报告模板

报告 bug 时,尽可能提供以下信息。每个字段都有助于调试工作流更快缩小搜索范围。

必填字段

字段说明示例
错误消息精确的错误文本或堆栈跟踪TypeError: Cannot read properties of undefined (reading 'id')
复现步骤触发 bug 的有序操作1. 以管理员登录。2. 导航到 /users。3. 点击任意用户的"删除"。
预期行为应该发生什么用户被删除并从列表中移除。
实际行为实际发生了什么页面崩溃,显示白屏。

可选字段(强烈建议提供)

字段说明示例
环境浏览器、操作系统、Node 版本、设备Chrome 124、macOS 15.3、Node 22.1
频率总是、有时、仅首次始终可复现
近期变更bug 出现前发生了什么变更合并了 PR #142(用户删除功能)
相关代码你怀疑的文件或函数src/api/users.tsdeleteUser()
日志服务器日志、控制台输出[ERROR] UserService.delete: user.organizationId is undefined
截图/录屏视觉证据错误界面的截图

你预先提供的上下文越多,调试工作流需要的来回提问就越少。


严重度分级(P0-P3)

严重度决定 bug 的处理方式和修复速度。

P0 —— 严重(立即响应)

定义: 生产环境宕机、数据正在丢失或损坏、安全漏洞正在发生。

响应预期: 放下一切。在解决之前这是唯一的任务。

示例:

  • 认证系统被绕过 —— 所有用户都能访问管理员端点。
  • 数据库迁移损坏了用户表 —— 账户无法访问。
  • 支付处理在向客户双重收费。
  • API 端点返回其他用户的个人数据。

调试方法: 跳过完整模板。提供错误消息和堆栈跟踪即可。工作流立即从步骤 2(复现)开始。

P1 —— 高(当前会话内)

定义: 核心功能对大量用户不可用。可能存在变通方案但长期不可接受。

响应预期: 在当前工作会话内修复。在解决前不开始新功能。

示例:

  • 包含特殊字符的搜索查询返回空结果。
  • 超过 5MB 的文件上传失败(限制应为 50MB)。
  • 移动应用在 Android 14 设备上启动时崩溃。
  • 密码重置邮件未发送(邮件服务集成损坏)。

调试方法: 完整 5 步循环。修复后建议进行 QA 审查。

P2 —— 中(当前冲刺内)

定义: 功能可用但行为降级。影响可用性但不影响功能。

响应预期: 安排在当前冲刺。在下次发布前修复。

示例:

  • 表格排序区分大小写("apple" 排在 "Zebra" 之后)。
  • 暗色模式在设置面板中有不可读的文本。
  • /users 端点的 API 响应时间为 8 秒(应低于 1 秒)。
  • 列表为空时分页显示"第 1 页,共 0 页"。

调试方法: 完整 5 步循环。纳入 QA 回归测试套件。

P3 —— 低(待办)

定义: 美观问题、边缘情况或轻微不便。

响应预期: 加入待办。方便时修复,或与相关变更一起批量处理。

示例:

  • 提示文本有错别字:"Delet" 应为 "Delete"。
  • 控制台警告关于已弃用的 React 生命周期方法。
  • 在 768-800px 视口宽度之间,页脚对齐偏差 2 像素。
  • 内容可见后加载动画继续 200 毫秒。

调试方法: 可能不需要完整调试循环。直接修复加回归测试即可。


5 步调试循环详解

/debug 工作流按严格顺序执行这些步骤。全程使用 MCP 代码分析工具 —— 从不使用原始文件读取或 grep。

步骤 1:收集错误信息

工作流询问(或从用户接收):

  • 错误消息和堆栈跟踪
  • 复现步骤
  • 预期与实际行为
  • 环境详情

如果提示词中已提供错误消息,工作流立即进入步骤 2。

步骤 2:复现 Bug

使用的工具: search_for_pattern 搜索错误消息或堆栈跟踪关键词,find_symbol 定位精确的函数和文件。

目标是在代码库中定位错误 —— 找到抛出异常的精确行、产生错误输出的精确函数,或导致意外行为的精确条件。

此步骤将用户报告的症状("页面崩溃了")转化为代码库级别的定位(src/api/users.ts:47, deleteUser() throws TypeError)。

步骤 3:诊断根因

使用的工具: find_referencing_symbols 从错误点反向追踪执行路径。

工作流从错误位置反向追踪以找到实际原因。它检查以下常见根因模式:

模式寻找什么
空值/undefined 访问缺少空值检查、需要可选链、未初始化的变量
竞态条件异步操作乱序完成、缺少 await、共享可变状态
缺少错误处理没有 try/catch、未处理的 promise 拒绝、缺少错误边界
错误数据类型期望数字但得到字符串、缺少类型转换、不正确的 schema
过期状态React 状态未更新、缓存值未失效、闭包捕获了旧值
缺少验证用户输入未清理、API 请求体未验证、边界条件未检查

关键纪律:诊断根因,而非症状。如果 user.id 是 undefined,问题不是"如何检查 undefined?",而是"为什么 user 在执行路径的这个点是 undefined?"

步骤 4:提出最小修复方案

工作流展示:

  1. 已识别的根因(带代码追踪的证据)。
  2. 提出的修复方案(只修改必要的部分)。
  3. 说明为什么这是修复根因而非症状。

工作流在此处阻塞直到用户确认。 这防止调试智能体未经批准就进行修改。

最小修复原则: 修改尽可能少的行。不重构、不改善代码风格、不添加无关功能。修复应在 2 分钟内完成审查。

步骤 5:应用修复并编写回归测试

此步骤执行两个操作:

  1. 实现修复 —— 应用已批准的最小变更。
  2. 编写回归测试 —— 一个测试:
    • 复现原始 bug(没有修复时测试必须失败)
    • 验证修复有效(有修复时测试必须通过)
    • 防止同一 bug 在未来变更中复发

回归测试是调试工作流最重要的输出。没有它,同样的 bug 可能被任何未来变更重新引入。

步骤 6:扫描类似模式

修复应用后,工作流扫描整个代码库以查找导致 bug 的相同模式。

使用的工具: search_for_pattern 搜索已识别为根因的模式。

例如,如果 bug 是由于访问 user.organization.id 而未检查 organization 是否为 null 引起的,扫描会查找所有其他无空值检查的 organization.id 访问。

子智能体委派条件 —— 工作流在以下情况启动 debug-investigator 子智能体:

  • 错误跨越多个领域(例如,frontend 和 backend 都受影响)。
  • 类似模式扫描范围覆盖 10+ 文件。
  • 需要深层依赖追踪才能完全诊断问题。

供应商特定的启动方式:

供应商启动方式
Claude Code使用 .claude/agents/debug-investigator.md 的 Agent 工具
Codex CLI模型协调的子智能体请求,结果为 JSON
Gemini CLIoma agent:spawn debug "scan prompt" {session_id} -w {workspace}
Antigravity / 回退oma agent:spawn debug "scan prompt" {session_id} -w {workspace}

所有类似的脆弱位置都会被报告。确认的实例作为同一会话的一部分修复。

步骤 7:记录 Bug

工作流写入内存文件,包含:

  • 症状和根因
  • 应用的修复和变更的文件
  • 回归测试位置
  • 在代码库中找到的类似模式

/debug 的提示词模板

触发调试工作流时,你可以提供结构化提示词:

/debug

Error: TypeError: Cannot read properties of undefined (reading 'id')
Stack trace:
at deleteUser (src/api/users.ts:47:23)
at handleDelete (src/routes/users.ts:112:5)

Steps to reproduce:
1. Log in as admin
2. Navigate to /users
3. Click "Delete" on a user whose organization was deleted

Expected: User is deleted
Actual: 500 Internal Server Error

Environment: Node 22.1, PostgreSQL 16

为什么这个结构有效:

  • 错误 + 堆栈跟踪 允许步骤 2 立即定位代码(search_for_pattern 搜索 "deleteUser" 找到函数;find_symbol 精确定位位置)。
  • 复现步骤 带有特定触发条件("组织已删除的用户")暗示了根因(null 外键)。
  • 环境 排除版本特定的干扰。

对于较简单的 bug,较短的提示词即可:

/debug The login page shows "Invalid credentials" even with correct password

工作流会根据需要询问额外细节。


升级信号

这些信号表明 bug 需要超出标准调试循环的升级处理:

信号 1:同一修复尝试了两次

如果工作流提出修复、应用后同一错误再次出现,问题比初始诊断更深。在支持探索循环的工作流(ultrawork、orchestrate、work)中会触发:

  • 为根因生成 2-3 个替代假设。
  • 在独立工作区测试每个假设(每次尝试使用 git stash)。
  • 评分结果并采用最佳方案。

信号 2:多领域根因

frontend 的错误由 backend 的变更引起,而 backend 的变更又由数据库 schema 迁移引起。当根因跨越领域边界时,升级到 /work/orchestrate 以引入相关领域智能体。

示例: Frontend 显示用户名为 "undefined"。Backend 对 user.display_name 返回 null。数据库迁移添加了该列但现有行有 NULL 值。修复需要:数据库迁移(回填)、backend 空值处理和 frontend 回退显示。

信号 3:缺少复现环境

Bug 仅在生产环境中出现,本地无法复现。信号包括:

  • 环境特定的配置差异。
  • 仅在生产负载下才出现的竞态条件。
  • 第三方服务在 staging 和 production 之间的行为差异。

行动: 收集生产日志,请求生产监控访问权限,在尝试修复前考虑添加插桩/日志。

信号 4:测试基础设施故障

无法编写回归测试,因为测试基础设施损坏、缺失或不足。

行动: 先修复测试基础设施(或使用 oma install 配置),然后返回调试工作流。


修复后验证清单

应用修复和回归测试后,验证:

  • 回归测试在无修复时失败 —— 临时还原修复,确认测试捕获了 bug。
  • 回归测试在有修复时通过 —— 应用修复,确认测试通过。
  • 现有测试仍通过 —— 运行完整测试套件以验证无回归。
  • 构建成功 —— 编译/构建项目以捕获类型错误或导入问题。
  • 类似模式已扫描 —— 步骤 6 已完成,所有找到的实例已修复或记录。
  • 修复是最小的 —— 仅修改了必要的行。未包含无关重构。
  • 根因已记录 —— 内存文件记录:症状、根因、应用的修复、变更的文件、回归测试位置和找到的类似模式。

完成标准

调试工作流在以下条件满足时完成:

  1. 根因已识别并记录(不仅仅是症状)。
  2. 经用户批准的最小修复已应用。
  3. 存在回归测试,在无修复时失败,有修复时通过。
  4. 代码库已扫描类似模式,所有确认的实例已处理。
  5. Bug 报告已记录在内存中,包含:症状、根因、应用的修复、变更的文件、回归测试位置和找到的类似模式。
  6. 修复后所有现有测试继续通过。