2026 年 11 月 11 日 • 1671 词

2004 年,我刚入职 Amazon 不到一个月,就得到了一个为团队挑选实习生的机会。我比同事们多一个优势:我早就听说过一位才华横溢的年轻人,正在阿姆斯特丹自由大学攻读博士学位(我恰好也是在那里拿到博士学位的 :-))。我立刻选中了 Swaminathan Sivasubramanian,也就是大家现在熟知的 Swami。这大概是我担任 Amazon CTO 的 22 年里做过的最好的决定之一。

2004 年经历了一个灾难性的圣诞节之后——当时商用关系型数据库无法满足 Amazon 的规模需求——我让 Swami 深入研究 Amazon 实际是如何使用关系型数据库的。结果发现,70% 的数据库操作根本不是关系型的,而是键值型的。这一洞察促成了Dynamo的诞生,Swami 参与了它的架构设计。他的实习结束后,我立刻全职聘用了他,甚至在他完成博士学业之前。

引入又一位有主见的学者,促成了他与 Amazon 务实的工程师们之间许多精彩的讨论——这些工程师通过真正大规模地构建系统,已经成为规模方面的专家。最终一致性与强一致性、CAP 与 Paxos,等等。随着时间推移,Swami 成为 AWS 数据战略的主要架构师之一。而正如我们近年来所见,他也是 Amazon 内部 AI 创新背后的思想推动者之一。

我很荣幸他愿意写一篇客座文章,讲述 AWS 许多服务背后根本性的分布式系统工作,以及当智能体编写代码时,工程师的工作会如何变化。今天发布的 AWS Emulator,为智能体提供了这类工作所依赖的测试环境。Swami 的故事是隐形工程的又一个绝佳范例。

现在,去构建吧。

-W


AWS Emulator,以及当智能体编写代码时工程师的工作

今天我们发布 AWS Emulator,它为编码智能体提供了一个本地 AWS 副本用于测试,并且它与我职业生涯早期的一个项目相关联。在很多方面,这次模拟器的发布让我想起我们为提升所构建的分布式系统质量而在可靠软件工程上投入的努力。为此,我们想分享一个故事:

大约二十年前,Werner 让我和 Amazon 最早的工程师之一 Al Vermeulen 合作,开发一个我们称之为“Alf”的分布式锁服务。Alf 构建在 Paxos 之上——这是一种基于 Leslie Lamport 工作的协议,能让一组服务器就某个值达成一致——其中的复制引擎让数据副本在各服务器之间保持一致。时至今日,Alf 仍然是支撑我们许多复杂分布式系统(如 S3、DynamoDB 等众多系统)的服务(尽管它已经经历了相当大的演进,在其之上做了各种改动——这个留到另一篇博客再讲!)。

分布式系统很难测试

Paxos 是分布式系统共识协议中的黄金标准,在学术界已被充分理解。然而,在 Amazon 和 AWS 当时所处的增长规模下构建它并不容易。我们不仅要处理跨服务器和数据中心的复制,还要应对数以万计的客户端同时请求锁、在网络分区期间续租,同时还要满足核心要求:始终保持正确!在当时,测试分布式系统的最佳思路是大规模系统测试和混沌测试。两者都有效,但成本高昂,而且无法按需复现许多类型的条件。这对 Alf 来说很重要,因为它被设计为真相存储,为每个客户端提供强一致的真相视图,并且必须在服务器故障和丢包的情况下持续工作。已有若干行业论文指出,基于 Paxos 的锁服务很难做对,而测试它们的难度正是原因之一。

我们通过尽可能高保真地模拟 Alf 的环境来解决这个问题。我们在 JVM 中运行服务器,并模拟网络及其依赖的其他基础设施,因此整个系统都运行在一个由我们控制的程序中。我们可以随时丢包并注入其他故障,还构建了工具来探查模拟中的缺陷和可扩展性问题。并发缺陷只有在事件以特定顺序发生时才会出现,而在模拟中,我们可以有意构造许多这样的顺序,并检查 Alf 如何处理每一种情况。我们还通过 TLA+ 等理论技术进行形式化推理,这也发现了许多问题。通过这种测试方式,我们在 Alf 运行于真实服务器之前就消除了它的大部分并发缺陷。随后在真实环境中测试又暴露出了不同的问题,因为现实世界会暴露出模拟无法覆盖的情况。

超越手工构建的测试环境

模拟和形式化推理都提升了我们应用它们的分布式系统的软件质量。模拟之所以有效,是因为一个小团队可以手工构建某个系统环境的副本,而当时 AWS 只有少数几个服务。但如今 AWS 拥有超过 200 个服务,一个调用 AWS 的应用需要为其使用的每个服务准备测试环境。手工构建所有这些环境将耗费数年的工程时间,而智能体现在编写代码的速度远超任何团队在生产环境中检查它的速度。因此,我们想知道智能体能否自行构建并测试这些环境。

这个想法来自 Matt Goldberg,他是 AWS 开发者工具团队的高级首席工程师。他的假设是:给定一份关于某个服务应如何行为的书面描述,以及用于对照检查的真实服务,智能体就能自行构建该服务的一个可用版本。对 AWS 而言,书面描述就是以 Smithy(AWS 用于描述服务操作及其输入、输出和错误的格式)编写的一组公开 API 模型。用于对照检查的真实服务就是 AWS 云本身,即客户所使用的同一套系统。

智能体依据保真度测试来工作,这些测试是根据公开 API 模型设计的端到端客户场景。例如,某个测试可能会检查在 Amazon Simple Queue Service 中,收到的消息在其他读取者看来是否一直保持隐藏,直到其可见性超时结束。智能体会修正每个测试,直到它在真实 AWS 上通过,因此该测试记录了 AWS 的行为。随后智能体构建模拟器,直到它通过同一个测试,而仍然失败的测试则指向模拟器的缺口。Matt 从 SQS 单独开始,当他给 Kiro 一个描述此方法的提示时,它在大约 15 分钟内返回了一个可用的 SQS 模拟器初版。Matt Goldberg 的发布文章讲述了那个原型如何发展为 AWS Emulator。AWS Emulator 的所有代码都由智能体编写和测试,它基于 400 多个 API 模型构建,覆盖 200 多项 AWS 服务。它可以在你自己的机器上免费离线运行。智能体团队会针对真实 AWS 测试它,并修复发现的缺口。每项变更都要经过合并门禁,即一套深度自动化检查,每项变更在进入代码库前都必须通过,其中包括多个安全智能体进行对抗性审查。

编码循环中的基础设施

编码智能体在一个循环中工作:它编写代码、运行代码,并读取结果,然后再决定下一步要改什么。在分布式系统中,这个循环运行在基础设施之内,因此它调用的服务必须表现得像真实服务一样。当它们确实如此时,智能体就能在编写过程中自行检查工作,并更频繁地在首次尝试时就产出正确的代码,从而提升软件质量。AWS Emulator 将这套基础设施放进了你自己机器上的循环中。

当智能体编写代码时工程师的工作

当智能体编写代码并检查自己的工作成果时,工程师的职责就是给它们留出自主工作的空间,并构建规范、测试和合并门禁,用来判定这些工作何时是正确的。这是我用惨痛教训换来的一课:当时我用 Kiro 重建我和 Al 为 Alf 构建的复制引擎,第一次花了大约四个月。我监督了智能体四个晚上,才意识到它根本没有办法检查自己的结果。一旦它有了规范和测试环境,重建只花了大约两个小时。

构建 AWS Emulator 的智能体从一开始就同时拥有这两者:公开的 API 模型和真实的 AWS。一位工程师构建了运行它们的脚手架。一个内部版本在一个周末内成形,并在一个月内开始被采用。要把它变成稳健的解决方案,还需要多得多的努力。

AI 时代的软件质量取决于工程师围绕智能体设计的护栏。在 AWS Emulator 中,这些护栏包括:对照真实 AWS 验证的保真度测试;一个合并门禁,其中多个安全智能体各自从不同的攻击角度审查变更,并配有一名通用代码审查员;以及阻止智能体触碰它们不应触碰的代码的确定性检查。我们期望智能体构建并检查大部分软件,由工程师决定构建什么以及工作何时是正确的。在了解工程师如何带领智能体团队构建可靠、高质量的软件方面,我们还处于早期阶段,而 AWS Emulator 的诞生方式就是这种做法在实践中如何运作的一个好例子。我们期望继续增加护栏,并改进智能体构建它的方式。

发布时你需要了解的内容

模拟器代码以 CC0 发布,这是 Creative Commons 对公有领域的奉献。

我们将在 re:Invent 上分享更多关于这项工作的内容。完整的提交历史和智能体提交的每一个 issue 都公开在GitHub 仓库中,其“things-that-do-not-work”文件夹收录了描述智能体发现的、目前尚与真实 AWS 不匹配的行为的 issue。