我如何让 AI Agent 项目保持可控
记录使用 AI Coding Agent 时降低失控风险的个人工作流方法。
为什么 Agent 项目容易失控
AI Agent 很擅长执行具体任务,但它不擅长判断”这件事该不该做”。
我遇到过几次这样的情况:给 Agent 一个明确的任务,它完成后顺手把其他东西也改了。有时候改的是 UI 样式,有时候改的是项目结构,有时候甚至把原本能跑的功能改坏了。
问题不在于 Agent 能力不够,而在于我没有给它足够的边界。没有边界的执行,很容易变成”改了不该改的东西”。
所以我现在的方法是:把项目拆成小阶段,每个阶段都有明确目标、禁止事项、验收标准和 commit 节点。
我现在的基本原则
方向判断和代码执行是两件事,我现在尽量不混在一起。执行 Agent 的职责是写代码,不是决定做什么。如果我发现一个功能需要重新思考方向,会先自己想清楚,或者用另一个模型梳理思路,再给执行 Agent 明确的指令。
每轮只做一个小目标,这个原则我现在基本都在用。一次让 Agent 实现三个功能,不如分三次,每次只做一个。出了问题范围小,回滚也清楚。每次 Agent 执行完一轮,我会先跑 npm run build,确认没有编译错误,再 commit——这顺序不能颠倒,否则一旦要回滚,根本分不清哪个 commit 是干净的。
在让 Agent 修改之前,我还会先让它读一遍相关文件。Agent 有时会基于它”以为”的代码结构去改,结果改错地方。多花几步让它先理解现状,比事后修错误要值得。
我常用的几类指令
修改前先审计。比如:「请先读一下 src/content.config.ts,确认当前 schema 结构」,或者「请列出 src/content/projects/ 下的所有文件」。目的是让 Agent 在修改之前理解现状,而不是基于它的假设去改。
明确边界。每次指令里都会说清楚只改哪几个文件,不改哪些东西。比如「只修改 src/content/writing/example.md,不要改其他文件」,或者「不要改 UI 样式,不要改组件结构」。
回滚先于修复。如果 Agent 的执行结果不满意,我会先用 git 回滚到上一个干净的 commit,再重新给指令,而不是在一个已经混乱的状态上继续改。git restore . 和 git reset --hard <commit-hash> 是最常用的两个命令。
交接要写文档。上下文过长时,或者需要切换 Agent,我会写一份短的交接说明:项目结构、当前状态、下一步要做什么、有哪些文件不能动。这比让新的 Agent 从头理解要可靠。
一个实际例子
有一次我用 Gemini Flash 修改个人主页的 About 区域。任务是”优化文案”,但它把整个 About 重写了,语气从克制变成了求职包装,还顺手改了导航逻辑和 Hero 定位。
用 git diff 一查,它改了 10 个文件,远超”修改 About”的范围。我用 git restore . 把所有改动回滚,然后换用 Claude Code,重新给指令,明确说”只改 src/content 下的文件,不改组件,不改样式”。这次只改了 About 文案,其他没动。
从这次开始,我养成了在 Agent 每次执行前先 commit 一个干净状态的习惯。这样即使结果不满意,git reset --hard 可以直接退回,不需要猜哪些是 Agent 改的、哪些是我自己改的。
还有一次验收时遇到了另一类边界问题:Cloudflare 的 Git 自动构建一直失败,但本地 npm run build 完全没问题。后来改用 Wrangler Direct Upload 单独上传,先把 Preview 跑通,再回头排查构建环境差异。这也是一种拆分边界的思路——验收和部署环境是两个问题,分开处理比混在一起更清楚。
边界指令不是可选项,而是必需品。
这个方法的局限
方向对不对还是需要人来判断,这一点目前没有办法绕开。有一次 Agent 实现了一个功能,build 通过了,功能也能用,但 UI 很丑——这类判断 Agent 做不了,还是得自己看。即使用了「每轮只做一个小目标」,上下文有时还是会累积很长,这时候需要主动清空,重新开始。
后续想继续优化的地方
目前做得还不够的,主要是两块。交接文档还比较随意,每次新 Agent 接手都要重新理解项目;指令模板也不稳定,每次都要重新组织语言。回滚点的管理可以更清晰——在每个功能完成前打一个 tag,而不是只依赖 commit hash。
验收自动化目前还是手动检查,短期内应该不会大改,够用就好。
这些优化不是为了让 Agent 变得更智能,而是为了让我的工作流更稳定。