Claude 不是编译器--它比编译器更好

在2025年初，我写了《Claude 是编译器吗？》：https://commaok.xyz/ai/is-claude-a-compiler/? 当时，我的答案是：我不知道。

我现在很确定答案是“不，那是类别错误，它比编译器更强大。”但这需要一些说明。

计算机程序以复杂和易出错而著称。程序的操作需要极高的精确度。没有“挥手”的CPU指令。与此同时，高级目标往往严重缺乏规范。

在一种高度程式化的世界观中，软件是分层构建的，每一层都增加规范并隐藏“非必要”的细节。愿景变成战略，产品计划变成编码计划，代码变成二进制。每个步骤由不同的角色处理：高管、副总裁、产品经理、架构师、工程师、编译器。

关键是，每一步都涉及大量决策。这就是提高规范程度的意义所在。（这也是我评估工程师的两个关键指标之一是判断力，另一个是礼让。）

最底层，从源代码到二进制，是编译器的工作。编译器做很多决策！如内联、寄存器分配、是否发出警告或直接拒绝程序。这些决策很重要：它们驱动性能、系统稳定性、可预测性以及故障模式。编译器工程师的工作是确保编译器持续做出良好决策。

一个好的、值得信赖的编译器让软件工程师无需自己做这些决策。大多数工程师对编译器的工作原理了解不多；他们不需要了解也能高效工作。

在2025年，我们生活在一个使用大语言模型生成小块代码的世界。在这个思维模型中，编码代理可能作为软件工程师与传统编译器之间的新一层存在。它将自然语言“编译”成代码，做出决策，让工程师无需操心。它的价值与其可靠性及能够做出决策的规模成正比。

问题是，这种高度程式化的世界观是错误的。抽象会泄漏，层与层之间会摩擦：https://www.dbreunig.com/2026/07/03/ai-ecosytem-pace-layers.html。即使没有，我们也会挑出它们的漏洞。

跨层工作极具价值；对机械特性的理解很重要。

帝国大厦建设的一部分方式：https://www.construction-physics.com/p/building-fast-and-slow-the-empire 在不到一年的时间内并且低于预算（!!）完成，是通过系统地跨层工作实现的。例如，在决定外部铬镍钢外壳时：

建筑师、施工方和分包商都觉得自己在没有充分咨询的情况下无法胜任处理这个复杂的施工技术问题。因此，在充分的初步讨论之后，召开了一次全体会议，出席会议的有业主代表、建筑师和施工方、负责滚制材料的分包商、负责制造和安装的金属工人，以及在各个准备阶段对所有钢板进行检测的检查员。

当你大声说出来时，这听起来真是显而易见。

然而，我们在实践中却系统性地未能做到这一点。我只能想象那些金属工人的高兴，他们有机会将设计引导向不慢且不痛苦的工作方式。

我们失败的部分原因是对值得询问的内容一无所知。最顶尖的高管在自己的行业中有深厚知识，这绝非偶然：https://daringfireball.net/linked/2022/10/11/ceos-as-nerds。我也怀疑，部分原因是轻视（“一名普通金属工能告诉我什么？”）。但很大一部分原因还是沟通和组织开销。层级存在是有原因的——信息隐藏使组织可以扩展。

Claude 比编译器更优，因为它可以在堆栈上下垂直工作。大语言模型现在可以讨论策略、产品、架构、代码和机器码。它（还？）不能像有经验、专注的人工一样出色完成大多数具体任务，但它可以完成所有这些任务，而且无需安排会议或征求许可。

exe.dev：http://exe.dev 虚拟机有很好的域名：vm-name.exe.xyz：http://vm-name.exe.xyz。当我们启动新虚拟机时，会添加一条或三条 CNAME 记录。很简单，对吗？

但我们的虚拟机启动非常快，即使在创建虚拟机之前创建了 DNS 记录，用户仍然不得不等待 DNS 传播，有时传播需要几分钟，而不是几秒钟。

我们做了最显而易见的事情：我们写了自己的 DNS 服务器，这样 DNS 总是能立即与信源保持一致。生活因此变得美好。

但延迟很重要：https://blog.exe.dev/regions，所以我们增加了区域。就这样，DNS 又成为了瓶颈，因为所有 DNS 都由俄勒冈提供服务。此外，部署会导致小规模的 DNS 中断。为了解决这个问题，我们现在需要的是一个地理分布但完全一致的 DNS 服务器。

面对困难问题时，我们采取了一个理智工程师会做的选择：作弊。我们根据自身特定需求精心设计了一个分布式 DNS 服务器。

目标很明确：降低远离俄勒冈的用户的延迟，并提高正常运行时间的韧性。但其他方面并不明确。我们必须弄清楚从我们想要的具体行为（尤其是在各种故障情况下）、它如何融入公司整体计划，到能够最好实现这些目标的架构，一直到具体实现的细节。

我们当面讨论了最高层的战略和架构决策。我们准备制作一个相当通用的 DNS 服务器，并在其上叠加我们特定的行为调整，采用辐射型模型，使用只追加复制策略，并在边缘进行持久化。

剩下的就是实际构建它。

我让大型语言模型研究分布式 DNS 系统的标准设计，讲解 DNS 的内部工作和怪癖，指出历史上的安全漏洞，探索替代实现策略（AXFR/IXFR？不，谢谢），研究开源方案，模拟故障模式，并制定测试策略。

一旦我有了一个看起来有希望的初步设计草图，我就让多个并行的代理循环去构建整个系统，包括测试和对抗性代码审查。他们提出了许多问题——从主要结构方法到代码行级的细节层面。当我回答这些问题（或撤回那些让我后悔的答案）时，我慢慢将所学转化为非常简洁的书面指导，将被证明重要的决策进行编码。

然后我让新的代理比较已完成的实现，并寻找有趣的偏差。令人震惊的是，有多少重要的决策是代理从未询问过的，而是直接做出——而且做法各不相同。

这里有一个例子。复制使用了相当明显的方法：通过请求自上次已知条目以来的所有内容来赶上进度，然后长轮询以获取新条目。有一个棘手的问题：数据库回滚。虽然罕见，但确实会发生，而且会破坏“只追加”合同。

代理注意到了这一点，并以截然不同的方式解决了它。我最终采用的设计是给每一行一个“时间线”字段，意思是“你生活在哪条时间线上？”这些时间线是随机生成的，每个“自第 N 行以来的条目”同步请求都包括边缘服务器的第 N 行时间线值。如果时间线不匹配，我们就知道历史已被更改，并回退到完全干净的重新同步。

不同代理构建的系统之间也存在明显的风格差异。Claude 和 Codex 都认为 Claude 创建的系统更优雅，但 Codex 更彻底。

我梳理了主要发现的分歧列表，进行了实验，然后添加了更多书面指导。

然后我重复了整个差异规范分析：https://commaok.xyz/ai/differential-spec/ 过程，两次。我了解我的格言：https://en.wikipedia.org/wiki/Second_system_effect。

计划放弃一个，你无论如何都会放弃。

如果你计划放弃一个，你将放弃两个。

等我准备构建一个正式系统时，我已经积累了一份疤痕文档，从经验上足以指导代理完成大多数重要决策，在每一层次上，从高层目标到架构，再到偶尔的低级细节，比如承载并发缓存的数据类型的确切形状。

最终系统包括单元测试、端到端测试、用于降低生产风险的影子模式，以及简明的为代理编写的文档套件。

这一切总共花了我大约一周的时间。我阅读了极少量的实际代码。

在那之后，我向团队展示了解决方案。我计划上线服务器，然后去度假。当同事们向我提问——“X 是怎么工作的？在 Y 条件下会发生什么？”——我发现自己能够自信地回答所有问题。（而我确实去度假了。一个月后的 DNS 事件数量：0。）

Claude 在这里不仅仅是一个编译器。我从未把任务交给一个代理，让它做一堆决策以付诸实践。那是氛围编码（vibe-coding）。

相反，Claude 是一个垂直整合的资源，一个多编译器。它跨堆栈工作的能力加速并增强了我在不同层次上做出一系列决策的能力，包括哪些决策重要的判断。（大多数单独的代码行达不到那个标准。）那是氛围工程（vibe-engineering）。

我想说，在所有重要方面，我理解这段代码。当然，如果我现在不得不手动编辑它，会有一个严重的学习曲线。但我不必那样做。更重要的是，我可以推理系统，与同事分享观点，并指导代理进行未来的工作。而且还有一个持久的产物，它概括了设计中重要到值得记录的核心意图要素，覆盖所有层，因而应该能够在修复 bug 和代码变动中存续。

这个时代的一个问题是：软件工程师需要理解他们所工作的系统的哪些内容？

精心选择的层次提供理解。基本物理定律看似无所不包，但在解释为什么在事故中坐公交比开车更好时，它们不如经典力学。

有些软件层正在消亡，因为它们提供便利，但没有额外洞察力。（抱歉，Tailwind。我曾爱过你。）但能够让我们以可理解的方式表达重要决策的软件层？那些会留下。

我们正在将更多注意力转向堆栈上层，但并没有完全放弃下层。代理并不是让我们放弃对系统更深层理解的免费通行证。Go 标准库的大部分是用 Go 写的，但少数关键例程是用汇编写的。在那里你不能依赖编译器。

软件工程师正被拉得很紧。这既令人振奋又令人筋疲力尽。不过，越来越明显的是，在不久的将来，‘氛围工程’只是……工程。