用 coding agent 做持续重构 小步可回滚
把重构从攒大坨改成小步可验证可回滚:任务拆分、验收命令、停手时机,以及 Plan Mode 与文件计划怎么配合。

Coding agent 一开口就能连写几千行,设计债也跟着堆。用 coding agent 做持续重构,指的是把「功能做完再开重构票」改成「每批新代码落地后立刻用同一套 agent 流程收一遍」,小步、可验证、随时能 git reset。重构从 Jira 墓碑里的史诗,变成跟 commit 同频的付费动作。
为什么要随写随收
Adrian Booth 在 2026-08 的 Medium 短文里把这套习惯叫 continuous refactoring。他们在两个目录里每周灌进大量新代码做订单问题系统(app/services/admin/order_issues_v2 与对应前端组件目录);若不定期用技能扫设计,很快会变成「agent 速度带来的复杂度坑」。他的做法是对刚生成的代码跑定制 skill:一个按 Sandi Metz 视角做 OOP review(feature envy、data clumps、命名漂移等),输出可审的重构计划;另一个 Simplify 派 6 个子 agent 分查死代码、重复、坏味道、命名、条件折叠、分层边界。一轮下来往往是一个过去要排进 backlog 好几天的大 PR,现在可以跟功能迭代穿插做完。
关键态度是:测试够硬时,agent 让重构便宜到可以常做;只让 agent 加代码,等于只用了半边工具。这和 Anthropic 官方 common-workflows 里重构小节的建议一致:小步、可测、行为保持。防止越改越糊的写法,另见 怎么避免 AI 生成 slop 代码。
任务怎么拆才算「一小步」
持续重构忌讳的提示是「把这层架构理干净」。Booth 的材料落在「两个目录 + 一份计划 + 可审的 PR」;官方示例则是「先找 deprecated → 建议改法 → 改一个文件 → 跑测试」。可执行的拆法:
- 范围钉死:路径或模块列表写进任务,禁止「顺手」扫全仓。
- 一次只改一类味道:先抽重复,或先收命名,不要同一次 PR 又搬家又换框架。
- 每步对应一条验收命令,失败就停在该步,不进入下一步。
- 提交粒度按路径 stage,方便单步回滚。
多文件改动仍建议先出计划再动手,方法见 Claude Code 多文件重构怎么拆。
验收命令才是闸门
没有绿基线,agent 会朝着「看起来更干净」用力,行为有没有坏反而排第二。开工前用项目自己的命令锁基线:pnpm test、cargo test、make lint,把通过数记进进度文件。官方重构配方的最后一步就是 run tests for the refactored code;Booth 也强调 test suite 要硬到撑得住连续迭代。基线没绿就先修测试或缩小范围,别带着红条「重构」。
验收要绑真实路径,编译通过不够。Web 就打开关键页或跑 e2e;库就跑受影响的测试子集;API 就打一条真实请求或 contract test。会话结束条件写成可判定句,例如「pnpm test --filter order-issues 退出码 0,且无新增 lint error」。写「重构到满意为止」等于没写结束条件:满意没法机器判定,退出码可以。
什么时候该停
Booth 写得很直:重构会过火,每条建议都要人工判断值不值。该停的信号通常是:
- 剩余味道要么动到公开契约(URL、API、对外格式),要么没有可靠验收路径。
- 同一处改了两轮测试仍红,说明问题在规格不清,不在「再让 agent 试一次」。
- PR 已经大到人审不动:拆成多个小 PR,比继续在同一分支堆更好。
- skill 开始建议「为对称而抽象」:读源码后发现重复是有意分叉时,记一笔跳过,别合并。
停手后留下的应是可合并的增量。架构终态不存在;下一周新功能进来,再跑同一轮 skill 即可。
Plan Mode 和文件计划怎么配
大范围动手前,先把写权限关掉。Claude Code 的 plan mode(claude --permission-mode plan,或会话里 Shift+Tab 切到 plan)允许读文件、跑只读探索,不改源码,直到你批准计划。适合回答:先动哪些文件、顺序是什么、哪几条测试守门。批准前把计划当 code review 读一遍:范围是否越界、有没有动公开契约、验收命令是否写死。
计划只活在对话里会在压缩后丢失。把阶段、下一步、已否决项写进仓库里的 task_plan.md / progress.md,压缩或换会话还能接着干;骨架与用法见 用文件做计划,上下文断了也不丢。实操顺序可以是:Plan Mode 出计划 → 写入 task_plan → 退出 plan 按步改 → 每步跑验收 → 勾选进度 → 人为决定停或开下一小步。
hooks 适合挂在「改完必跑」上:例如 PostToolUse / afterFileEdit 后跑 lint,或 stop 时跑目标测试失败则续跑。这是加固闸门,不能替代「范围写死」和「人工判停」。
这套方法在什么情况下会失效
测试稀疏或全是快照时,agent 会在绿条下改坏语义。没有路径级回滚习惯时,一天的「持续重构」会变成一次巨大的不可审 diff。把 OOP review / Simplify 类 skill 开成无人值守全自动合并,也会把「判断值不值」交回模型,Booth 自己也没这么建议:计划给人审,合并给人点。还有一种失效:功能分支尚未稳定就每天大扫除,重构噪声会淹没真正的产品 diff。更稳的节奏是功能增量合并前或合并后立刻收一小轮;另开一张遥遥无期的「技术债史诗」,多半又会回到旧的延期模式。