代理群（Agent Swarm）通过树状分解在构建 SQLite（Rust 版）任务中达到 80% 测试通过率

今年早些时候，我们进行了实验，测试扩展代理以协作实现目标的极限。我们的假设是，这将解锁新一层的任务规模和复杂性。

旗舰项目是一个长期运行的群体，从零开始构建一个网页浏览器：/blog/scaling-agents。它作为概念验证取得了成功，但距离完善的软件还有很大差距。

这项工作是刻意进行的经验研究。我们从空白画布开始，通过爬山法逐步建立一个稳定、有效的系统：/blog/self-driving-codebases。从那时起，我们的目标是充分理解代理群体，以便能够有意地进行工程设计。

为了测试这一进展，我们回到了旧群体曾经苦苦挣扎的任务：从零开始用 Rust 构建 SQLite，而且只能依据其文档。

我们的初步结果令人鼓舞。我们让旧的和新的群体在相同任务上运行，使用相同的模型和相同的时间预算，并测量每个群体能够通过的预留 SQL 测试套件的比例。

新的群体在每种模型配置下表现都更好。使用 Grok 4.5，它在四小时内达到 80%，而旧群体则陷入混乱，并在第二小时之前不得不停下。

我们还改变了模型的分工。在一些运行中，一个模型负责全部任务，而在另一些运行中，一个前沿模型负责计划，而一个快速、廉价的模型执行工作。每种组合产生的质量相似，但成本差异巨大。1：#fn-1

大型任务的描述自然呈现树状结构，根节点为目标，递归细分为基本工作单元。我们的群体有两个角色，都是围绕同样的树状分解组织的：

这种设计是更严格的编排系统的超集。它不是在问题上强加固定拓扑，而是群体的形状随问题的轮廓成长，计算和上下文规模按任务复杂度成比例增长。

我们认为这就是为什么这种设计可以推广到如此多样的任务，比如构建浏览器：/blog/scaling-agents、解决数学问题：https://x.com/mntruell/status/2028903020847841336，以及优化 GPU 内核：/blog/multi-agent-kernels。我们还在内部使用它来发现并修复开源软件中的漏洞，提高我们自己代码库的测试覆盖率，以及生成数十亿个训练数据的合成标记。

当单个智能体承担完整任务时，它必须自行遍历整个树，沿途下降到每个叶节点，同时始终保持其祖先、当前位置以及更广泛目标的上下文。

我们认为这解释了为什么长期运行的单个智能体会漂移。它们要么专注于眼前任务而忽视更大局面，要么关注大局而在具体任务上表现较差。

在蜂群中，规划者从不执行，因此其上下文中从不会充满低级细节；而执行者从不规划，因此它可以将所有上下文投入到一项狭窄的工作中。

我们怀疑，智能体蜂群的可扩展性来自这种上下文效率，而不是并行性本身。这种效率在不同规模的蜂群中都存在，这就是为什么这种任务分解即使在中等规模任务上也能提高智能体的性能。

这种结构在其他地方也有呼应。经济学家罗纳德·科斯（Ronald Coase）在探讨企业为何存在时提出：https://en.wikipedia.org/wiki/The_Nature_of_the_Firm 协调成本增长速度快于工作本身，因此组织倾向于形成有边界的层级单元，而不是让每个人都互相交流。

在关于蜂群的早期文章中：/blog/self-driving-codebases，我们指出，像 Git 和 Cargo 这样的工具依赖粗粒度锁进行并发控制。这对单个开发者没问题，但对于数百个并发智能体产生的工作量来说则不可行。

今年早些时候的浏览器蜂群在 Git 上的峰值大约为每小时 1,000 次提交。新系统的峰值约为每秒 1,000 次提交。

为了实现这个活动频率，我们从零构建了一个新的版本控制系统（VCS）。吞吐量并不是拥有这一层的唯一原因。系统中的每一次更改都必须通过VCS，因此它是碰撞首次显现的地方，并且下一部分中的几个协调机制直接在其内部实现。

人类工程团队有标准的协调机制，如代码审查、所有权、站会和合并队列。这些系统以人类的节奏工作，但在“蜂群”的提交速度下，我们会看到人类团队通常不会遇到的失败模式。

两个计划者彼此不知情，却在代码库的不同部分以不同方式实现相同的概念。

我们通过提示解决了这个问题。计划者自己做设计决策，而不是委派它们，我们要求他们确保没有两个被委派的子树做出相同的问题决策。

更困难的一种争用情况是两个计划者彼此知情，并在相同文件上通过来回更改进行争夺。

问题在于现实的两个不同“图像”，合并工具无法解决分歧。相反，我们让代理在共享设计文档中记录决策。依赖某个决策的代码带有一个经过编译检查的引用，指回其文档。当计划者无意中相互矛盾时，协调器会合并文档，并且引用将解决方案传播到下游。

在蜂群中，代理不断在相同文件上发生碰撞。为了解决碰撞，他们必须停下来，吸收其他代理的上下文，并围绕它进行合并。工作人员代理对此很不擅长，实际上，要么覆盖其他更改，要么放弃自己的更改。

为了解决这个问题，我们创建了一个系统，在合并冲突中由中立的第三方代理介入，并代表所有各方解决冲突。它的唯一目标是保持公正和高效，类似于工程团队中的合并队列。

有些文件特别受代理欢迎。每个代理可能只添加少量代码，并且没有单个代理负责保持文件小巧。

这些“巨型文件”会使所有事物阻塞。它们传输、比对和合并都很昂贵，并且成为持续碰撞的地点。

为了解决这个问题，我们给工人代理提供了一种标记臃肿文件的方法。一旦被标记，我们会阻止新的提交，并由外部代理将过大文件分解成较小的模块。

代理从与人类协同工作的现有代码库中学会了，即使核心代码需要更改，也不要去触碰它。

为了解决这个问题，我们允许有意破坏。一个判断核心更改有价值的代理可以在其职责范围之外进行集中修补，并留下评论解释为什么这样做。

编译器将更改传递到系统的其余部分，所有依赖旧设计的部分都会构建失败。每个遇到这些错误的代理会找到评论，阅读其理由，并更新自己的工作以匹配。

在一个既长期运行又多代理的系统中，错误会逐渐累积，群体需要在小错误成为基础性问题之前找到自我修正的方式。

我们尝试了许多类型的审查镜头，例如给审查代理提供工人的完整记录，或仅提供其输出，或者只提供代码库。我们还尝试了运行在不同模型上的审查者，具有不同训练和不同个性。

没有单一的镜头能捕捉所有问题，但不相关的镜头叠加，就像自动驾驶系统在没有任何单一完美组件的情况下达到超越人类的可靠性。用于审查的计算量回报很高，因为审查比它审查的工作便宜得多。我们怀疑这种叠加审查系统是运行质量持续稳定的主要原因之一。

Stigmergy：https://en.wikipedia.org/wiki/Stigmergy 是蚂蚁和白蚁等群体生物在没有直接交流的情况下协调行为的机制。它们塑造环境，而环境又塑造下一个生物的行为。

我们在早期运行中编码了类似“保留笔记”和“记录决策”的规则，因为它们看起来显然是好的。事后看来，这些规则让代理为将来的自己和团队成员制度化地保存知识。

我们通过一个名为《野外指南》的自编共享上下文实验进一步推进了这一点。它是一个完全由代理拥有的文件夹，里面的 index.md 会在每个代理启动时自动注入。代理的任务是策划指南中包含的内容，他们唯一的限制是行数预算。

指南的基本逻辑是模型权重被冻结，因此正是那些意外的遭遇值得记录，以便下一个代理轨迹更短。

《野外指南》是一个早期实验，结果很有前景。我们预计在代理不完全拥有的代码库上，这些好处会更大。训练模型为它们的继任者撰写内容，其中更好的记录能带来更高的回报，是一个有趣的后续研究方向。

我们指示配备了上述所有改进的新版本蜂群用 Rust 实现整个 835 页的 SQLite 手册。我们没有提供源代码、测试套件、SQLite 二进制文件和互联网访问。

为了衡量进展，我们使用 sqllogictest：https://www.sqlite.org/sqllogictest/doc/trunk/about.wiki 进行评分，这是 SQLite 项目提供的测试套件，用于检查不同数据库引擎在相同查询下是否返回相同结果。它包含数百万个已知正确答案的查询，评分是蜂群数据库答对的比例。进展体现为运行过程中成绩曲线的上升。

蜂群从未被告知测试套件的存在。每次运行后，我们都会手动审查代码和运行情况，检查是否有作弊或捷径，并确认系统是全面构建，而不仅仅是构建在测试所在的位置。

在阅读曲线时，请记住代理自行选择策略。有些代理构建了广泛的基础，在几个小时内得分很低，然后晚些时候才出现高峰；而另一些代理则专注于某一领域，得分较早，然后在填充其余部分时保持平稳。趋势比精确时刻的分数更重要。

我们测试了四种涵盖能力和成本的配置：

新工具在每种组合中都优于旧工具。

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%的代币，在大多数情况下超过了90%。

但是美元分配与代币不同，因为规划者代币更贵。在 Opus 4.8 和 Composer 2.5 的混合中，作为规划者的 Opus 只产生了少量代币，但大约承担了三分之二的成本，而作为工人的 Composer 则处理了绝大多数代币，花费了剩下的三分之一成本。

在一项大型任务中，真正需要前沿智能的时刻很少，例如最初的分解、设计决策以及某些权衡。一旦前沿规划者将模糊性转化为详细、明确的指令，成本较低的模型只需遵循执行。这是节省成本的巨大潜力来源。在使用 GPT-5.5 作为规划者和工人的运行中，仅工人的成本就为 $9,373。而在 Opus 4.8 做规划、Composer 2.5 做工作的运行中，整个工人队伍的成本仅为 $411。

值得注意的一个细节来自比较两次混合运行。Fable 5 规划者的账单略低于 Opus 4.8，尽管每个代币的价格大约是其两倍，因为它使用的规划代币远少于 Opus。但 Fable 运行的工人使用了数倍的代币，整个运行的总成本显著更高。