把 Agent 修复 Bug 拆成定位、补丁与验证三阶段
让同一个 Agent 一次完成读工单、搜索仓库、修改代码、运行命令和提交结果,会把根因判断、权限提升与验证混在一条不可重放的会话里。测试通过也无法说明它没有改动任务之外的文件,失败时更难判断哪些动作已经发生。本文把修复拆成三个独立阶段:只读定位生成证据,隔离工作区生成补丁,CI 使用仓库既有命令验证;每阶段重新声明权限和输入。
为什么需要阶段边界
Bug 修复至少包含三种不同责任:
| 阶段 | 核心问题 | 主要产物 | 不应拥有的权限 |
|---|---|---|---|
| 定位 | 根因证据在哪里 | 候选文件、调用链、假设 | 写文件、执行任意命令 |
| 补丁 | 最小行为变化是什么 | Diff、测试变更、风险 | 发布、合并、生产访问 |
| 验证 | 变更是否满足仓库约定 | 独立命令结果、失败日志 | 自行改代码掩盖失败 |
三个阶段分开后,前一阶段的结构化产物成为后一阶段输入。人可以在权限提升前拒绝错误方向,也可以用同一定位报告生成另一版补丁。
阶段一:只读定位
输入应包含经过脱敏的故障报告、复现条件、实际错误和预期行为。不要只给一句“接口报错”,也不要把生产令牌、用户数据或完整内部日志直接加入提示词。
定位提示词可以使用:
Claude Agent SDK 的 allowed_tools 只预批准所列工具,未列工具仍会进入 permission mode。按照 官方权限文档,需要结合 disallowed_tools、当前 permission mode 和运行环境限制真正阻止写入与命令执行。
定位阶段完成后检查:
- 路径和符号确实存在。
- 根因与故障现象之间有可追溯证据。
- “事实”和“假设”没有混写。
- 建议测试能在修改前失败,而不是只验证实现细节。
- Agent 没有给出无关重构或依赖升级计划。
如果证据不足,阶段结果应为“需要更多信息”,而不是强行进入补丁。
阶段二:在隔离工作区生成补丁
补丁阶段使用临时分支、工作树、容器或其他可丢弃工作副本。运行账号只能访问目标仓库和必要依赖,不能持有发布凭据或生产数据访问权。
输入由人工确认后的定位报告组成,并声明变更合同:
补丁提示词示例:
不要在要求逐次审批时使用会自动接受文件操作的模式。官方文档说明,acceptEdits 会批准文件操作;自动批准的工具调用也不会再进入 canUseTool 回调。需要审批时,应选择能把写操作路由到审批流程的当前模式,并通过实际拒绝测试确认配置有效。
审查补丁而不是审查摘要
阶段二的验收对象是 Git Diff:
- 修改文件是否完全位于允许范围。
- 测试是否表达故障行为,而非简单复制实现。
- 修复是否改变异常、返回值、状态或兼容接口。
- 是否出现大范围格式化、锁文件或生成文件变化。
- 是否写入凭据、内部路径或故障数据。
- 未验证项是否明确列出。
代理生成的“只改了必要代码”不是证据,必须与实际 Diff 对照。范围外修改应拒绝并重新生成,而不是在同一补丁上不断叠加修正。
阶段三:由独立 CI 验证
验证阶段从干净基线应用已批准补丁,使用仓库文档、构建配置或持续集成定义的命令。不要让补丁 Agent自己发明命令,也不要允许它在测试失败后即时修改代码,使验证结果失去独立性。
验证顺序可按影响范围展开:
CI 产物至少包含命令、环境、退出状态、失败日志和测试报告位置。失败后回到定位或补丁阶段,建立新一轮输入;不要把失败日志直接变成无限自动重试。
失败与取消也要设计
每阶段都要能回答:
- 超时或取消后还有没有工具在运行。
- 哪些文件已经写入,工作区是否可直接丢弃。
- 消息流不完整时是否会被误标为成功。
- 同一任务重试是否会重复写入或覆盖证据。
- 人工拒绝后如何终止,而不是换一种工具继续。
在进入真实仓库前,用测试项目演练允许、拒绝、超时、取消和工具错误。权限配置只有在拒绝路径也通过验证后才可信。
任务记录如何串联
三个阶段共享一个任务标识,但分别保存:
模型原始上下文可能含源码和内部信息,不应无条件长期保存。记录范围、访问权限和保留时间应符合组织规则。
不适合自动生成补丁的情形
当故障涉及无法在隔离环境复现的生产状态、跨服务事务、数据迁移、密钥、授权边界或不可逆业务动作时,Agent 可以辅助收集证据和提出测试,但补丁设计与执行需要更严格的领域审查。
判断标准不是“模型会不会写”,而是团队能否定义明确输入、限制权限、复现行为并独立验证。
结论与限制
Agent 修复 Bug 的可控闭环不是一次全自动会话,而是三份可审查产物:定位证据、隔离 Diff 和独立 CI 结果。权限只在阶段需要时提升,任何范围扩大都重新经过人工确认。
阶段化会增加交接成本,也不能替代领域专家对业务语义的判断。它的价值是让错误方向在低权限阶段暴露,并让补丁和验证能够被复现、拒绝和重新执行。




