跳到正文
一AllOne
关注

工作流

用 Agent 写代码不翻车:小步提交、先测后改、出错怎么回退

编程 Agent 改代码又快又多,翻车也一样快。这篇给出一套和具体工具无关的安全工作流:每个任务前先存档、一次只做一件事、先写测试再改代码、让它拿出证据、看完 diff 再提交,以及出错时按什么顺序回退。

发布于 2026-10-22 · 最后核实:2026-10-22 · 文中价格与额度以各官网为准

编程 Agent 和「AI 补全」最大的区别是:它会自己读文件、改文件、跑命令,一口气动十几个文件。效率高得惊人,风险也一样——一次没看住,它可能顺手重构了你没让它碰的模块,或者为了让测试通过,把测试本身改了。

好消息是,避免翻车的方法和具体工具无关。无论你用 Claude Code、Codex、Cursor、TRAE 还是 OpenCode,下面这套做法都成立。Simon Willison 有一个很精辟的观察:编程 Agent 会放大那些本来就是好习惯的工程实践——自动化测试、事先规划、版本管理、代码审查。有这些习惯,Agent 是助推器;没有,它就是放大器,把混乱放大。

结论先说:存档 → 小任务 → 可验证 → 看 diff → 提交。出了问题先回退,不要在烂摊子上继续修。

原则一:开工前先存档

每次给 Agent 一个新任务前,确保工作区是干净的——上一个任务的改动已经提交了。在终端里跑一下:

git status

如果显示 nothing to commit, working tree clean,就可以开始了。这样做的意义是:任何时候你都能一条命令回到开工前的状态。 没有这个存档点,Agent 改坏的东西和你自己之前没提交的改动会混在一起,想拆都拆不开。

很多 Agent 工具也自带「检查点」或「撤销」功能(比如 Claude Code 每次对话轮次都会自动生成检查点,可以把代码恢复到之前的状态)。这些功能很好用,但它们是工具内部的机制,换个工具就没了;Git 提交是通用的、永久的存档,两者都用,以 Git 为准。

原则二:一次只做一件事

任务越大,Agent 越容易跑偏,你也越难审查。把需求拆成「一句话说得清」的小任务:

  • ❌「把用户系统做完」
  • ✅「给注册表单加上邮箱格式校验,校验规则见 SPEC.md 第 3 节」

判断标准:做完之后,你能不能在几分钟内看懂它改了什么? 如果不能,任务就太大了。需求怎么拆,可以参考本站的《给 AI 写需求》一文。

另外,不相关的任务之间清空上下文。Claude Code 的官方最佳实践里有一条很实用的经验:如果同一个问题已经纠正了两次以上还没好,说明上下文里塞满了失败的尝试,不如清空、带着学到的东西重新写一个更具体的提示词。这条经验适用于所有基于大模型的工具。

原则三:先写测试,再改代码

这是让 Agent「自己发现自己的错误」的关键。思路是:给它一个能自己运行、能明确判断通过与否的检查。

修 Bug 时,推荐这样下指令:

用户反馈:会话超时后登录失败。
1. 先写一个能复现这个问题的测试,运行它,确认它失败。
2. 然后修复代码,让这个测试通过。
3. 运行全部测试,确认没有破坏其他功能。
4. 不允许修改或删除已有的测试。

做新功能时同理:先把验收标准写成测试(或者至少写成具体的输入和期望输出),再让它实现。

为什么强调「先看到测试失败」?因为一个从来没失败过的测试,可能根本没在测你以为它在测的东西。

如果项目还没有测试,至少要有构建命令和类型检查 / 代码检查命令可以跑。Anthropic 的文档说得很直接:没有可运行的检查,「看起来做完了」就是 Agent 唯一的完成信号,而你就成了那个人肉检查器。

原则四:要证据,不要「我已经完成了」

Agent 说「已修复,所有测试通过」,不等于真的通过了。要求它展示证据:

  • 运行了哪条命令、输出是什么;
  • 测试结果的原始输出;
  • 界面改动的话,给一张截图。

审查证据比你自己从头复现快得多。同时注意几种「假完成」的信号:

  • 测试被改得更宽松了,或者被跳过(skip)、被删掉了;
  • 错误被 try/catch 吞掉,而不是被解决;
  • 出现了 // TODO: 实现这里 或者硬编码的假数据。

原则五:看完 diff 再提交

提交前,看一眼它到底改了什么:

git diff            # 还没暂存的改动
git diff --staged   # 已经暂存、准备提交的改动

或者在编辑器的源代码管理面板里逐个文件查看。重点检查:

  • 有没有改到任务之外的文件? 比如你只让它改表单,它却动了配置文件或依赖清单。
  • 有没有新增依赖? 每个新依赖都是长期的维护负担和潜在的安全风险。
  • 有没有碰敏感内容? 密钥、.env 文件、生产环境配置。

确认没问题,再提交,并写一句清楚的提交信息:

git add -A
git commit -m "注册表单增加邮箱格式校验"

一个任务一次提交。以后出问题,你能精确地找到是哪一步引入的。

原则六:控制它能做什么

大多数 Agent 工具都有权限设置:哪些命令可以直接执行,哪些需要你确认。几条通用建议:

  • 删除文件、强制推送(git push --force)、改数据库、部署上线,这些不可逆或影响线上的操作,保持「需要确认」。
  • 读文件、跑测试、跑构建这类安全操作可以放开,免得你被确认弹窗淹没,最后变成闭眼点「同意」。
  • 有沙箱模式就用沙箱,限制它能访问的目录和网络。
  • 把「绝不做」的事写进项目说明文件(AGENTS.md 等,见本站的相关教程),比每次在对话里重复更可靠。

原则七:大改动放在分支上

尝试性的、规模较大的改动,先开一个分支:

git switch -c try-new-layout

在分支上随便折腾,满意了再合并回主分支;不满意,切回主分支、删掉这个分支,主分支毫发无损。如果你的托管平台支持预览部署,推送这个分支就能拿到一个预览链接,在真实环境里看效果。

出错了怎么回退

按「代价从小到大」的顺序:

情况 做法
改坏了,还没提交,想全部放弃 git restore .(丢弃工作区里对已跟踪文件的改动;新建的文件还需要手动删除或用 git clean 清理,执行前先用 git clean -n 预览)
只想撤销某一个文件 git restore 路径/文件名
已经提交了,但还没推送 git reset --hard HEAD~1(回到上一个提交,本地改动会丢失,确认后再用)
已经推送到远程了 git revert 提交号(生成一个「反向提交」来抵消它,不改写历史,最安全)
线上网站已经坏了 先在托管平台上回滚到上一个正常的部署止损,再在代码里用上面的方法修

两条铁律:

  1. 改写历史的命令(reset --hard、push --force、commit --amend)只用在还没推送的本地提交上。 Pro Git 一书对 --amend 的提醒同样适用于这一类操作:只修改还在本地、尚未推送的提交。
  2. 不要在烂摊子上继续修。 如果 Agent 连续几轮都没修好,而且越改越乱,最省时间的做法几乎总是:回退到存档点,总结一下失败的原因,写一个更具体的新指令,重新开始。

常见的坑

  1. 一整天不提交。 等到出问题时,已经分不清哪些改动是好的。
  2. 让它「顺便优化一下」。 范围一模糊,改动就会蔓延到你没预料到的地方。
  3. 测试由它写、由它改、由它判断。 至少在提交前亲自看一眼测试在测什么。
  4. 把密钥贴进对话。 用环境变量,在说明文件里写明「不读取、不输出 .env」。
  5. 在主分支上做实验。 开分支的成本几乎为零。
  6. 同时开几个 Agent 改同一批文件。 并行可以,但要分给它们互不重叠的任务,最好各自在独立的分支或工作目录里。

一张每轮任务的流程卡

  1. git status 确认干净 → 2. 给一个小而具体的任务,附验收标准 → 3. 要求它先写测试或说明怎么验证 → 4. 让它跑检查并展示输出 → 5. git diff 审查 → 6. 提交 → 7. 下一个任务前清空无关上下文。

工具会不断更新,但这七步不会过时。它们本来就是好的软件工程习惯,只是在有了 Agent 之后,变得更加重要。

参考资料

← 返回教程列表