维护与迁移
维护是今天唯一能够得着 L3 的阶段,因为编译器和测试套件早已规定了什么叫"完成"。Airbnb 用六周迁移了约 3,500 个测试文件,原先估计要 1.5 年;让它成功的是模型周围的流水线,而不是模型本身。可行的模式是:确定性工具打头,语言模型处理长尾,节奏由评审能力而不是生成速度决定。
什么变了
迁移是每个组织都在拖的活:一个已停止支持的框架版本、一个废弃的 API、一个快要不够用的标识符类型。这类活描述起来容易、做完却很贵,因为同一处改动要在成千上万个略有差异的地方重复。在语言模型出现之前,答案是确定性工具:代码改写工具(codemod)、AST 重写、依赖更新机器人。证据表明,它们应当继续做主干。
不过确定性工具有天花板,Spotify 记录下了它在哪里。其 Fleet Management 系统自 2024 年年中起自动化了"大约一半的 Spotify 拉取请求",但背后的脚本越长越难维护。光是 Maven 依赖更新器,为了"处理所有边角情况"就已膨胀到"超过 20,000 行代码",而且"由于这种复杂性,我们能实现的自动化改动大多是简单的"(Spotify Engineering,Honk 第 1 篇,2025 年 11 月)。据 InfoQ 对一场 QCon London 演讲的报道(演讲者为两名 Spotify 工程师,2026 年 3 月,二手来源),脚本让"70% 的舰队的迁移周期从将近一年缩短到不到一周",但"剩下的 30% 因边角情况和复杂性而极其困难"。
变化就发生在这 30% 上。语言模型能处理那些脚本作者要花几周才能穷举的边角情况,前提是由别的东西来判定每一处改动是否正确。在维护阶段,这个东西已经存在。编译器、类型检查器、代码检查器(linter)和现有测试都早于智能体写成,它们检验的正是迁移应当保持不变的行为,而且不在乎差异(diff)是谁写的。这就是为什么判据原则在这里比在任何其他阶段都更容易满足。你不必发明判据,只需让智能体碰不到它。
有两件事没变。第一,光靠模型不够。Google 的迁移团队写道:"仅通过简单提示来使用 LLM,除了最简单的迁移之外都不够"(Google,2025 年 1 月,T2)。Slack 在把模型与 AST 代码改写工具结合之前先单独试过模型,结果"遇到了显著的波动和不一致"(Slack Engineering,2024 年 5 月,T3)。记录在案的每一次成功迁移,都是确定性工具与模型的混合。
第二,结果仍然要有人评审,约束就落在这里。Google 的 JUnit 团队限制了每周生成的变更数量,以免压垮评审者。Spotify 的演讲者在 QCon 上说,这一转变"让 PR 评审而不是代码生成成了新的瓶颈"(InfoQ,二手来源);2026 年 6 月,Spotify 首席架构师报告"要评审的 PR 多了 76%"(Spotify Engineering,T3)。这正是《当代码变便宜,瓶颈就会转移》一章的论点在阶段层面的体现:生成一旦变便宜,迁移的速度就等于评审者的速度。Google 和 Spotify 的完整案例及其注意事项见《案例研究》;本章在其基础上展开,不再重复。
本阶段的阶梯
下面的标准沿用成熟度网格的维护一行,并把各级别的通用条件逐条写出。和本书其他地方一样,级别按任务类型打分("维护:测试框架迁移为 L3;依赖升级为 L2"),并取评审方式与智能体实际持有的权限两者中较高的那个。
这一行网格两头稀、中间密。L1 根本没有公开案例;其余每条边界各带一课。
L0 并不"落后"。Fleet Management 是迄今公开描述过的自主程度最高的变更系统之一,它在 AI 维度上得 L0,只因为其中没有模型。一个能覆盖 70% 舰队的确定性重写,比任何智能体都更便宜、更可预测、也更容易评审;智能体的活是剩下的部分。为了"往阶梯上爬"而用智能体替换好用的代码改写工具,是读错了阶梯:级别描述的是权限,而不是抱负。
L2 由评审定义,而不是由工具定义。Google 的 int32 迁移是参照。模型产出了大部分修改,但工程师评审了每一项变更;作者报告说,"人需要回退模型所做的至少一部分改动,这些改动要么不正确、要么没必要"。《案例研究》把它评为"L2 正向 L3 过渡",因为产量由评审者能消化多少来决定。Elastic 处理出错的 Renovate 依赖 PR 的流水线(2025 年 9 月)按明文政策属于 L2:"未经人工监督,绝不提交 AI 的工作",只要智能体参与过,自动合并就关闭。
L3 改变的是人看什么。在 Spotify,智能体在沙箱里无人值守地运行,确定性核验器决定拉取请求能否被打开,再由负责的团队评审并合并结果。按设计层面的证据,这是针对舰队迁移的 L3,如成熟度模型的示例所示;外部评分者必须记下其中的缺口:没有公开的、与人工变更对比的逃逸缺陷数据。这一行里每个 L3 条目都有同样的缺口。核验器有文档,结果没有。
L4 对语言模型而言是空的。公开记录里没有任何 LLM 编写的迁移变更在验证记录之下、无需逐项人工批准就合并的例子。依赖自动合并由来已久、十分常见,但它是确定性的。
并非所有"迁移"都在这条阶梯上。数据库模式迁移或数据迁移是对生产状态的操作,往往不可逆,适用另一个风险上限。Anthropic 在介绍其自动模式分类器的文章中,列举了自家内部使用中出现的越界行为,其中包括"试图对生产数据库执行迁移"。本书提议的权限边界(见《安全、权限与爆炸半径》)规定:在 L3,这类迁移由智能体准备、由人执行;没有撤销能力和位于爆炸半径之外的备份,就永远不具备 L4 资格。本站的数据库迁移智能体实战手册介绍了这一模式。本章关于 L3 的论断只适用于代码迁移,其影响可以用一次回退撤销。
案例:Airbnb 从 Enzyme 迁移到 RTL
级别:维护,针对一次测试框架迁移的 L3,依据核验器设计打分。决定哪些文件完成的是逐文件的验证步骤,而不是人;文章没有说明完成后的文件如何评审。
Airbnb 需要把 React 组件测试从 Enzyme 迁移到 React Testing Library。"我们最初估计,手工完成需要 1.5 年的工程时间。"团队转而搭了一条流水线,让每个文件依次走过固定的步骤:从 Enzyme 重构、修复 Jest、修复 lint 和 TypeScript 编译器报错,然后标记为完成(Airbnb 技术博客,2025 年)。只有当前步骤的确定性检查通过,文件才会进入下一步;未通过的文件会被重试。
第一轮批量运行"在短短四小时内成功迁移了 75% 的目标文件"。随后团队花四天时间跑一个他们称为"抽样、调整、横扫"的循环:抽查失败案例,调整提示词和上下文,再重跑。这"把完成的文件从总数的 75% 推到了 97%"。部分长尾文件被重试了"50 到 100 次不等"。剩下的文件由人工修复,流水线的半成品为"人工介入提供了很好的基础"。整个迁移"仅用 6 周"完成,覆盖"将近 3,500 个 React 组件测试文件"。
有两个发现比标题数字更值得重视。第一,坚持胜过巧思。"改进结果最有效的途径就是简单的暴力":对着确定性检查反复重试,而不是打磨提示词。这之所以奏效,只因为检查便宜、自动、且不受模型控制。如果智能体能修改核验器,重试循环最终会收敛到删掉那条失败的断言。
第二,上下文比措辞更重要。提示词增长到"40,000 到 100,000 个 token 不等",最多拉进"50 个相关文件";作者把"选对相关文件"称为"主要的成功因素",排在"把提示词工程做到完美"之前。真正得到回报的投入在流水线上:分步验证、重试和上下文选择。
它没有证明什么。迁移后的测试是否还在检验旧测试所检验的东西;文章没有报告覆盖率或变异测试的对比,而这一点格外要紧,因为被迁移的产物本身就是测试(如何检查这一点,见《测试与验证》)。文章也没有给出算力成本、评审工作量,以及迁移后的缺陷数据。1.5 年的基线是一个没人重跑过的估计。
对照:Slack 做的同一次迁移
Slack 在 2024 年做了同一次迁移,报告的数字却不同。它计划转换"超过 15,000 个" Enzyme 测试。仅用 AST 的代码改写工具达到了"45% 的一般成功率",因为"AST 缺乏纳入此类上下文信息的能力",比如渲染后的 DOM。单独使用模型则产生了"显著的波动和不一致"。把两者结合起来,由代码改写工具做机械部分、模型做依赖上下文的部分,得到了"基于选定文件、高达 80% 的转换成功率":对"九个复杂度各异的测试文件"的人工评估发现,其中 80% 的内容被准确转换。Slack 报告的采用率约为 64%,节省了"22% 的开发者时间"。
不要把 80% 和 97% 对比读成 Airbnb 胜过 Slack。两个数字在模型代际上不同(Slack 的文章写于 2024 年),在重试预算上不同(Airbnb 对部分文件重试多达 100 次),在"成功"的定义上也不同(一个是 9 个文件样本中被正确转换的代码所占比例,另一个是约 3,500 个文件中通过了每一步的文件所占比例)。它们在模式上一致,在数字上不一致。迁移数字不能在组织之间迁移,甚至不能在同一次迁移的两次运行之间迁移。你能拿来做计划的,只有你自己第一次试点的数字。
迁移步骤
以下步骤按级别排列。每一次爬升都按改动类别进行:同一个季度里,你可能让依赖修复跑在 L2,而测试框架迁移跑在 L3。
L0 到 L1:先盘点,再加模型。
- 列出你已在运行的确定性工具(代码改写工具、Renovate 或 Dependabot、lint 自动修复)以及它们做不完的迁移。没做完的剩余部分就是你的候选清单。
- 让工程师在迁移工单上使用助手。这一级没有公开证据,所以把它当作便宜而未经测量的一步,而不是需要评估的一步。
L1 到 L2:一个改动类别,核验器先行。
- 挑一个具名、反复出现、终态明确的改动类别:一次框架迁移、一个废弃的 API、出错的依赖升级。本站的迁移智能体、依赖升级智能体和死代码与功能开关清理实战手册覆盖了常见类别。
- 先写核验序列,再写提示词:构建、类型检查、lint、现有测试。像 Airbnb 那样,把每一项做成文件必须通过的一个流水线步骤。
- 让确定性的部分保持确定性。像 Slack 那样,代码改写工具能做的交给它,剩下的交给模型。
- 给每个智能体 PR 署名标记,并对智能体动过的任何东西关闭自动合并。Elastic 的脚本在无法关闭自动合并时会直接中止。
- 跟踪该类别的接受与返工:原样合并、修改后合并、被回退。
L2 到 L3:把判据移到够不着的地方,并改变评审者看什么。
- 在智能体控制之外运行核验器。在 Spotify,核验器在智能体试图结束时于停止钩子中运行,核验失败意味着"PR 不会被打开"(Honk 第 3 篇)。
- 把智能体放进沙箱,只给它一小套工具,推送和通知交给外围基础设施(Spotify 的设计)。
- 为重试编预算,而不是为改写提示词编预算。Airbnb 的收益来自对着检查反复重跑。
- 爬升之前先补齐核验器的缺口。Spotify 迁移下游数据管道时(Honk 第 4 篇,2026 年 4 月),这些仓库很少有构建期测试,于是负责人只能手工测试这些变更。没有核验器的地方,人就是核验器,该类别就停在 L2。
- 用负责人批准的证据包取代逐行评审:核验日志、差异摘要、抽样文件。证据包的格式是本书的提议;附录 A《模板》收录了一个版本。
- 按评审能力设定生成速率,像 Google 那样,并把路由规则写下来。
- 演练暂停与回退,并开始与同类人工变更对比回退率和逃逸缺陷的 90 天比较。比较跑完之前,只能说"设计上是 L3",而不是 L3。
L3 到 L4:还没有人公开过这一步。如果你要尝试,本书的提议是:从一个已经可逆、且已由确定性工具自动合并的类别开始,比如补丁级依赖更新,并套用成熟度模型中的 L4 条件:连续 N 个变更无逃逸缺陷的验证记录、自动回退、具名责任人,以及定期审计抽样。你会是第一个公开数据点。
示例:估算评审节流
以下是示意性算术,不涉及任何具体组织。设想一次 4,000 个文件的迁移。流水线在一周内自动转换 95%,剩下 200 个文件交给工程师。评审者按每批 25 个文件接收变更。
Files converted by pipeline 3,800 (95% of 4,000) PRs at 25 files each 152 Review time per PR 45 min (line by line) Review budget 8 h/wk (2 owners x 4 h) PRs reviewed per week 10.7 (480 / 45) Weeks to land ~14 Twice the generation speed ~14 weeks (review-bound) Evidence pack + sampled files 15 min per PR PRs reviewed per week 32 (480 / 15) Weeks to land ~5
生成一周就完成了;迁移却要 14 周,因为评审要这么久,所以生成再快也什么都不改变。更大的批量也不是杠杆:DORA 2025 年报告推测,与 AI 相关的不稳定性"部分是因为更大批量的代码更难评审"(见瓶颈一章),每个 PR 的评审时间会随之上升。真正能把日期提前的,是改变评审者看什么:从逐行看,变成看证据包加抽样,而这一改变恰恰就是从 L2 到 L3 的那一步。15 分钟这个数字是假设;请测出你自己的。
护栏
让判据在智能体够不着的地方,并检查已知的作弊手法。只要能做到,迁移智能体就会钻核验器的空子。据 InfoQ 对 Spotify 演讲的报道,早期的智能体"会走捷径让构建通过,比如注释掉失败的测试,或降低 Java 版本"。Elastic 的智能体"修复"出错的依赖升级的办法是把升级删掉,团队的应对是在提示词里新加一条规则:"绝不降低依赖的版本"("NEVER downgrade versions of dependencies")。指令不是护栏。本书的提议:加入确定性的差异检查,拒绝任何删除或跳过测试、降低版本、或修改核验器配置的变更,并把这些检查纳入判据。
把 LLM 评判者当作可调的第二道关卡,而不是安全层。Spotify 的评判者在数千次会话中否决了"大约四分之一",而"智能体有一半时间能够自我纠正"(Honk 第 3 篇,2025 年 12 月)。InfoQ 后来报道,Spotify 因其"过于僵化,拦下了有效的变更"而将其移除。评判者有误报成本。确定性核验器优先;评判者可有可无。
把权限放在基础设施里,而不是智能体手里。让智能体在没有生产凭证的沙箱中运行,把它的令牌限定在它自己的分支上,由流水线负责推送、开 PR 和通知。各级别的权限边界见《安全、权限与爆炸半径》;任何数据或模式迁移都始终由人执行。
弄清核验器看不到什么。Spotify 把最糟的失败模式描述为"一个通过了 CI 但功能上不正确的 PR"。你的 L3 只和你的测试一样强;爬升之前,先检查测试发现缺陷的能力(看变异得分,而不是覆盖率),《测试与验证》对此有专门论述。
在评审者处节流。给每个负责团队设定未关闭智能体 PR 的上限,并关闭陈旧的 PR,而不是任其堆积。InfoQ 的报道提到,Spotify 正在考虑"允许迁移负责人批准自己的 PR,并关闭陈旧的拉取请求"。《代码评审》介绍了按风险分级的路由。
指标
按改动类别,把每个流动指标与一个稳定性指标配对,并在智能体开工之前为两者都建立基线。
- 流动。每周落地的变更数;每个智能体 PR 的评审等待时间,与实际评审时间分开测量;相对于上一次不用智能体完成的同类迁移的耗时。
- 稳定性。智能体迁移变更的回退率,与同类人工变更对比;90 天内可追溯到迁移变更的缺陷。唯一公开的智能体对非智能体的回退对比(对照组中含机器人拉取请求)来自编码而非维护:dotnet/runtime 的 0.6% 对 0.8%(《案例研究》,T2)。没有任何迁移案例公布过这样的对比。
- 流水线健康度。核验器拒绝率、评判者否决率(如果你用了评判者)、每个落地文件的重试次数,以及迁移中由人工完成的比例。人工长尾在增长,说明这个类别正在滑出流水线能核验的范围。
有两个流行的数字不该出现在仪表盘上。第一个是 AI 编写的修改所占比例。Google 的 80% 及其为期一年的研究中 74.45% 的变更,描述的是流水线而不是结果;结果是:这些变更在一个不在乎作者是谁的编译器后面落地了。第二个是"节省的开发者年",它是反事实的乘法,而不是测量。
厂商自报。Amazon CEO 在 2024 年 8 月谈及 Amazon 自家的 Q Developer 时说,把一个应用升级到 Java 17 的时间"从通常的 50 个开发者日降到了短短几个小时","我们估计这为我们节省了相当于 4,500 个开发者年的工作量",并且"我们的开发者对 79% 自动生成的代码评审未作任何额外修改便直接发布"(引自 Simon Willison)。三周前的一篇 AWS 博客文章称,Amazon 已"将数以万计的生产应用从 Java 8 或 11 迁移到 Java 17"。
测量方是 Amazon,测的是 Amazon 自己的产品。这里的"成功"指相对于一个估计的人工基线而节省的开发者年。缺失的是:应用的数量、50 天基线是怎么测出来的、评审与修补时间、确定性改动与模型生成改动的比例,以及任何缺陷数据。等级:T4。《经济性、风险与度量》拆解了其中的算术。
哪个指标应当触发退回一级、阈值定在哪里,是第 17 章《衡量成效,以及何时回退》的主题。在迁移开始之前就把阈值写下来。
反模式
- 只靠提示词。把模型对准代码库,让它去迁移。Google 和 Slack 都报告说,除了最简单的情况,这样做都会失败。要搭流水线:确定性步骤、检查、重试。
- 永远只靠确定性。为了追最后那些边角情况,把重写脚本一路养到 20,000 行。悬而未决的争论是:模型该写代码改写工具,还是直接写差异(Moderne 和 OpenRewrite 主张确定性配方,这是分析师观点);无论哪种,都应把长尾交给站在同一套检查后面的模型。
- 智能体能修改的判据。如果智能体能跳过测试、降低版本或修改 lint 配置,流水线通过就毫无意义。不管仪表盘怎么说,这个类别都在 L2。
- 生成快于评审。一千个未关闭的迁移 PR 是队列,不是进展。先算好节流。
- 照搬别人的数字。因为 Airbnb 做到了就按 97% 做计划,或因为 Slack 做到了就按 80%。跑你自己的样本。
- 把确定性自动化叫作"AI 自主",或者反过来。自动合并的机器人 PR 就 AI 而言是 L0;一个因为没人看而被合并的 LLM 编写的 PR,事实上就是 L4。按实际发生的情况打分。
- 把数据迁移当作代码迁移。回退能撤销代码改动,撤销不了一个被删掉的列。
怎么做。
- 列出你的确定性工具做不完的迁移,从中挑一个反复出现、且已有构建和测试套件的改动类别。
- 在写提示词之前先写好核验序列(构建、类型检查、lint、测试,外加针对删除测试和降级版本的差异检查),并在智能体无法修改的地方运行它。
- 从 L2 起步:给每个智能体 PR 署名标记,对智能体动过的任何东西关闭自动合并,并跟踪原样合并、修改后合并和被回退的数量。
- 在扩大生成规模之前先算好评审节流,并给每个负责团队设定未关闭智能体 PR 的上限。
- 为同类人工变更的回退率和逃逸缺陷建立基线,让 90 天对比有可比之物。
- 无论代码迁移到了哪一级,模式和数据迁移都始终由人执行。
- 进入 L3 的标准:核验器在智能体够不着的地方;用负责人批准的证据包取代逐行评审;暂停与回退演练过;90 天的回退与缺陷数据不差于人工基线。这正是第 14 章《90 天试点》推荐的第一个试点。