视频 · 前往原文观看今年早些时候,我们进行了一系列实验,旨在测试智能体在协作达成目标时的扩展极限。我们的假设是,这将解锁一个全新层级的任务规模与复杂度。
旗舰项目是一个长期运行的智能体集群,从零开始构建一个网页浏览器。它作为概念验证取得了成功,但距离成熟的软件产品还相差甚远。
这项工作刻意采用了经验主义方法。我们从一张白纸出发,通过爬山法逐步优化,最终构建出一个稳定、高效的系统。此后,我们的目标转变为充分理解这个智能体集群,以便能够有意识地对其进行工程设计。
为了检验这一进展,我们重新审视了旧集群曾难以应对的任务:仅凭文档,用 Rust 语言从零开始构建 SQLite。
初步结果令人鼓舞。我们让新旧两个集群在相同任务上运行,使用相同的模型和相同的时间预算,并衡量它们各自能通过多少保留的 SQL 测试套件。
新集群在所有模型配置下都表现更优。使用 Grok 4.5 时,它在四小时内达到了 80% 的通过率,而旧集群则陷入混乱,不得不在第二小时之前暂停运行。
我们还尝试了让不同模型承担不同工作。在某些运行中,一个模型处理所有事务;而在其他运行中,由前沿模型负责规划,同时由一个快速、低成本的模型执行具体工作。每种组合产生的质量都相近,但成本差异巨大。
树与叶
对大型任务的描述自然呈现出树状结构,根节点是目标,然后递归地细分为基本工作单元。我们的集群包含两个角色,都围绕这种相同的树状分解方式组织:
- 规划智能体,由最智能的模型驱动,负责将目标拆解为多个部分并进行委派。
- 工作智能体,通常由更快、成本更低的模型驱动,负责执行这些部分。
该设计是更刚性编排系统的超集。集群的形态并非将固定拓扑结构强加于问题,而是根据问题的轮廓自然生长,计算资源和上下文窗口则根据任务的复杂度按比例扩展。
我们认为这正是该设计能够泛化到构建浏览器、解决数学问题以及优化 GPU 内核等多样化任务的原因。我们还在内部用它来发现并修复开源软件中的漏洞、提升自身代码库的测试覆盖率,以及生成数十亿 token 的合成训练数据。
树结构对内存的作用
当单个智能体承担一项完整任务时,它必须自行遍历整棵树,在下降到每个叶节点的同时,始终在上下文中持有其祖先节点、当前位置以及更宏观的目标。
我们认为这解释了为何长时间运行的单个智能体会出现漂移。它们要么专注于眼前的工作而忽略全局,要么紧抓全局而在具体环节上表现不佳。
在智能体集群中,规划者从不执行具体实现,因此其上下文永远不会被底层细节填满;而执行者从不进行规划,因此可以将全部上下文用于某一项狭窄的工作。
我们推测,智能体集群的扩展能力正源于这种上下文效率,而非并行性本身。这种效率在集群的任意规模下都存在,这也是为何这种分解方式即使在中等规模的任务上也能提升智能体性能。
这种结构在其他领域也有类似体现。经济学家罗纳德·科斯在探讨企业为何存在时指出,协调成本的增长速度超过工作本身,因此组织会形成层级化的有限单元,而非让所有人相互沟通。
面向智能体的版本控制系统
在之前一篇关于智能体集群的文章中,我们提到 Git 和 Cargo 等工具依赖粗粒度锁来实现并发控制。这对单个开发者来说没问题,但对于数百个并发智能体产生的工作量而言则不可行。
今年早些时候的浏览器智能体集群在 Git 上的峰值约为每小时 1000 次提交。新系统的峰值约为每秒 1000 次提交。
为了支撑如此高的活动频率,我们从零构建了一套新的版本控制系统(VCS)。吞吐量并非我们掌控这一层的唯一原因。系统中的每一次变更都会经过 VCS,因此冲突会在这里最先显现,而下一节中提到的若干协调机制也直接实现在 VCS 内部。
每秒 1000 次提交下的故障模式
人类工程团队拥有标准的协调机制,例如代码审查、代码所有权、每日站会和合并队列。这些系统以人类的节奏运行,但在智能体集群的提交速率下,我们看到了人类团队通常不会遇到的故障模式。
脑裂式设计
两个规划器彼此不知情,在代码库的不同部分以不同方式实现了同一个概念。
我们通过提示词修复了这个问题。规划器自行做出设计决策,而不是将决策委托出去,并且我们要求它们确保没有两个被委托的子任务对同一个问题做出决策。
规划器之间的争用
一种更棘手的争用形式是,两个规划器知道彼此的存在,并通过在相同文件上来回修改进行对抗。
问题在于存在两套对现实的认知,而合并工具无法解决分歧。因此,我们让智能体将决策记录在共享的设计文档中。依赖某个决策的代码会携带一个编译时可检查的引用,指向其对应的文档。当规划器在不知情的情况下相互矛盾时,一个协调器会合并这些文档,而引用会将解决方案向下游传播。
合并冲突
在智能体集群内部,智能体们会持续在相同文件上发生碰撞。为了解决冲突,它们必须停下来,吸收另一个智能体的上下文,然后进行合并。工作型智能体不擅长处理这种情况,在实践中,它们要么覆盖掉对方的修改,要么放弃自己的修改。
为了解决这个问题,我们创建了一个系统,由中立的第三方智能体介入合并冲突,并代表所有相关方解决冲突。它的唯一目标是保持公正和高效,类似于工程团队中合并队列的工作方式。
巨型文件
某些文件是智能体特别青睐的工作场所。每个智能体可能只添加少量代码,但没有哪个智能体负责保持这些文件短小精悍。
这些“巨型文件”会拖慢一切。它们传输、比较差异和合并的成本都很高,并且会成为持续冲突的根源。
为了解决这个问题,我们为工作智能体提供了一种标记臃肿文件的方法。一旦被标记,我们就阻止新的提交,并由一个外部智能体将过度膨胀的文件分解成更小的模块。
僵化
智能体在与人类协作处理现有代码库的过程中学会了不去触碰核心代码,即使这些代码需要修改。
为了解决这个问题,我们允许有意的破坏。一个判断核心改动有价值的智能体可以在其职责范围之外制作一个有针对性的补丁,并留下注释解释其修改原因。
编译器将改动传递到系统的其余部分,所有依赖旧设计的部分都会构建失败。每个遇到这些错误的智能体都会找到注释,阅读推理过程,并更新自己的工作以保持一致。
审查视角
在一个既长期运行又涉及多智能体的系统中,错误会不断累积,智能体集群需要一种在微小错误演变成根本性问题之前自我纠正的方法。
我们尝试了多种审查视角,例如向审查智能体提供工作智能体的完整记录,或仅提供其输出,或只提供代码库本身。我们还尝试让审查者运行在不同的模型上,这些模型具有不同的训练数据和不同的特性。
没有单一的视角能捕捉所有问题,但去相关化的视角可以叠加,就像自动驾驶系统无需任何单个完美组件就能达到超越人类的可靠性一样。用于审查的计算投入回报率很高,因为审查比它所审计的工作要便宜得多。我们怀疑这种叠加的审查系统是运行质量得以持续保持的主要因素。
让智能体塑造环境
间接协调是蚂蚁和白蚁等集群生物无需直接沟通就能协调的机制。它们塑造环境,而环境又反过来塑造下一个生物体。
在早期的运行中,我们编码了诸如“保留笔记”和“记录决策”之类的规则,因为它们看起来显然是有益的。事后看来,这些规则让智能体能够为其未来的自身和队友将知识制度化。
我们通过一项名为“现场指南”的、由智能体自行编写并共享上下文的实验,进一步推进了这一理念。这是一个完全由智能体拥有的文件夹,其 `index.md` 文件会在每次启动时自动注入到每个智能体中。由智能体负责策划指南中的内容,而它们唯一的限制是一个行数预算。
该指南的基本逻辑是,模型权重是冻结的,因此正是那些意外的遭遇值得被记录下来,以便下一个智能体的轨迹更短。
“现场指南”是一项早期的实验,已展现出有希望的结果。我们预计,在智能体并非完全拥有的代码库上,其收益会更大。训练模型为其后继者编写内容,其中更好的记录能带来更好的奖励,这是一个有趣的研究后续方向。
SQLite 实验
我们指示配备了上述所有改进的新版智能体集群,用 Rust 实现整本 835 页的 SQLite 手册。我们扣留了源代码、测试套件、SQLite 二进制文件以及互联网访问权限。
为了衡量进展,我们根据 sqllogictest 进行评分,这是 SQLite 项目中的一个测试套件,旨在检查不同的数据库引擎对相同查询是否返回相同结果。它包含数百万个带有已知正确答案的查询,评分是智能体集群的数据库答对的比例。进展表现为运行过程中不断上升的曲线。
从未告知智能体集群该测试套件的存在。每次运行后,我们都会手动审查代码和运行过程本身,检查是否存在作弊和走捷径的行为,并确认系统是均匀构建的,而不仅仅是针对测试所检查的地方。
在阅读这些曲线时,请记住智能体选择了自己的策略。有些智能体建立了广泛的基础,在后期出现峰值之前,长时间得分较低;而另一些则深入一个领域,早期得分,然后在填补其余部分时进入平台期。趋势比特定时刻的精确得分更重要。
不同模型组合的结果
我们测试了四种覆盖不同能力与成本的配置:
- GPT-5.5 同时担任规划者与执行者。全程使用强大的前沿模型。
- Grok 4.5 同时担任规划者与执行者。作为对比基准,这是我们成本高效的前沿模型。
- Opus 4.8 担任规划者,Composer 2.5 担任执行者。前沿判断力搭配高效执行。
- Fable 5 担任规划者,Composer 2.5 担任执行者。旨在观察次一级的规划者是否会让混合架构的性价比发生变化。
新测试框架在所有组合中的表现均优于旧框架。
Fable 5 混合架构在第一个小时内通过了约三分之二的测试集。到四小时截止时,新运行的通过率介于 73% 到 85% 之间,而旧运行的通过率则在 11% 到 77% 之间。
旧的 Grok 4.5 运行在两小时标记前被暂停(详情见下文)。每种新配置最终都 100% 通过了测试集。
未来我们希望运行完整的规划者-执行者 N×N 组合矩阵。在本轮测试中,有意义的对比在于新旧框架版本之间,而行为上的差异远比分数差异所显示的更为显著。
深入分析运行过程
从最简单的活动度量指标入手,我们可以看到 Grok 4.5 在旧框架与新框架下的提交频率差异。旧运行在前两小时内产生了 68,000 次提交,大约是新型运行速度的 70 倍。
一种解读是它的效率更高。另一种解读则是,这些提交中的大部分都是无效劳动(系统颠簸、资源争用、频繁变更)。
合并冲突数据指向了后一种解释。旧运行在被我们暂停前积累了超过 70,000 个冲突,且冲突数量呈加速增长而非趋于稳定;而新运行在整整四小时内记录的冲突不到一千个。
冲突集中在文件变得最大的地方。在旧运行中,最大的文件在整个运行期间持续增长,其中单个最热门的文件积累了 7,771 个冲突,被 1,173 个不同的智能体修改过。在新运行中,整个代码库中争议最大的文件仅出现了 47 个冲突。
旧智能体群最大的协调失败——脑裂,或者规划者重复彼此的工作——在包结构中暴露无遗。Rust 代码按称为 crate 的包来组织,在这样的项目中,每个 crate 大致对应一个主要组件。
旧版本运行扩展到 54 个 crate,其中包括三个独立的 SQL 包。新版本运行早期就确定了九个 crate,并且之后从未增加。
所有这些都体现在最终的代码库中。在 Fable 5 组合中,新旧两个智能体群最终都通过了全部测试套件,但旧版本需要 64,305 行引擎代码,而新版本只用 9,908 行就完成了。Opus 组合也呈现相同模式:旧框架下用了 19,013 行代码,达到 97% 的评分;新框架下仅用 4,645 行代码,就达到了 100% 的评分。
模型经济学
我们在开头提到,每个模型组合产生的质量相近,但成本差异巨大,从 Opus 4.8 混合方案的 1,339 美元到单独使用 GPT-5.5 的 10,565 美元不等。token 数据揭示了这种差异的来源。
每次运行的开销结构都是一致的,工作模型承担了至少 69% 的 token,在大多数情况下甚至超过 90%。
但美元花费的分配方式与 token 不同,因为规划者 token 的成本更高。在 Opus 4.8 和 Composer 2.5 的组合中,作为规划者的 Opus 产生了少量 token,却占了大约三分之二的成本;而作为工作模型的 Composer 处理了绝大多数 token,只占剩余三分之一的成本。
在大型任务中,真正需要前沿智能的时刻并不多,例如最初的分解、设计决策以及某些权衡。一旦前沿规划者将模糊性化解为详细、明确的指令,成本较低的模型只需遵循指令即可。这是一个巨大的潜在成本节约来源。在同时使用 GPT-5.5 作为规划者和工作模型的运行中,仅工作模型就花费了 9,373 美元。而在使用 Opus 4.8 进行规划、Composer 2.5 执行工作的运行中,整个工作模型群的总成本仅为 411 美元。
比较两次混合运行的结果,有一个细节值得注意。Fable 5 规划器产生的费用略低于 Opus 4.8 规划器,尽管其每 token 价格大约是后者的两倍,因为它使用的规划 token 要少得多。但 Fable 运行的 worker 消耗的 token 数量是前者的数倍,导致整个运行的总成本显著更高。
将规格说明作为提示词
AI 能力的每一次跃升,都提高了工程师能够工作的抽象层级。
自动补全让工程师可以一次编写一行代码。早期模型将其提升到一个代码块,而智能体则将其提升到一个文件或一个功能。
到了智能体集群,工作的基本单元变成了规格说明。
要实现这一点,集群必须真正遵循规格说明,而这正是本文大部分内容所探讨的。我们向集群提供了 835 页的叙述性文本,它返回了一个数据库。在这个实验中稀缺的,也是我们预计在未来的软件工程中会稀缺的,是对意图的正确描述。
从这个角度看,智能体集群开始类似于一个编译器。编译器通过一系列中间步骤将源代码翻译成机器码。智能体集群对意图也做着类似的事情。规划器将目标解析为任务树,然后逐步将其降级为可执行的工作。区别在于,编译器在每一步都保持语义不变,而智能体集群在每一步都是概率性的。本文描述的一切,都是为了缩小这一差距。
我们邀请您探索智能体集群的输出。来自单独 Opus 4.8 运行的代码库已公开在 github.com/cursor/minisqlite。根据我们的初步观察,它看起来很棒,但我们尚未进行更深入的人工分析。请自行查看,并告诉我们您的发现。
- 为了了解单独使用前沿模型的成本,我们还单独运行了 Opus 4.8 和 Fable 5。我们仅对这些运行进行了非正式评估,因此在此不对其质量下任何结论,不过根据经验,我们预计这两个模型都会表现良好。它们的成本在图表中以阴影条显示。↩
- 我们原本希望将 GPT-5.6 Sol 作为前沿配置。这个新模型对我们测试过的其他模型相比,似乎对字面措辞和强调性措辞更为敏感,并且我们遇到了其他模型从未产生过的失控循环问题。由于这个模型来得太晚,没有时间为其调整提示词,而只针对一个模型进行调整却保持其他模型不变,又会导致对比不准确,因此我们退而使用了 GPT-5.5。 ↩