《给 Claude Code 建工作环境》系列第 3 篇,共 5 篇。 这篇讲多 agent 并行------大项目里我最离不开的提速手段。可它也有翻车的时候,那次我亲手把一个 65 行的小需求跑成了两个小时。
- 环境比 prompt 重要,和 CLAUDE.md 红线
- 会滚雪球的 Memory 长期记忆
- (本篇)多 agent 并行与三层 review
- 四次翻车,和每次翻车留下的机制
- 权限、远程协作、长任务编排
那次的需求小得可笑,统共 65 行代码。我却让 Claude Code 一口气开了 25 个 agent,前后磨了两个小时。我自己都看不下去:就这么点东西,也值得跑两个小时?
确实,本来半小时就能收工。
但你先别急着否定多 agent 并行。在大项目里,它是我最看重的提速手段,没有之一。这篇我想说清楚两件事:我平时怎么把它用好,以及那次怎么把它用砸的。
我一个人带着 Claude Code 在一个大型遗留 Kotlin/Akka SLG 游戏服务端上干了好几个月。前两篇聊的是「知识」------CLAUDE.md 红线怎么定、memory 怎么滚雪球。这篇换个维度聊「时间」。
大项目最大的时间黑洞是编译。一次模块编译动不动三五分钟,几个任务串着做,光等编译就能把人等麻。多 agent 并行就是用来折叠这段等待的。下面先说怎么折叠,再说那套三层 review 流水线------以及它用错地方时,我是怎么搞出两小时灾难的。
四、Subagent 并行与三层 review:让主对话只当裁判
并行的好处其实就一句话:几个互不相干的任务一起跑,等待时间是叠在一起的,不是一个接一个加上去的。三个任务各等三五分钟编译,串着做就是三段等待累加;并行派出去,三段等待折叠成一段。
并发数我写死成了 3
触发条件我直接写进 CLAUDE.md,当成唯一标准,省得每次现想:
markdown
## Subagent Defaults
- ≥2 个独立写代码任务 且 单个预计 > 30s → 默认并行派 Agent,
先一句话报备不询问:「准备派 N 个 agent 并行跑 X / Y / Z」
- 写代码 Agent 默认 isolation: "worktree",回来报
路径 + 分支 + 改动文件数 + 测试结果,主对话只做裁判
- 单条回复并发上限 3 个 Agent,超出先报预算
- 共享配置冲突 → prompt 里预分号段(序列化注册 ID / 协议 tag /
各种全局注册项),各 agent 取互不重叠区间避免撞号
- 不派:需求含糊(先问)/ 子任务有隐式依赖 / 改动 < 30s / 单文件单点改
几个数字不是拍脑袋来的。并发上限定在 3,是因为编译堆内存按 6g 配,超过 3 个 agent 同时编译就开始互相抢、互相打架。预分号段是另一个坑:好几个 agent 同时去改同一份全局注册文件(序列化 ID、协议 tag 那种),不分配区间就会撞号,所以派单的时候我就先给每人划好一段互不重叠的号段。
「worktree 隔离 + 主对话只当裁判」是这套玩法的骨架。每个写代码的 agent 在自己的 git worktree 里折腾,回来只报四样东西:路径、分支、改了几个文件、测试过没过。它探索时的弯路、试错、半成品,全留在它自己的上下文里,一点都不会渗进主对话。主对话就负责一件事:看结果,决定合不合并。
两个 reviewer 一定要并行派
高风险的改动,我用三层:一个 agent 写(implementer),两个 agent 审。一个对着 spec 查实现齐不齐(spec reviewer),另一个专门找 bug、找 edge case、找跨模块的耦合(code-quality reviewer)。
这两个 reviewer 必须塞进同一条消息里并行派。它们读的是同一个 commit,彼此不依赖,一个接一个派纯属浪费时间。我实测过,单个 Task 串行下来要 15 到 25 分钟,spec 和 quality 并行派之后压到 10 到 15 分钟,十个 Task 攒下来能省 50 到 100 分钟。
配套的监控我也写死了:
text
implementer 交付 commit 后:
spec reviewer 和 code-quality reviewer 在【同一条消息】里并行派
→ 收回两份结论汇总:任一 FAIL 则 fixup,都 PASS 进下一 Task
监控阈值:
超 6 分钟无产出 → 查是不是 API 529(限流)
超 12 分钟无产出 → 主对话直接接管,不再干等
接管前先 git log --oneline + git show HEAD 读已有 commit 再续做
那次两小时是怎么炼成的
三层 review 用着是真爽。但场景一选错,它就从提速器变成绞肉机。
有一次做个小需求,一处资源豁免逻辑,设计上拢共 65 行代码加 100 行测试,涉及 5 个文件。我选了「subagent-driven」这个执行模式,然后脑子一根筋,严格照流程把它拆成 6 个 Task,每个 Task 都老老实实跑 implementer 加两个 reviewer 加 fix loop。一圈下来,agent 调用了大约 25 次,时钟走了整整两个小时。等回过神来,我自己都臊得慌------这玩意儿 inline 直接写、最后整体 review 一次,半小时就该收尾了。
事后我复盘,三个错叠在一起:
一是把 skill 里那句「持续执行不要停」当成了不能违抗的流程。二是把「最高 effort」理解歪了,以为 effort 拉满就等于必须上最重的流程------其实 effort 说的是质量目标,跟用什么流程是两码事。三是忘了一件最朴素的事:简单任务要快,靠的是 inline 快速迭代,不是把它拆给一堆 agent。
后来我把流程层数钉成了一棵决策树
这件事最后沉淀成 CLAUDE.md 里的一棵决策树,按改动规模先定层数再开工:
text
用户选了 subagent-driven 后,先评估改动规模再决定层数:
< 100 行 + 单/双模块 + 无序列化/DB schema/集群消息
→ inline 实施,不派 implementer
100-300 行 / 多模块 / 单一服务类
→ 派 implementer,单层 review(一个 reviewer 兼顾 spec+quality)
> 300 行 / 序列化 schema / 集群消息 / 跨节点协议 / DB migration
→ 完整三层 review
fix loop 强阈值:单 Task review 找到 ≥3 个 nit 或任意 critical 才派 fix agent;
1-2 个 nit 主对话 inline 直接修
跑超 30 分钟主动停:报「按当前速度估剩余 X 小时,要不要降级」
一句话:三层 review 只伺候真正高风险的改动------DB schema、序列化注册、集群消息、跨节点协议、外部协议验签这些。纯函数、data class、改个配置这种,单层够了,很多时候 inline 就完事。
别一上来全用最强模型
派 subagent 的时候,除了「并行几个」和「review 几层」,还有第三个旋钮,和前两个是正交的:模型档位。
早期我图省事,不管什么活全派最强模型,纯属杀鸡用牛刀。spec reviewer 来来回回干的就是「对着 spec 查实现齐没齐」这种比对活,中档模型绰绰有余,我却拿顶配单价烧着它。
后来固化成一张表:
| 任务类型 | 推荐档位 | 关键判断 |
|---|---|---|
| Explore / 搜索 / 找符号 | 最低档 | 读片段不读全文 |
| 机械实施:data class / 改名 / typo | 最低档 | spec 已定只是写出来 |
| 中等 implementer:单 Handler / Service | 中档 | 几个文件交叉理解,无架构决策 |
| spec reviewer:对照 spec 查齐全 | 中档 | 比对类工作 |
| code-quality reviewer:找 bug / edge case | 顶配 | 烧脑的发散直觉,P0 靠这层挖出 |
| 高风险架构:序列化 / 集群消息 / 外部验签 | 顶配 | 一处错连锁线上事故 |
派最低档模型有个前提:它跨文件推理弱,所以 prompt 里得把具体类名、行号、要改成什么全喂进去,别指望它自己去翻代码。
effort(推理强度)也是同一个道理,要钉在「干一件事」这个粒度上,而不是每条消息上。我把那些机械型 skill(lint、看板同步、文本改写)的 frontmatter 直接标成低 effort,激活时覆盖整个会话,干完自动恢复;高风险编码则在开工前手动拉满,跟三层 review 一起触发。说到底,一次风险判断,同时把「并行度 × review 层数 × 模型档 × effort」四个旋钮拨到位。
为什么 review 同一段代码,每次结论都不一样
我自己一开始也犯嘀咕:同一段代码,让 Claude review 几遍,每次挑出来的毛病都不一样,这正常吗?
正常,而且这恰好是 LLM review 值钱的地方。LLM 的输出本来就有随机性,注意力走的路每次都会飘一点。所以多跑几次轻量 review,攒下来的覆盖面,反而比一次性拿一张大 checklist 死磕要广。
我的 review 方法论也是顺着这个来的:轻量加发散,不搞穷举。特化的 checklist 最多 5 个维度封顶,扫完之后我会特意留出三成的上下文,去发散 checklist 以外的直觉------这部分才是最值钱的。哪个维度连着两次在 checklist 外冒出同类问题,我才把它升级成永久红线。我从不追求覆盖率那个数字,因为 bug 藏在你没列到的第 N+1 个维度上的概率,永远大于零。
nit 当场就修,别攒
最后一条,小但是我吃过亏。review 挑出来的 nit------KDoc 漏了、typo、多余的空行、命名前后不一致这种------要当场让 implementer 在同一个 commit 里顺手修掉,绝对别记进什么「follow-up 清单」。
我以前偷懒,把 8 条 nit 全攒到 progress 文档末尾。结果下次接着干之前,光是重读那张五十来行的清单、一条条重新评优先级、把上下文捡回来,花的功夫早就超过当场五分钟修完的成本了。清单这东西只会越滚越长,攒到最后基本就是永远不修。真正该进 follow-up 的,只有那种「得外部拍板」「要跨任务重构」「影响面大」的。
说到底,并行这件事的内核,就是把「等待」从一段接一段地累加,变成叠在一起一次过;然后用 review 层数、模型档、effort 这几个旋钮,照着风险高低去配火力。但所有这些的前提,是你得先看清这次改动到底多大------别拿一套两小时的重型流程,去砸一个 65 行的小活儿。
下一篇:方法论说完了,该见血了。第 4 篇是整个系列我自己最想写的------四次实打实的翻车,以及每一次翻车最后变成了哪道机制。