DeepSeek总结的用智能体团队构建一个 C 编译器

用并行 Claude 团队构建一个 C 编译器

原文地址:https://www.anthropic.com/engineering/building-c-compiler
发布日期: 2026年2月5日

我们让 Opus 4.6 使用智能体团队来构建一个 C 编译器,然后(大部分)走开让它自主运行。以下是这次实验关于自主软件开发未来的一些启示。

  • 启用长期运行的 Claude 智能体
  • 并行运行 Claude
  • 使用 Claude 智能体团队编程的经验教训
  • 压力测试智能体团队的极限
  • 展望未来

作者:Nicholas Carlini,我们安全防护团队的研究员。

我一直在试验一种我们称之为"智能体团队"的监督语言模型的新方法。

通过智能体团队,多个 Claude 实例可以并行处理一个共享的代码库,无需人类主动干预。这种方法极大地扩展了大型语言模型智能体可实现的任务范围。

为了对其进行压力测试,我让 16 个智能体从头开始编写一个基于 Rust 的 C 编译器,要求其能够编译 Linux 内核。经过近 2000 次 Claude Code 会话和 20,000 美元的 API 成本,这个智能体团队产出了一个包含 10 万行代码的编译器,可以在 x86、ARM 和 RISC-V 架构上构建 Linux 6.9。

这个编译器本身就是一个有趣的作品,但我在这里主要关注的是在设计和运行长期自主智能体团队时所获得的经验:如何编写测试以确保智能体在没有人类监督的情况下保持正轨,如何构建工作流程以使多个智能体能够并行推进,以及这种方法在何处会达到其极限。

启用长期运行的 Claude 智能体

现有的智能体框架(如 Claude Code)需要操作员在线并随时准备协同工作。如果你要求模型解决一个长期而复杂的问题,模型可能会解决其中一部分,但最终它会停下来等待进一步的输入------一个问题、状态更新或请求澄清。

为了促使智能体能够持续、自主地取得进展,我构建了一个"控制程序",将 Claude 置于一个简单的循环中(如果你见过 Ralph-loop,这看起来应该很熟悉)。当它完成一项任务时,它会立即开始下一项任务。(请在容器中运行此程序,而不是在你的实际机器上)。

bash 复制代码
#!/bin/bash

while true; do
    COMMIT=$(git rev-parse --short=6 HEAD)
    LOGFILE="agent_logs/agent_${COMMIT}.log"

    claude --dangerously-skip-permissions \
           -p "$(cat AGENT_PROMPT.md)" \
           --model claude-opus-X-Y &> "$LOGFILE"
done

在给智能体的提示中,我告诉 Claude 要解决的问题,并要求它通过将问题分解成小块、跟踪正在处理的内容、确定下一步的工作,并持续进行直到完美解决。关于最后一点,Claude 别无选择。这个循环会永远运行下去------尽管有一次,我确实看到 Claude 不小心运行了 pkill -9 bash,从而杀死了自己并结束了循环。糟糕!

并行运行 Claude

并行运行多个实例可以解决单智能体系统的两个弱点:

  1. 一个 Claude Code 会话一次只能做一件事。特别是随着项目范围的扩大,并行调试多个问题要高效得多。
  2. 运行多个 Claude 智能体允许专业化分工。当一些智能体负责解决手头的实际问题时,可以调用其他专业智能体来(例如)维护文档、关注代码质量或解决专门的子任务。

我实现的并行 Claude 系统非常简单。创建一个新的空的 git 仓库,并为每个智能体启动一个 Docker 容器,将仓库挂载到 /upstream。每个智能体将仓库克隆到本地的 /workspace 目录,完成后,将其更改从自己的本地容器推送到上游仓库。

为了防止两个智能体同时尝试解决同一个问题,控制程序使用了一个简单的同步算法:

  1. Claude 通过在 current_tasks/ 目录下写入一个文本文件来"锁定"一个任务(例如,一个智能体可能锁定 current_tasks/parse_if_statement.txt,而另一个锁定 current_tasks/codegen_function_definition.txt)。如果两个智能体试图获取同一个任务,git 的同步机制会迫使第二个智能体选择不同的任务。
  2. Claude 处理该任务,然后从上游拉取更改、合并其他智能体的更改、推送自己的更改,并移除锁定。合并冲突很常见,但 Claude 足够聪明来处理这些冲突。
  3. 无限的智能体生成循环会启动一个新的 Claude Code 会话到一个新的容器中,循环重复。

这是一个非常早期的研究原型。我尚未实现任何其他智能体间通信的方法,也没有强制任何管理高级目标的过程。我没有使用协调智能体。

相反,我让每个 Claude 智能体自己决定如何行动。在大多数情况下,Claude 会选择处理"下一个最明显"的问题。当遇到 bug 时,Claude 通常会维护一个记录失败方法和剩余任务的运行文档。在项目的 git 仓库中,你可以阅读历史记录,观察它获取各种任务锁的过程。

使用 Claude 智能体团队编程的经验教训

框架让 Claude 在一个循环中运行,但只有 Claude 能够判断如何取得进展时,这个循环才有用。我的大部分精力都花在了围绕 Claude 设计环境上------测试、环境、反馈------以便它能够在我不在的情况下自我定位。以下是我在协调多个 Claude 实例时发现最有帮助的方法。

编写极高品质的测试

Claude 将自主工作以解决我交给它的任何问题。因此,任务验证器必须近乎完美,否则 Claude 可能会解决错误的问题。改进测试框架需要找到高质量的编译器测试套件,为开源软件包编写验证器和构建脚本,并观察 Claude 犯的错误,然后根据识别出的故障模式设计新的测试。

例如,在项目接近尾声时,Claude 在每次实现新功能时,经常会破坏现有功能。为了解决这个问题,我建立了一个持续集成管道,并实施了更严格的约束,让 Claude 能够更好地测试其工作,从而确保新的提交不会破坏现有代码。

设身处地为 Claude 着想

我必须不断提醒自己,我是在为 Claude 编写这个测试框架,而不是为我自己,这意味着需要重新思考我对测试应该如何传达结果的许多假设。

例如,每个智能体都被放入一个没有上下文的新容器中,会花费大量时间进行自我定位,尤其是在大型项目上。甚至在运行测试之前,为了帮助 Claude 帮助自己,我提供了指示,要求维护广泛的 README 和进度文件,这些文件应频繁更新当前状态。

我还牢记语言模型有其固有的局限性,在这种情况下需要围绕这些局限性进行设计。这些包括:

  • 上下文窗口污染 :测试框架不应打印数千个无用的字节。最多应打印几行输出,并将所有重要信息记录到文件中,以便 Claude 在需要时可以找到。日志文件应易于自动处理:如果有错误,Claude 应写入 ERROR 并将原因放在同一行,以便 grep 能够找到。预先计算汇总统计数据有助于 Claude 无需重新计算。
  • 时间盲视 :Claude 无法感知时间,如果任其运行,它会很乐意花费数小时运行测试而不是取得进展。框架会不频繁地打印增量进度(以避免污染上下文),并包含一个默认的 --fast 选项,运行 1% 或 10% 的随机样本。这个子样本对每个智能体是确定性的,但在不同虚拟机之间是随机的,因此 Claude 仍然覆盖所有文件,但每个智能体都能完美地识别出回归问题。

让并行变得容易

当有很多不同的失败测试时,并行化是轻而易举的:每个智能体选择不同的失败测试来处理。在测试套件达到 99% 的通过率后,每个智能体负责让一个不同的小型开源项目(例如 SQlite、Redis、libjpeg、MQuickJS、Lua)能够编译。

但是,当智能体开始编译 Linux 内核时,它们卡住了。与拥有数百个独立测试的测试套件不同,编译 Linux 内核是一项巨大的单一任务。每个智能体都会遇到同样的 bug,修复那个 bug,然后互相覆盖彼此的更改。运行 16 个智能体并没有帮助,因为每个都卡在解决同一个任务上。

解决方法是使用 GCC 作为一个在线已知正确的编译器参考来进行比较。我编写了一个新的测试框架,它随机地使用 GCC 编译内核的大部分文件,只对剩余的文件使用 Claude 的 C 编译器。如果内核正常工作,那么问题就不在 Claude 编译的文件子集中。如果内核损坏了,那么它可以进一步细化,用 GCC 重新编译这些文件中的一部分。这让每个智能体并行工作,修复不同文件中的不同 bug,直到 Claude 的编译器最终能够编译所有文件。这之后,仍然需要应用增量调试技术来找到那些单独编译通过但一起编译会失败的文件对。

多种智能体角色

并行化还支持专业化分工。LLM 编写的代码经常重新实现现有功能,因此我让一个智能体负责合并它发现的任何重复代码。我让另一个智能体负责改进编译器本身的性能,第三个智能体负责生成高效的编译代码。我让另一个智能体从 Rust 开发者的角度批判项目的设计,并对项目进行结构性更改以提高整体代码质量,还有一个智能体负责编写文档。

压力测试智能体团队的极限

这个项目旨在作为一个能力基准测试。我有兴趣对 LLM 今天勉强能够实现的极限进行压力测试,以帮助我们为未来模型将能可靠实现的目标做好准备。

我一直在使用 C 编译器项目作为整个 Claude 4 模型系列的基准测试。和之前的项目一样,我首先起草了我想要的目标:一个从头开始、没有依赖、与 GCC 兼容、能够编译 Linux 内核、并设计用于支持多个后端的优化编译器。虽然我指定了设计的某些方面(例如,它应该有一个 SSA 中间表示以支持多次优化过程),但我没有详细说明如何做到这些。

早期的 Opus 4 模型几乎无法产生一个功能正常的编译器。Opus 4.5 是第一个突破门槛,能够生成一个能通过大型测试套件的功能编译器的模型,但它仍然无法编译任何真正的大型项目。我对 Opus 4.6 的目标是再次测试极限。

评估

在近两周的时间里,经过近 2000 次 Claude Code 会话,Opus 4.6 消耗了 20 亿输入令牌,生成了 1.4 亿输出令牌,总成本略低于 20,000 美元。即使与最昂贵的 Claude Max 计划相比,这也是一个极其昂贵的项目。但这个总成本仍远低于我自己(更不用说整个团队)来生产这个东西的成本。

这是一个"干净室"实现(Claude 在开发期间的任何时刻都没有访问互联网);它只依赖 Rust 标准库。这个包含 10 万行代码的编译器可以在 x86、ARM 和 RISC-V 架构上构建可启动的 Linux 6.9。它还可以编译 QEMU、FFmpeg、SQlite、Postgres、Redis,并且在包括 GCC 酷刑测试套件在内的大多数编译器测试套件中达到了 99% 的通过率。它还通过了开发者的终极试金石测试:它能够编译并运行《毁灭战士》。

然而,这个编译器并非没有局限性。这些包括:

  1. 它缺少启动 Linux 脱离实模式所必需的 16 位 x86 编译器。对于这部分,它调用 GCC(x86_32 和 x86_64 编译器是它自己的)。
  2. 它没有自己的汇编器和链接器;这是 Claude 开始自动化的最后一部分,目前仍然有些 bug。演示视频是使用 GCC 的汇编器和链接器生成的。
  3. 编译器成功构建了许多项目,但并非全部。它还不能完全替代真正的编译器。
  4. 生成的代码效率不高。即使启用了所有优化,它输出的代码也比禁用所有优化的 GCC 效率低。
  5. Rust 代码质量尚可,但远不及专业 Rust 程序员可能产出的质量。

最终产出的编译器几乎已经达到了 Opus 能力的极限。我(努力地!)尝试修复上述几个限制,但并未完全成功。新功能和错误修复经常破坏现有功能。

作为一个特别具有挑战性的例子,Opus 无法实现启动 16 位实模式所需的 16 位 x86 代码生成器。虽然编译器可以通过 66/67 操作码前缀输出正确的 16 位 x86 代码,但生成的编译输出超过 60kb,远远超过了 Linux 强制执行的 32k 代码限制。因此,Claude 在这里直接"作弊",为此阶段调用 GCC(这只针对 x86。对于 ARM 或 RISC-V,Claude 的编译器可以完全自行编译。)

该编译器的源代码是公开的。你可以下载它,通读代码,并在你最喜欢的 C 项目上尝试。我始终认为,理解语言模型能力的最佳方式是将其推向极限,然后研究它们在哪里开始出现问题。在接下来的几天里,如果你想知道 Claude 如何继续尝试解决这些限制,我会继续让 Claude 推送新的更改。

展望未来

每一代语言模型都开辟了与之协作的新方式。早期模型在 IDE 中用于代码自动补足很有用。不久之后,模型能够根据函数文档字符串补全函数体。Claude Code 的发布将智能体带入主流,使开发人员能够与 Claude 进行结对编程。但这些产品都基于一个假设:用户定义一个任务,LLM 运行几秒或几分钟后返回答案,然后用户提供后续操作。

智能体团队展示了自主实现整个复杂项目的可能性。这使我们作为这些工具的用户,能够对我们的目标抱有更大的雄心。

我们仍处于早期阶段,完全自主的开发伴随着真实的风险。当人类在开发过程中与 Claude 坐在一起时,他们可以确保一致的质量并实时捕捉错误。对于自主系统,很容易看到测试通过就认为工作已完成,但情况很少如此。我曾经从事渗透测试工作,利用大公司产品中的漏洞,而程序员部署他们从未亲自验证过的软件,这种想法确实令人担忧。

所以,虽然这个实验让我兴奋,但也让我感到不安。构建这个编译器是我最近最有趣的经历之一,但我没想到在 2026 年这么早就能实现接近这样的成果。语言模型以及我们用来与之交互的框架都在快速进步,这为编写大量新代码打开了大门。我预计积极应用会超过负面影响,但我们正在进入一个新世界,需要新的策略来安全地航行。

致谢

特别感谢 Josef Bacik、Edwin Chen、Bernardo Meurer Costa、Jake Eaton、Dan Kelley、Felix Klock、Jannet Park、Steve Weis,以及 Anthropic 的其他许多人的帮助和贡献。

相关推荐
ZHOUPUYU7 小时前
PHP 8.3网关优化:我用JIT将QPS提升300%的真实踩坑录
开发语言·php
九.九11 小时前
ops-transformer:AI 处理器上的高性能 Transformer 算子库
人工智能·深度学习·transformer
春日见11 小时前
拉取与合并:如何让个人分支既包含你昨天的修改,也包含 develop 最新更新
大数据·人工智能·深度学习·elasticsearch·搜索引擎
恋猫de小郭11 小时前
AI 在提高你工作效率的同时,也一直在增加你的疲惫和焦虑
前端·人工智能·ai编程
寻寻觅觅☆11 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
YJlio11 小时前
1.7 通过 Sysinternals Live 在线运行工具:不下载也能用的“云端工具箱”
c语言·网络·python·数码相机·ios·django·iphone
deephub11 小时前
Agent Lightning:微软开源的框架无关 Agent 训练方案,LangChain/AutoGen 都能用
人工智能·microsoft·langchain·大语言模型·agent·强化学习
l1t11 小时前
在wsl的python 3.14.3容器中使用databend包
开发语言·数据库·python·databend
大模型RAG和Agent技术实践12 小时前
从零构建本地AI合同审查系统:架构设计与流式交互实战(完整源代码)
人工智能·交互·智能合同审核
老邋遢12 小时前
第三章-AI知识扫盲看这一篇就够了
人工智能