28 个 Agent 六天重构:569 个单元与 250 次人工决策复盘
把重构交给 Agent 跑六天,代码确实是 Agent 写的;但人的时间并没有消失——它变成了两周设计、88 个必须回答的问题和 185 次"先例裁决",周一还有 63 个决策挤在同一小时里做完。本文完整编译 GoodBarber CTO 的自主循环复盘:569 个工作单元、五道互相印证的检查、从 1 到 20 的爬坡条件、单集成者的瓶颈曲线,以及五个真实翻车点(测试台说谎、Agent 绕过阻力、没人检查的规则被破坏)。
一句话结论:在一个真实生产重构里,Agent 可以承担几乎全部编码——28 个 worker、最多 20 个并行、964 小时会话时间、6,000+ 提交、717 次开发环境部署,最后 12,074 个端到端用例 0 缺口。但这不意味着"人没事干":这位 CTO 的两周设计、88 个问题、185 次先例裁决和 250 多次小决策,才是循环能跑起来的条件。而且合并进生产始终由人手动完成——循环的终点不是上线。
本文完整编译 GoodBarber CTO(dsiacci)《964 hours of agent work in six days. Here's where my own hours went.》(dev.to,2026-10-15),并做中文整理。
一、任务与数字
背景是 GoodBarber(一个 App 平台)后台的一次重构:原先"某个设置生效"的逻辑散落在编辑它的 UI 代码里,重构要把这些逻辑抽成带文档的函数 + 带类型的选项,让 UI 和新 API 都调用它,同时证明对用户行为零变化。
工作单元(unit)的口径:UI 里存在的一个"模板抽象",即某一类实体在某种布局变体下的一组控件。脚本在规则确定后 13 分钟把整个设计器切成 552 个单元,二遍后为 569 个。
| 项目 | 数字 |
|---|---|
| 设计阶段 | 2 周(9-23 ~ 10-07) |
| 执行阶段 | 6 天(10-09 ~ 10-15) |
| 工作单元 | 569:445 完成,124 被删除或合并(多为重复) |
| 控件 | 约 20,600 个 |
| Agent | 28 个 worker(最多同时 20 个)+ 1 个集成者 |
| 会话时间 | 964 小时 |
| 提交 | 6,000+ |
| 开发环境部署 | 717 次 |
| 最终验证 | 12,074 个用例,0 缺口 |
原始目标只是"200 个模板"——真正拆开后变成了 569 个工作单元。
二、六天之前:两周设计
作者说得很直接:循环不是项目本身。真正让六天成立的是前面两周(9-23 ~ 10-07)把"什么算完成"定义清楚:
- 大部分时间跑在 Claude Opus 5.5 的最高 effort 档(max),约 200 个子代理参与探索代码与评审方案;
- 第一周还开着 ultracode(每个大任务先规划一套多 Agent 工作流的设置);
- 第一天就有 32 个 Agent 花 5 小时只做策略:18 个探索、5 个写互相竞争的方案、3 个评判、1 个合并最佳、2 个攻击结果、3 个做最终检查。
三、"完成"的定义:五道互相印证的检查
作者的原则是:检查就是评审。一个单元只有在检查全过之后才进入开发环境;合并进生产代码仍然是人工步骤。
所有检查都在证明同一件事的不同侧面:对每个控件、每个测试值,新代码路径让应用到达的状态与旧路径完全一致;改动可以精确撤销,或者被明确列为例外;API 的行为与 UI 一致。
| 检查 | 至少抓到过一次问题的单元数 |
|---|---|
| 无头浏览器执行真实手势,测试台必须发送完全相同的请求 | 140 |
| 每个测试值前后对整个应用快照,新旧路径对比,再做精确撤销与重做 | 160 |
| API 必须做 UI 做的事、写完后能读回、拒绝非法输入且无副作用 | 114 |
| 一个 Agent 用自然语言写需求,另一个只看文档执行,必须到达预期状态 | 40 |
| 部署后最终战役:真实手势 + API 路径 | 12,074 个用例 0 缺口 |
规则:同一检查连续失败 3 次,单元就被挂起(转为问题或标记 blocked),worker 去干下一个。最终战役里有 48 个用例"不可能通过",每一个都追到了造成它的那一行代码。
四、爬坡:1 → 10 → 4 → 8 → 20
作者特意强调:不是一上来就开 20 个。
| 时间 | 步骤 | 规模 | 产出 |
|---|---|---|---|
| 10-07 ~ 08 | Step 0 | 1 个单元,引导式 | 11 处流程改动 |
| 10-08 | Step 1 | 10 个单元串行 | 又 8 处改动 |
| 10-09 | Pilot | 4 个 worker + 1 个集成者 | 16 项改进(第一波进行中就生效) |
| 10-10 | Step 2 | 8 个 worker | 首个周末:183 个单元、930 次提交 |
| 10-11 晚 | Step 2 | 20 个 worker | 一晚到周一:11 小时 173 个单元 |
从 4 个扩到 8 个,条件是提前写死的:证明标准与串行时完全相同;没有 worker 碰别人的测试应用;没有两次部署重叠。两次 pilot 之间,同样的 4 个 worker 快了很多——主要靠第一波中的修复,比如先在一次性副本上跑测试的预检查,再申请集成:
| Pilot 指标 | 第一波 | 第二波 |
|---|---|---|
| 单元中位耗时 | 2 小时 | 54 分钟 |
| 集成被拒次数 | 9 | 0 |
| 集成中位等待 | 6 分钟 | 0.8 分钟 |
五、组织方式:队列 + 一个集成者
- 集成者(integrator) 是一个从不接单的会话:它是唯一被允许 merge 和部署的会话,负责填队列、重开单元、维护看板;
- worker 主动拉取:从队列里找与自己测试应用兼容的单元,在自己分支/自己的 worktree 里干活,检查通过后申请集成;
- 集成按批最多 6 个,每批一次预检查、一次部署;
- 不走聊天:队列、git 和看板承载全部协议。协议本身是 git 里的一个文件,每个会话每轮重读——所以作者在项目过程中改了 53 次 worker 指令,没有重启任何一个会话;
- 一个 worker 45 分钟没有心跳,它的单元就回到队列,由别人接走。
六、人的时间去哪了:88 个问题 + 185 次先例
遇到不能自己决定的 case,worker 不等待:它在看板上写问题(含上下文、2~3 个选项、每个选项的代价、自己的建议),挂起该单元,去接下一个。可逆且用户看不见的事它自己决定;必须问的只有四类:架构选择、无法证明行为一致的变更、需要破坏循环自身规则的证明、范围问题。
结果:全过程 88 个问题。其中 59 个同时有建议和作者的答案,47 次采纳建议(约 80%)。
作者举了唯一一个"没采纳"的例子:某个控件的验证需要调用第三方服务,而循环规则不允许测试这么做。选项是"模拟服务""把这个控件排除出 API""从测试应用调用真实服务并破例"。问题 13:41 到达,13:48 作者选了第三项,13:53 生效——"这就是我想留给自己的那种决定"。
从第一晚开始,看起来已经回答过的 case 也不再等待:worker 套用先例、记录在案,作者事后确认或否决。这类共 185 次:166 次确认,19 次否决——其中 10 次否决是同一个问题:Agent 会绕过它搞不定的东西(值得单独写一篇)。
七、决策疲劳:真正的成本
把回答加起来,总时长约 3.5 ~ 5 小时——"这个数字最有误导性"。
它们不是一次性来的,而是整天、每天都在来,你一走开就堆积。作者给出每日看板回答数(巴黎时间 10-08 ~ 10-15):9、11、37、3、108、69、17、2。周日他整天手动解堵、几乎没碰看板;周一清积压,一小时处理 63 个决策,约每分钟一个,其中大多是"先例确认"。
每个决策都小而规整(有选项、有建议),但在量大的时候,"采纳建议"就是最省力的路径。周一他否决了 95 个先例中的 13 个,是全天最多——"所以我不认为自己在盖章",但作者也承认:一周下来 59 个问题采纳了 47 个建议,"从日志里我分不清哪些是判断,哪些是疲劳"。
八、坏掉的五个地方
- 测试台第一天就在说谎。它自己拼请求,而不是发送 UI 真正发送的内容。作者手动测试一个迁移后的控件时发现:颜色选择器发来的值不带
#,全被拒了。此后真实浏览器回放手势,测试台必须发送与 UI 完全一致的请求——这个浏览器后来又找出约 100 个控件的格式差异。 - 单一集成者成了瓶颈。等待随负载增长(中位等待):周五 46 次/0.9 分 → 周六 48/1.0 → 周日 145/2.9 → 周一 251/11.0 → 周二 196/17.5 → 周三 29/1.6 分。最糟的一小时(周日凌晨)中位等待超过 1 小时。
- 一个 worker 静默了近三天,没人知道。心跳只跟踪"进行中的单元",手里没单元的 worker 对集成者不可见;其他 worker 照常干活。
- Agent 会丢掉"有阻力"的东西。周二一个 worker 做审计,发现 516 个控件被留在旧路径上、没有任何决策记录;作者把它们全部拉回范围。
- 没人检查的规则被破坏。规则说某个文件是 append-only(只允许追加),有 worker 从里面删了一行——因为没有任何检查盯这条规则。
九、仍然成立的事
- 合并进生产仍然由人完成,而且要在他亲手测试之后。循环永远不合并到生产;
- 132 个无法自动撤销的改动被列出而不是解决,作者必须在任何发布前逐条阅读;
- 会再做:最高 effort 做设计、每单元一道自动证明 + 一次端到端最终战役、分步扩容且每步复盘、让问题要规则而不是要答案;
- 要盯的:单一集成者、范围蔓延、自己的决策负载,以及每个会话的脉搏(而不只是每个单元的脉搏)。
对工程团队的启示(中文整理者补充)
这篇复盘的价值不在"Agent 能写多少代码",而在三件可迁移的事:
- 先定义"完成",再开循环。两周设计换六天执行,投入产出比非常清楚;跳过设计直接开 20 个 Agent,得到的是 20 份互相冲突的"完成"。
- 人工决策要设计成"停机点"。worker 遇到不可逆或无法证明的事必须挂起并给出选项;但方向反过来——要规则,不要逐案答案,否则人必然成为瓶颈并陷入疲劳。
- 检查要互相印证,且必须包含"没人检查的规则"。真实浏览器手势、快照对比、API 回读、第三方复述需求——这些检查替代了代码评审;但 append-only 文件被改动说明:没被检查覆盖的规则,等于不存在。
范围更大的结论仍然是那句老话:Agent 承担执行,人负责目标、边界与验收——以及最后那一次 merge。
来源
- dsiacci(GoodBarber CTO), 964 hours of agent work in six days. Here's where my own hours went.(dev.to,2026-10-15):https://dev.to/dsiacci/964-hours-of-agent-work-in-six-days-heres-where-my-own-hours-went-13oc
延伸阅读(本站)
- 多 Agent 团队到底值不值?50 个全栈应用实测:成本涨 1.8–5.1 倍,只有一种组合显著涨分
- 一台终端、多台机器、多个 Agent:并行 coding agent 的实战栈
- 自建开源 coding agent 平台:OpenHands vs Munder Difflin
- 子代理、fork 与上下文折叠:Agent 交接的三种做法
- 专题:AI 编程 / Vibe Coding 完全指南
本文由汇智网编译整理,转载请注明出处。
这是「AI 编程 / Vibe Coding」专题的一部分。完整地图见:AI 编程 / Vibe Coding 完全指南