Claude 不是编译器:LLM 如何跨层工作并超越传统工具
本文探讨了 LLM(如 Claude)与编译器的本质区别,指出 LLM 能跨软件构建的各个层级工作,从战略到代码,做出决策,而编译器仅处理底层转换。通过构建分布式 DNS 服务器的实例,展示了 LLM 在复杂工程中的实际应用和价值。
2025 年初,我写了《Claude 是编译器吗?》当时我的回答是:我不知道。现在我相当确定答案是“不,这是一个范畴错误,它比编译器更好。”但这需要一些解释。计算机程序以极其复杂和挑剔著称。程序在极端精确的水平上运行。
没有“挥手”这样的 CPU 指令。与此同时,高层目标却严重缺乏具体说明。在一个高度风格化的世界观中,软件是分层构建的,每一层都增加规范并隐藏“不必要”的细节。愿景变成战略,产品计划变成编码计划,代码变成二进制。
每个步骤都由不同的角色处理:高管、副总裁、产品经理、架构师、工程师、编译器。关键是,每一步都涉及做出大量决策。这就是增加规范水平的意义。(这也是我招聘工程师的两个关键指标之一是判断力的原因。另一个是礼貌。
)最底层,从源代码到二进制,是编译器的工作。编译器会做出大量决策!内联、寄存器分配、是否发出警告或直接拒绝程序。这些决策很重要:它们影响性能、系统稳定性、可预测性和故障模式。编译器工程师的工作是安排编译器做出一致的好决策。
一个好的、值得信赖的编译器可以让软件工程师不必做出这些决策。
大多数工程师对编译器的工作原理知之甚少;他们不需要了解也能高效工作。2025 年,我们使用 LLM 生成小块代码。在这种心智模型中,编码智能体可能作为软件工程师和传统编译器之间的新层插入。它将自然语言“编译”为代码,做出决策,让工程师不必亲自处理。
它的价值与其可靠性以及它能做出的决策规模成正比。问题是,这种高度风格化的世界观是错误的。抽象会泄露,层之间会摩擦。即使它们不泄露,我们也会故意戳破它们。跨层工作非常有价值;机械共情很重要。帝国大厦在不到一年内、预算内建成(!
)的部分原因就是系统地跨层工作。例如,在决定外部铬镍钢覆层时:没有充分协商,建筑师、建筑商和分包商都觉得自己没有能力处理这个复杂的建筑技术问题。
因此,经过充分的初步讨论后,召开了一次包容性会议,出席者包括业主、建筑师和建筑商、碾压材料的分包商、制造和安装材料的金属工人,以及在各个准备阶段测试所有板材的检查员。这听起来非常显而易见。
然而,我们在实践中却系统地失败了。我只能想象金属工人的喜悦,他们有机会引导设计走向一个不那么缓慢和痛苦的方向。我们失败的部分原因是不知道什么值得询问。最优秀的高管对所在行业有深入了解是有原因的。
我还怀疑其中一些是轻视(“一个流水线金属工人能告诉我什么?”)。但很大一部分也是沟通和组织开销。层的存在是有原因的——信息隐藏使组织能够扩展。Claude 比编译器更好,因为它可以在堆栈上垂直工作。
LLM 现在可以谈论战略、产品、架构、代码和机器代码。它还不能(目前?)像经验丰富、专注的人类那样完成大多数单个任务,但它可以完成所有任务,而无需安排会议或请求许可。这里有一个具体例子。exe.dev 虚拟机有漂亮的域名:vm-name.exe.xyz。
当我们启动新虚拟机时,我们会添加一两个 CNAME 条目。很简单,对吧?但我们的虚拟机启动很快,快到即使我们在创建虚拟机之前就创建了 DNS 条目,用户仍然需要等待 DNS 传播,这有时需要几分钟而不是几秒。
我们做了显而易见的事:编写了自己的 DNS 服务器,这样 DNS 总是立即匹配真实来源。生活很美好。但延迟很重要,所以我们添加了区域。
就这样,DNS 再次成为瓶颈,因为所有 DNS 都从俄勒冈州提供服务。此外,部署会导致短暂的 DNS 中断。为了解决这个问题,我们需要的只是一个地理分布但完全一致的 DNS 服务器。我们做了明智工程师面对难题时会做的事:取巧。
我们针对特定需求 vibe-engineered 了一个分布式 DNS 服务器。目标很明确:减少远离俄勒冈州的用户的延迟,并提高正常运行时间的弹性。但其余部分并不明确。
我们必须弄清楚一切,从我们想要的确切行为(特别是在各种故障条件下),到它如何适应我们的整体公司计划,再到最能实现这些目标的架构,一直到精细的实现细节。我们亲自制定了最高级别的战略和架构决策。
我们将构建一个相当通用的 DNS 服务器,并在其上添加特定的行为调整,使用中心辐射模型,使用仅追加复制策略,并在边缘实现持久化。剩下的就是实际构建它。
我让 LLM 研究分布式 DNS 系统的标准设计,教我 DNS 的内部原理和怪癖,指出历史上的安全缺陷,探索替代实现策略(AXFR/IXFR?不,谢谢),研究开源产品,推演故障模式,并规划测试策略。
一旦我有了一个看起来很有希望的设计的初步草图,我就促使多个并发智能体循环构建整个系统,包括测试和对抗性代码审查。它们提出了一系列问题——在各个细节层面,从主要的结构方法到行级代码问题。
当我回答它们(或撤销导致后悔的答案)时,我慢慢地将所学转化为非常简洁的书面指导,将事实证明重要的决策编入文档。然后我要求新智能体比较已完成的实现,并寻找有趣的差异。令人震惊的是,智能体从未询问过多少重要决策,而是直接做出——并且做出了不同的决策。
这里有一个例子。复制使用相当明显的方法:通过请求自最后一个已知条目以来的所有内容来追赶,然后长轮询新条目。有一个丑陋的转折:数据库回滚。很少见,但它们确实会发生,并且会破坏“仅追加”的约定。智能体注意到了这一点,并以截然不同的方式解决了它。
我最终决定的设计是为每一行赋予一个“时间线”字段,即“你生活在哪个时间线?”这些是随机生成的,并且对于“自第 N 行以来的条目”的每个同步请求,都包含边缘服务器对于第 N 行的时间线值。如果时间线不匹配,我们就知道历史已被篡改,并回退到完全干净的重新同步。
不同智能体构建的系统之间也存在明显的风格差异。Claude 和 Codex 都认为 Claude 创建了更优雅的系统,但 Codex 更彻底。我列出了主要的分歧,进行了实验,然后添加了更多的书面指导。
然后我重复了整个差异规范分析过程,两次。我知道我的格言。计划扔掉一个;无论如何,你都会扔掉的。—— Fred Brooks如果你计划扔掉一个,你会扔掉两个。
—— Craig Zerouni当我准备构建一个最终版本时,我已经积累了一份“疤痕组织”文档,根据经验,它足以指导智能体完成每一层的大多数重要决策,从高层目标到架构,再到偶尔的低层细节。