800 个 Agent 在无需人工逐一审核的情况下迁移代码库的循环模式解析

@cyrilXBT
英语3周前 · 2026年6月23日
117K
126
29
21
200

TL;DR

深入了解 Google 用于大规模代码库迁移的“暗工厂”架构。本文解析了为何单个 Agent 往往会失败,以及如何通过规划、执行和确定性验证的循环机制,实现安全且无需人工干预的迁移。

谷歌的 AI 与基础设施团队在一篇博客文章中悄然发布了一项引人注目的成果,而业内大多数人只是匆匆扫过:将生产级机器学习模型从 TensorFlow 迁移到 JAX,实现了六倍的速度提升,涉及数千行代码、数百个层,以及跨多个文件的深层依赖关系。桑达尔·皮查伊在 Google Cloud Next 大会上提到了这个数字。这个数字登上了头条。但底层的架构才是真正的故事,而这也是当前每一次可信的大规模 Agent 迁移背后的相同架构——无论这个集群是 8 个 Agent 还是 800 个。

这里最关键的一个细节是:他们首先尝试让一个单一的 AI Agent 来处理整个代码库。结果失败了。不是部分失败,而是完全失败。它丢失了上下文,凭空捏造了不存在的 API,并生成了无法编译的代码。解决方案并非使用更智能的模型,而是一种完全不同的架构,它有一个名字:“黑暗工厂”模式。在这种模式下,Agent 能够规划、实施、测试并交付代码,而整个过程完全无需人工审查,就像全自动工厂在黑暗中运行机器一样,因为已经没有人需要去开灯了。

本文是对该模式的完整解析。不是营销版本,而是数百个 Agent 如何在不逐个检查每个更改的情况下迁移真实代码库的实际机制,以及为什么让这一切安全可靠的不是对模型的信任,而是一种从一开始就设计为无需这种信任的架构。

为什么单一 Agent 在大规模下会失败

在介绍架构之前,先要准确理解为什么这种简单粗暴的方法会失败,因为工作模式中的每一个设计决策,都是为了修补这些失败中的某一个。

一个指向大型代码库的单一 Agent 首先会遇到上下文问题。即使拥有慷慨的上下文窗口,一个包含数百个相互依赖的文件、深层调用链以及跨模块继承假设的代码库,也超出了任何单一会话能够连贯处理的范围。Agent 在处理前几个文件时表现良好,但随着工作上下文被累积的、半相关的历史信息填满,其表现会迅速下降。

接着,它会遇到排序问题。代码迁移默认不是一项并行任务。文件 B 通常依赖于文件 A 已经完成迁移,因为函数签名变了、导入路径移动了、或者数据结构发生了变化。一个没有显式依赖关系图的 Agent,要么猜测顺序(这会产生损坏的中间状态),要么按照文件被列出的顺序进行处理(这本质上和猜测一样)。

然后,它会遇到验证问题,而这实际上是最关键的一个。一个 Agent 迁移代码,然后评估自己的迁移成果,这相当于在检查自己的作业,并且带着最初导致任何错误的相同盲点。如果 Agent 不理解某个特定 API 在新版本下的行为差异,那么它在审查自己的输出时也不会发现这个误解,因为两次检查中都存在相同的理解差距。

谷歌团队直接发现了这个问题。单一 Agent 的设置无法同时平衡迁移的结构性规则和逐行执行的细节。将这两个关注点拆分成独立的角色才是真正的解决方案,而这个方案也独立地出现在 OpenAI 发布的迁移指南、关于多 Agent 迁移循环的学术研究,以及每一个实际运行在大规模下的生产系统中。

架构:三个角色,而非一个通才

工作模式将任务拆分成具有真正不同职责的角色,而不仅仅是给同一个通才 Agent 设置不同的提示词。

规划器(Planner)使用确定性工具,而非 LLM 猜测,来安排工作顺序。 这个细节区分了一个真正能扩展的系统和一个在演示中令人印象深刻、但在生产中却崩溃的系统。谷歌的规划器不会让 LLM 通过推理来找出迁移顺序。它使用基于编译器的静态分析——这种确定性工具类别支撑企业软件数十年——来构建实际的依赖树,并定义一个从叶节点(没有其他文件依赖的文件)开始,向上到所有其他文件都依赖的文件的执行计划。

这一点很重要,因为依赖排序不是一个创造性的问题。它是一个有正确答案的机械性问题,而使用 LLM 来解决一个已有确定性解决方案的问题,只会引入一个新的错误源,而这个错误源本无需存在。这背后的规则是:任何有算法答案的问题,都使用算法。将语言模型保留给那些真正需要判断的任务部分,即实际的代码转换,而不是哪个文件先处理的排序问题。

迁移 Agent(Migration Agent)(在更大的系统中,是数百个并行运行、相互隔离、范围狭窄的相同角色实例)负责执行实际的代码转换。 每个实例获得一个范围明确的任务,理想情况下是一个文件或一个紧密绑定的模块、一个单独的检出副本,以及一份明确的迁移简报,精确描述需要更改什么以及为什么更改。它检查相关代码,进行编辑,并生成一个补丁。它不判断自己的补丁是否正确。这不是它的工作,而且架构专门设计为使其无法意外地承担这项工作。

环境和验证层(Environment and Verification layer)在隔离环境中构建、运行和测试迁移后的代码,然后才接受任何更改。 这就是“完成即完成”从观点变成机械事实的地方。谷歌对此的表述很精确:业界历来提供两种糟糕的选项来决定 AI 的工作是否真正完成——要么是无法扩展到数百个文件的人工审查,要么是无法审计的 AI 自我评估(因为没有记录实际检查了什么)。他们的答案是数学验证,即确定性代码,用于确认编译成功、测试通过、行为符合定义的规范,用第三个真正可检查的选项取代了前两个糟糕的选项。

注意这个列表中缺少了什么:在合并之前,没有人类去阅读每一个单独的差异(diff)。这就是“黑暗工厂”模式的全部意义所在,也正是大多数人对安全性的直觉出错的地方,因为这听起来像是系统更加信任 Agent 了。恰恰相反。这是从结构上减少对 Agent 的信任,通过用一个 Agent 无法影响或绕过的验证层,取代了单一的判断点——“Agent 说这个能工作”。

隔离层:为什么每个 Agent 都有自己的沙箱

同时让数百个 Agent 针对同一个代码库运行会带来一个明显的风险:当 Agent 47 正在编辑一个文件,而 Agent 12 的更改依赖于这个文件,并且 Agent 12 的编辑刚刚破坏了编译,会发生什么?

答案,在 OpenAI 发布的迁移架构和谷歌的生产系统中是一致的,就是默认隔离。每个迁移任务都在自己沙箱化的环境中运行,通常是一个独立的 git 工作树(worktree),即该仓库的一个完整、独立的检出副本,范围限定于该任务。如果沙箱中的某个 Agent 破坏了某些东西,它破坏的是一个隔离的副本,而不是共享的代码库,更不会破坏其他 Agent 正在进行的工作。

这种隔离的作用不仅仅是防止冲突。它使整个系统变得易于并行化,因为没有共享的可变状态供数百个同时运行的 Agent 去踩踏。Agent 1 到 Agent 800 可以真正同时运行,每个都在一个干净的环境中,只包含与其特定任务相关的文件和上下文,一个 Agent 的幻觉污染另一个 Agent 正确工作的风险为零。

管理程序(harness),即决定哪个任务进入哪个沙箱以及如何处理生成的补丁的编排层,保持在每个独立沙箱之外。这是一个具体且重要的架构选择:拥有访问密钥、外部工具和实际仓库权限的受信任进程,与 AI 生成代码实际运行的不可信执行环境是分开的。沙箱只获得其单一任务所需的内容,仅此而已。宿主进程永远不会使用其自身的提升权限直接运行生成的代码。这种分离使得让 Agent 的代码得以执行成为可能,因为沙箱内部的错误,甚至是敌对的提示注入,都无法触及沙箱之外的任何东西。

循环本身:规划、执行、验证、优化

剥离规模和具体工具,底层实际运行的循环有四个阶段,每个任务重复执行,直到该任务通过或用尽重试预算。

阶段一:迁移规划。 迁移 Agent 接收其范围明确的任务(一个文件或模块)、具体的目标规范(语言版本、框架变更、API 兼容性要求),并生成一个候选转换方案。这是唯一一个创造性的、基于判断的语言模型推理承担主要工作的阶段,因为决定如何将一个特定模式正确翻译成新框架中的等价物,确实需要理解,而不仅仅是机械查找。

阶段二:自动化环境搭建。 一个独立的组件(在关于此模式的学术文献中有时称为环境 Agent)自主地为迁移后的代码构建一个构建和运行时环境,处理依赖解析和配置,以便候选补丁能够在现实条件下实际编译和运行,而不是在抽象中进行评估。

阶段三:测试验证。 迁移后的代码针对实际的测试套件运行,或者如果该特定模块没有测试套件,则针对生成的等效测试运行。这是机械验证步骤,产生客观的通过或失败结果,而不是一种印象。测试要么通过,要么不通过,Agent 无法通过任何方式含糊其辞。

阶段四:反馈优化。 失败时,具体的测试失败信息和诊断日志会被路由回迁移 Agent,作为有针对性的修正输入,而不是一个模糊的“这不行,再试一次”。拥有该补丁的 Agent 根据具体出错的证据来优化其特定的逻辑和依赖映射,而不是从头开始泛泛地重试。

这个四阶段循环每个任务重复执行,并有一个定义好的上限。一个已记录在案、可工作的该精确循环模式版本,指定了一个停止条件,例如“没有文件再匹配旧模式”,同时还有一个硬性的最大迭代次数,在一个已发布的例子中是 200 次迭代,之后系统会自动停止,而不是在一个无法收敛的任务上无限运行。

这个上限在大规模下至关重要。没有它,一个结构上不可能完成的任务(因为规范本身含糊不清,或者目标模式确实没有干净的等价物)将无限消耗资源,而不是作为一个具体的、有边界的失败浮现出来,让人类可以实际查看并解决。

为什么人工审查无法扩展,以及什么取代了它

有必要精确说明为什么“没有人逐个审查”实际上是这里更安全的设计,而不是在偷工减料。

比较 AI Agent 代码审查和人工代码审查的研究发现了一些具体且有用的东西:AI 生成的审查评论每行代码的长度几乎是人工审查的七倍,并且几乎完全集中在代码改进和缺陷检测上;而人工审查则自然地分布在其他完全不同的事情上:建立共同理解、知识传递、团队成员之间的社交沟通。人工审查的来回互动根据反馈类型的不同而有很大差异。AI 之间的审查互动则要统一和机械得多,无论被标记的是什么。

正确理解这一点,它告诉我们一些重要的事情:人工审查和 AI 验证擅长结构上不同的事情。要求一个人以 Agent 集群产生的速度和数量去审查 800 个独立的差异,这并非安全升级,而是一个导致橡皮图章式批准的瓶颈,因为没有人能在如此大的数量下保持真正的审查力度。“黑暗工厂”模式中真正的安全性并非来自移除验证。它来自用一种验证取代另一种验证:用缓慢、令人疲惫、不一致、分散在数百个重复差异上的人类注意力,替换为一种可以扩展的不同验证:确定性的构建和测试验证,它在差异 1 和差异 800 上产生完全相同的严格性,且零注意力疲劳。

这也正是规划器阶段使用基于编译器的静态分析而非 LLM 判断来进行排序的原因。在系统中任何确定性检查可以取代判断的地方,都应该这样做,因为确定性检查是这个架构中唯一可以在事后真正审计的部分。你可以完全重放静态分析器发现了什么。你无法完全重放为什么一个语言模型“觉得”某个特定的迁移顺序是正确的。

仍然需要人类的地方,以及界限究竟在哪里

这种模式并非“完全移除人类然后听天由命”。每一个可信的已发布版本——谷歌的生产系统、学术界的“环境参与循环”研究、OpenAI 自己的指南——都为人类判断必须保留的地方划出了一条明确的界限。

一项关于 Agent 驱动的库迁移的定量研究得出的一致发现是:Agent 能够可靠地实现高迁移覆盖率,正确识别需要哪些 API 更改,但在更复杂的情况下,它们特别难以保持整体应用程序的行为,因为成功的迁移需要理解意图,而不仅仅是模式匹配语法。该发现直接得出的建议是,在确定性验证标记为高风险或低置信度的文件子集上设置一个人工参与的检查点,而不是针对整个批次。

在实践中,这产生了一个分层系统。静态依赖分析归类为小型、良好隔离且结构简单的文件(任何实际迁移中的大部分),通过完全自动化的循环流动,除了确定性的构建和测试门控之外,无需任何人工干预。被标记为复杂、深度互联或触及业务关键逻辑的文件,即使在一个原本完全自动化的系统中,也会在合并前被路由到队列中,等待实际的人工审查。

这种分层方法是“800 个 Agent,零人工逐个审查”的现实版本。并非没有人类查看任何东西。而是系统被专门设计为将 95% 的机械性、低风险工作通过完全自动化处理,同时将稀缺资源(真正的人类判断)集中用于确定性验证无法复制的、能真正增加价值的那一小部分案例。

为你自己的代码库构建这个模式

这个模式向下扩展和向上扩展一样清晰。无论你是针对一个庞大的生产代码库运行 800 个并行 Agent,还是针对单个仓库运行少量顺序迁移任务,同样的四个角色都适用。

从规划器开始,并抵制将其做成 LLM 的冲动。如果你的迁移有任何类型的依赖结构——文件导入、共享接口、构建顺序——请使用适合你语言的实际静态分析工具来机械地构建那个依赖图。这个单一决策是整个系统中杠杆率最高的一个,因为每个下游阶段都会继承规划器所做的任何排序错误。

将每个单独任务的范围限定得尽可能窄,以依赖图允许的为准。一个文件、一个模块、一个清晰界定的变更单元,并附有一份明确的简报,精确描述需要做什么以及为什么。不要仅仅为了提高效率而将多个不相关的更改合并到一个任务中,因为狭窄的范围是使验证阶段的通过/失败判断毫不含糊的关键。

隔离每个任务的执行。每个任务至少需要一个全新的 git 工作树,如果你以任何实际规模运行,则需要一个完整的沙箱化环境。这不是可选的、可有可无的基础设施开销。它是使并行化安全、使单个 Agent 的错误被遏制而非传染的关键。

在构建其他任何东西之前,先构建确定性验证。编译成功、测试套件通过率、行为等价性检查(在你能构建它们的地方)。这个组件取代了“Agent 说它工作了吗”,变成了“它真的工作了吗”,而这也是大多数自行构建的迁移尝试完全跳过的组件,这正是这些尝试在任何有意义的规模下失败的原因。

明确地限制重试循环,用一个数字,而不是一种感觉。在运行任何东西之前,定义“这个任务卡住了”看起来是什么样子,并将卡住的任务自动路由到人工队列,而不是让它们无限消耗资源,或者更糟的是,默默地报告虚假的成功。

头条数字背后的实际教训

无论在任何特定的大规模迁移中运行的实际数字是多少——800 个 Agent、80 个或 8,000 个——头条数字都是故事中最无趣的部分。有趣的部分在于,这些 Agent 中没有一个被单独信任来决定自己的工作是否正确,并且整个系统是围绕这种不信任而非无视它来设计的。

黑暗工厂在黑暗中运行,并非因为无人监视。它在黑暗中运行,是因为监视已经被完全移入了机器本身——移入了编译器检查、测试套件和依赖关系图中,这些工具每次都能产生同样严谨的答案,无论是文件一还是文件八百,没有疲劳,也没有要求人类连续数千次重复同样的判断所带来的不一致性。

这就是当前每一个在生产环境中运行的此类版本背后的实际模式。不是对更大模型更勇敢的信任,而是一种更严格的拒绝,不让任何一个单一组件——无论是人类还是 AI——成为自己工作的唯一评判者。

关注 @cyrilxbt 获取更多 AI 内容

一键保存

使用 YouMind AI 深度阅读爆款文章

保存原文、追问细节、总结观点,并在一个 AI 工作空间里把爆款文章沉淀成可复用笔记。

了解 YouMind
写给创作者

把你的 Markdown 变成干净的 𝕏 文章

图片上传、表格、代码块,往 𝕏 上手动重排太痛苦。YouMind 把整篇 Markdown 一键转成干净、可直接发布的 𝕏 文章草稿。

试试 Markdown 转 𝕏

更多可拆解样本

近期爆款文章

探索更多爆款文章