Agent 集群,首先是个分布式系统问题
最近读到两篇文章,放在一起看很有意思:Cursor 的 Agent Swarms and Model Economics,和 Anthropic 的 大规模代码迁移实践。
它们讲的其实是同一件事的两半:怎么把一群 Agent 调度起来干活,以及怎么确认它们干对了。
而让我印象最深的,不是“AI 能写多少代码”,是另一件事——里面不少难题读着眼熟,不妨参照分布式系统来看。
树与叶子:分工的理由变了
Cursor 把 Agent 组织成一棵任务树,节点分两种角色:
Planner agents, powered by the smartest models, split a goal into pieces and delegate them. Worker agents, generally powered by faster and less expensive models, execute those pieces.
Planner 用最强的模型,负责把目标拆开、分派下去;Worker 用更快更便宜的模型,负责执行。
这个结构可以参照 MapReduce、YARN 的 ResourceManager/NodeManager,或者更早的 master/worker。但关键不在“分工”这件事本身,而在他们为什么要这么分——原文里那句话是整个架构的地基:
a planner never implements, so its context never fills with low-level detail, and a worker never plans, so it can spend all its context on one narrow piece of work.
Planner 从不动手,所以它的上下文不会被实现细节填满;Worker 从不规划,所以它能把全部上下文花在一件窄事上。
这才是新东西。传统 master/worker 里,分工是为了并行、为了扩展。而这里分工是为了保护一种全新的稀缺资源:上下文。
而且这种资源和 CPU、内存很不一样。内存不够会 OOM,会硬失败,你立刻知道出事了。上下文被填满不会崩——它只是慢慢变笨。一个跑了很久的单体 Agent,不会给你抛异常,它只会开始遗忘早先的约定、重复已经做过的事、在细节里丢掉大目标。这是一种没有告警的退化。
所以“planner 从不 implement”不是洁癖,是在给一个会静默劣化的资源划边界。
一秒一千次提交:并行写代码是真正的并发控制问题
这是我觉得最精彩的一段。他们把新旧两版调度系统放在一起对比,数字非常直白:
旧版本跑 Grok 4.5,头两个小时产生了 68,000 次提交,然后累积了超过 70,000 个冲突——而且冲突数还在加速增长,最后他们只能把任务掐掉。
新版本,同样规模的工作,四个小时里的冲突总数不到一千个。
最终产物的差距更夸张:旧版本跑出 54 个 Rust crate,里面有好几套重复的 SQL 实现,代码 64,305 行;新版本稳定在 9 个 crate,9,908 行——而且通过率更高。
这组数字指向一个词:thrashing。
那条曲线很熟悉——并行度提高不等于吞吐提高。往锁竞争严重的系统里加线程,吞吐会先涨后跌,因为冲突解决的开销是超线性的。八十个 Agent 同时改一个代码库,和八十个线程抢同一把锁,面对的是同一类争用。
而他们的三个解法,也全是老朋友:
- Design doc + 编译期可检查的引用。Planner 把决策写进共享文档,代码引用这些决策,冲突时能顺着引用传播。说白了就是把口头约定变成机器可校验的契约——可以参照 schema、IDL、protobuf。约定只有能被机器检查,才在高并发下站得住。
- 中立的第三方 Agent 解冲突。不是让当事双方吵,而是引入一个不带立场的仲裁者。这个设计在共识协议里也很常见。
- 拆解 megafile。自动识别那些变得过于臃肿、成为协作瓶颈的文件,然后拆开。这很接近热点分区:一个所有人都要写的文件,和一个所有请求都打到同一个 shard 的库,处境差不多。
我甚至觉得,“1,000 commits per second”这个指标本身就说明问题——当你的版本控制需要按“每秒提交数”来度量时,你面对的已经不是版本管理,是一个分布式写入系统。Git 不是为这个场景设计的,所以他们得自己造。
账单在哪里:一个反直觉的成本结构
这部分对做技术决策的人最有参考价值。他们用同一个任务(从零用 Rust 实现 SQLite,只给文档,用 sqllogictest 打分)跑了几种模型组合,四小时预算:
| 组合 | 结果 | 成本 |
|---|---|---|
| GPT-5.5 同时做 planner 和 worker | 85% 通过 | $10,565 |
| Grok 4.5 同时做两者 | 80%(不到两小时被叫停) | 高于混合方案 |
| Fable 5 planner + Composer 2.5 worker | 100% 通过 | ~$2,800 |
| Opus 4.8 planner + Composer 2.5 worker | 100% 通过 | $1,339 |
先看结论:混合方案便宜了将近 8 倍,而且质量更好。
这不是一个 trade-off,是一次 Pareto 改进。这一点值得停下来想想——通常“又好又便宜”是不成立的。
真正解释这件事的,是下面这个成本结构:
workers carrying at least 69% of the tokens, and over 90% in most
Worker 至少承担 69% 的 token,多数情况超过 90%。但是——
the Opus-as-planner produced a small fraction of the tokens but roughly two-thirds of the cost
Planner 产出的 token 只占一小部分,却吃掉了大约三分之二的成本。
token 的大头在 worker,钱的大头在 planner。
所以优化的着力点非常清楚。他们给的对比是:GPT-5.5 全包那次,光 worker 就烧了 $9,373;换成 Opus 做规划、Composer 干活之后,整个 worker 集群只花了 $411。
我的理解是这样:贵的模型应该放在“决策密度最高”的地方,而不是“token 量最大”的地方。
这个原则听起来平平无奇,因为它和分配硬件资源的直觉是一致的——没有人会给整个集群都上最贵的机型,钱只花在瓶颈上。但它和当下“用最好的模型做所有事”的直觉是相反的。
而且它能成立,是因为两件事同时为真:便宜模型在“指令明确、范围很窄”的任务上并不差;贵模型在超长上下文里反而会被细节淹没。前面那个 planner/worker 的上下文边界,和这里的成本结构,其实是同一件事的两个侧面。
另一半:你不修代码,你修那个循环
如果说 Cursor 那篇解决的是“怎么让一群 Agent 高效干活”,Anthropic 那篇解决的是更要命的问题:你怎么知道它们干对了?
那篇文章里最狠的一句:
The core insight is that you don’t fix the code. You fix the process (loop) that produced the code.
你不修代码,你修那个产出代码的循环。
这句话背后是一个规模上的事实。他们把 Bun 从 Zig 迁到 Rust,两周内产出一百万行代码,消耗 59 亿 uncached 输入 token 和 6.9 亿输出 token,按 API 定价约 $165,000。在这个量级上,你根本没有“逐个 review”这个选项。发现一个错误模式,唯一有意义的动作是回去改规则、改流程,让它在全部 1,448 个文件上一次性消失。
于是验证必须变成机械的:
Make review adversarial and verification mechanical. Let scripts — a compiler, a diff, a test suite — be the referee.
让编译器、diff、测试套件来当裁判。
再加上对抗式 review——用独立上下文的多个 reviewer 交叉检查,有分歧就升级。为什么必须独立上下文?因为共享上下文的 reviewer 会继承同样的偏见,相当于让同一个人 review 自己的代码。
还有一个细节:
Done should mean “the output file exists on disk.”
“完成”的定义应该是“产物文件在磁盘上存在”。 不是 Agent 说它做完了,是磁盘上有那个文件。这样队列随时可以从磁盘状态重建,任务天然幂等、可恢复、能断点续跑。
这套纪律在批处理和任务队列里是老生常谈。只是在一个非确定性的系统里,它变得更加不可妥协——因为你连“重试一次会得到同样结果”这个前提都没有了。你不能信任何节点的自我报告,只能信外部的、机械的判据。
那么,做类似的事该怎么想
把两篇合起来,我觉得如果要在自己的项目里做类似的事(大规模重构、语言迁移、批量代码生成),得先老实回答三个问题:
1. 我的“机械裁判”是什么?
这是准入门槛,不是加分项。没有编译器、没有能跑的测试套件、没法做行为比对,整套范式就不成立——你会得到一百万行没人能验证的代码,那比没有更糟。
顺带说一句:他们那篇文章里提到,对于没有测试套件的项目,做法是先让 Agent 把测试套件建起来。这其实暗示了真正的第一步是什么。
2. 我的任务能不能切成“一个 worker 一次装得下”的片段?
如果任务本身高度耦合、每一片都要理解全局才能动手,那 planner/worker 的分离就没有意义,你只是在给自己制造沟通开销。
3. 我的冲突面有多大?
如果所有 Agent 最后都要改同样那几个文件,并行度就是负收益——那 70,000 个冲突就是前车之鉴。上 swarm 之前,先看看你的代码库有没有 megafile。
成本这件事的性质也变了。以前“要不要做这次迁移”是个立项问题,要论证几个人年、几百万预算;现在它更接近一个采购决策——这个长期卡着我们的瓶颈,值不值几万美元和两周时间。这个变化本身,可能比技术细节更重要。
一点思考
这两篇都是厂商自己发的,benchmark 也是自选的。而“从零实现 SQLite”恰恰是最理想的场景——SQLite 有极其完备、可机器执行的测试套件(sqllogictest),行为规范清晰,正确性有明确定义。同理,Bun 的迁移之所以能做,前提是“100% 现有测试套件在合并前通过 CI”。
可现实项目里,最大的困难往往恰恰是没有可靠的判据:测试覆盖率感人、需求写在某个人脑子里、“正确”本身就是模糊的。在那种地方,Agent 集群跑得越快,产出的不确定性反而越大。
所以我的看法是:这两篇文章真正的价值,不是“AI 能写一百万行代码”,而是它们把条件说清楚了——需要什么样的调度、什么样的契约、什么样的裁判。而这些条件里,绝大部分是老的工程纪律,不是新的模型能力。
调度、契约、仲裁、幂等、验证。执行单元变了,这些反而更重要了。