00:00:00Anthropic 刚刚干了一件大事,他们放出了 16 个 Claude 智能体来构建
00:00:05一个 C 语言编译器,在全天候运行了两周后,它们竟然真的造出了一个可以编译
00:00:11Linux 内核甚至运行《毁灭战士》的编译器,这太令人印象深刻了,在旧版的
00:00:16Opus 4 上绝对是不可能实现的。但有人说这项成就只是标题党,
00:00:22甚至是半真半假的谎言,因为 Anthropic 为了得到这个结果使用了些存疑的手段。
00:00:28那么,Anthropic 到底有没有作弊?点个订阅,让我们一探究竟。
00:00:31我们将把视频分为三个部分。首先,看看实验是如何设置的,
00:00:37然后分析核心发现,我觉得每位开发者都能从中受益匪浅,
00:00:42最后,我们要讨论结果是否有效,因为对于 Anthropic 构建编译器的方式,我有不少看法。
00:00:47好了,这次实验是由 Nicholas Carlini 执行的,在我看来他是个极其聪明的人。
00:00:52我是说,来看看他是如何搭建环境的。实际的项目存储在一个名为 Upstream 的目录中,
00:00:58并挂载到了 16 个不同的 Docker 容器上。我知道这里只画了四个,但请想象成 16 个。
00:01:03每个 Docker 容器都运行着一个基于 Opus 4.6 的 Claude Code 版本,
00:01:08它们会将 Upstream 仓库克隆到本地 Workspace,在 Workspace 里完成所有修改,
00:01:15然后再推送到 Upstream。这招非常高明,因为每个智能体都能独立工作,
00:01:21互不干扰。如果出现了合并冲突,Claude
00:01:27也足够聪明,能够自行解决并重新推送到 Upstream。每个智能体会从中挑选任务。
00:01:32我不确定这些任务是由人类生成的,还是由智能体根据测试结果自行生成的,
00:01:38但任务清单确实存在且都有名称,每个智能体会领取一个新任务,
00:01:44并在每次领任务时创建一个新会话。为了让这些智能体能长时间运行,
00:01:50实验使用了一个 Ralph 循环,智能体完成任务后推送到 Upstream,
00:01:56然后开启一个全新的会话并领取新任务,如此循环往复。
00:02:02如果你看过我们关于 Ralph 的视频,就会知道让智能体长期运行的关键在于定义清晰的任务。
00:02:08但如果有 16 个智能体同时运行,该如何防止它们领取完全相同的任务呢?答案是“任务锁定”。
00:02:13作者虽然没细说具体实现,但逻辑是这样的:存在一个任务列表,智能体领取任务后,
00:02:19会创建一个与任务名匹配的文本文件,并通过提交该文件来锁定任务,
00:02:24确保只有自己能处理它,然后推送到 Upstream 目录。如果另一个智能体领了同样的任务
00:02:30并尝试创建相同的文件,Git 就会拒绝它的推送请求,提示该文件已存在,
00:02:36于是它就必须去处理别的任务。这就是 Carlini 压力测试的核心机制,
00:02:42用来测试 Opus 4.6 驱动的长期运行智能体的能力,其结果确实令人惊叹。
00:02:48但在实验过程中,他发现了一些非常有价值的事情,我觉得每个开发者都可以学习。
00:02:53首先是构建一个测试框架或脚本来运行各种测试,因为当 Nick 运行实验时——
00:03:00是的,我们现在已经熟到直接叫他 Nick 了——他发现 Claude 在开发新功能时总会搞坏旧功能。
00:03:07于是他从 SQLite、libjpg 和 Redis 等知名开源仓库中提取了高质量测试,构建了测试框架。
00:03:12为了防止上下文污染,他确保测试框架只输出对智能体有用的日志,
00:03:17基本上就是错误日志,并把其他类型的日志存入另一个文件,供 Claude 必要时查阅。
00:03:23然而,面对成千上万个测试,智能体如果运行整个测试套件要花好几个小时,
00:03:29本可以用这些时间做更多事。这时候 Nick 用了一个非常聪明的办法。
00:03:35他在测试框架中加入了一个“快速标记”,让智能体根据设定只运行 1% 或 10% 的测试。
00:03:41如果每个智能体运行 10%,那总计就是 160% 的测试覆盖率,不仅够用甚至还有富余。
00:03:47具体的实现方式是:每个智能体运行的特定测试是随机挑选的,但种子数是相同的,
00:03:52从而保证了确定性。这样每个智能体都会处理不同的随机测试组,
00:03:58最终过完整个测试套件的速度,比单个智能体跑完全程要快得多。
00:04:05下一点同样高明,但由于涉及使用现有技术,因此略带争议。
00:04:13到目前为止,每个智能体都在运行现有开源项目的单元测试,
00:04:19按 1% 或 10% 分块运行的效果很好。但到了编译 Linux 内核时,
00:04:25由于这些源文件不是独立的单元测试,事情变得复杂了,因为每个智能体都会尝试编译整体,
00:04:31遇到同样的错误,然后尝试修复并互相覆盖对方的成果。为了解决这个问题,
00:04:36Nick 再次让每个智能体只负责编译一小部分,然后由 GCC(GNU 编译器)
00:04:41来完成剩下的部分。Nick 把 GCC 称为“先知”,因为 Linux 内核用它编译绝对没问题。
00:04:46这样如果智能体用自己的编译器编译一个部分,而其余部分交给 GCC,
00:04:53一旦出错,那肯定就是智能体编译器的问题而非 GCC。智能体只需针对该点修复,
00:04:58而不会误改其他智能体造成的 Bug。这之所以有争议,是因为它动用了现有的编译器,
00:05:04而 Claude 本该是从零开始构建一切。我们会在视频末尾详细讨论这一点。
00:05:09接着看下一点:赋予你的智能体记忆。既然新任务是由全新的 Claude 会话处理的,
00:05:15它们对之前的操作几乎一无所知,Nick 发现更新 Readme 文件非常有用,
00:05:22并通过不同的进度文件记录交接指令和项目进度,让新会话
00:05:27有一个良好的起点,避免引入已经修复过的 Bug。
00:05:34最后一点比较显而易见:为智能体分配不同的角色。并行开发最妙的地方在于,
00:05:40可以同时对同一段代码进行多项操作。当不需要编写新代码时,
00:05:46Nick 会给智能体指派独特的角色,比如一个负责检查重复代码,
00:05:51另一个负责寻找极致性能优化的方案,他甚至让一个智能体从 Rust 开发者的角度
00:05:57来审视设计。我只希望那个智能体没向其他智能体显摆自己是写 Rust 的。
00:06:03虽然项目很成功,但真正的核心问题是:Anthropic 是否作弊了?
00:06:09嗯,算是吧。任务目标是从零构建一个 C 编译器,智能体没有联网,
00:06:13所以代码都是它自己写的。真的是这样吗?因为它确实有权限访问开源项目的测试套件,
00:06:18并且可以访问编译好的 GCC。所以从技术上讲,它可以反复试探 GCC 编译器,
00:06:23通过输入输出进行逆向,并以此指导其用 Rust 编写的编译器的设计。
00:06:29但平心而论,如果让我从零开始写个 C 编译器,我也会这么干。
00:06:35我会研究现有编译器如何实现,并参考它们来决定自己的开发方向。
00:06:40当然,如果是在为一种全新的语言构建编译器,那难度会大得多,
00:06:45这或许是测试 Claude 真正“从零”构建编译器能力的绝佳方法。
00:06:51也许 Nick 以后可以试试,但我们先来聊聊实验的自主性,因为这也是测试重点。
00:06:57公平地说,代码确实是 Claude 写的,但背后离不开人类的强力引导。
00:07:03是人类决定了运行哪些测试套件,人类开启了循环并决定使用 Ralph,
00:07:10也是人类构建了测试框架并分配了具体角色。所以,虽然这远非简单的指令,
00:07:16也并非把 Claude 丢在那儿不管就能跑出结果。我不会说这些代码是由 100% 自主的智能体
00:07:24完成的,因为如果没有人类参与,这个编译器到底能做成什么样还很难说。
00:07:31而且,即使在人类精心设计的系统下,Claude 的 C 编译器仍有一些核心局限。
00:07:36比如,它使用了 GCC 的汇编器和链接器,因为它自己造的那个 Bug 太多了。
00:07:41它还需要 GCC 的 16 位 x86 编译器来启动 Linux。最重要的是,
00:07:47代码效率不高。Claude 编译器最优化版本的性能,甚至不如 GCC 最差优化版本的性能。
00:07:53所以看来,开发者们短期内还不会失业,至少目前是这样。
00:07:57experiment since that was also tested. And to be fair, yes, Claude did write all of the code, but
00:08:04it had some heavy steering from a human. A human decided on what test suite to run. A human started
00:08:11the loop and decided to use routes. A human was the one that built the test harness and gave agents
00:08:16specific roles. So while this is far from someone telling Claude to build a compiler and leaving it
00:08:22to run forever and ever, I wouldn't say the code was written by an agent that was a hundred percent
00:08:28autonomous because how good would the compiler have been if a human wasn't involved in the first place?
00:08:33And even with all the systems in place designed by a human, the Claude C compiler did have some
00:08:39key limitations. For example, it used the assembler and linker from GCC because the one it created was
00:08:46too buggy. It also needed GCC's 16-bit x86 compiler in order to boot up Linux. And to top that all off,
00:08:54the code wasn't very efficient. The most optimized version of the Claude's compiler was less
00:09:00performant than the least optimized version of the GCC compiler. So it looks like developers
00:09:05aren't going anywhere anytime soon, or at least for now.