跳到主要内容

重写现在变得廉价,但做对依然很难。

· 阅读需 10 分钟
Tian Pan
Software Engineer

二十五年以来,“绝不从零开始重写”一直是软件工程界最接近诫律的一条原则。这一公认论点背后的成本结构曾被所有人视为理所当然:重写意味着重新阅读、重新理解并重新编写多年积累的代码;而当你忙于这些时,旧系统仍在运行,竞争对手仍在不断交付。重写之所以被禁止,是因为它太慢了。

编程智能体刚刚消除了这个“慢”的部分。一个智能体可以在几天之内——而不是几个季度——将一个拥有十万行代码的代码库从一种语言或框架翻译成另一种。研究大型机现代化的团队发现,主要由于 AI 辅助转换,平均程序成本从 2024 年的 910 万美元下降到了 2025 年的 720 万美元,咨询机构目前报告称现代化进度加速了 40–50%。那么,这条诫律失效了,对吗?如果重写中最昂贵的部分变便宜了,那么重写又重新回到了选项中。

问题在于:编写代码从来都不是最昂贵的部分,它只是最显眼的部分。在大规模迁移中失败的组织,很少是因为代码难以转换。他们的失败源于代码之外的一切——未记录的行为、数据迁移、集成切换,以及那些没人想到要写下来的运维肌肉记忆。智能体让重写的开始变得廉价,但对于让重写安全完成的那些因素,它们几乎没有提供帮助。

真正变廉价的是:翻译

准确识别智能体真正改变了什么,因为这种改变是真实且巨大的。典型遗留代码库中大约 80% 是机械性的:CRUD 管道、数据映射、序列化、层级间的粘合代码。这正是智能体能够可靠翻译的内容——从 COBOL 到 Java,从 AngularJS 到 React,从过时的内部框架到替代框架的语法级转换。

这种翻译过去曾决定了整个进度。重写之所以是一个耗时数年的项目,很大程度上是因为人类必须阅读旧代码、重构意图并重新编写——而阅读代码是编程中最难、最慢的部分。当智能体负责阅读和重写时,进度会大幅缩减。Microsoft 的工程团队描述了这样一种智能体流水线:它清点 COBOL 资产、提取候选业务规则,并循环输出翻译后的服务,而人类则在睡眠中。

But look at what practitioners report on the other side of that loop: 自动化的 COBOL 到 Java 转换在投入生产前仍需要 40–60% 的手动修复,而且输出结果往往是“技术上的 Java”,却保留了 COBOL 的过程式结构——同样的程序换了套语法而已。智能体给了你一份翻译,而不是一次重新设计。翻译保留了一切,包括那些你原本想通过重写来摆脱的部分。

这种区别正是本文的核心,值得重申:智能体降低了生成一个行为与旧代码库相同的新代码库的成本。但它们并没有降低去搞清楚“与旧代码行为相同”究竟意味着什么的成本。

从未廉价过的部分:那些没人写下来的行为

Hyrum 定律指出,只要有足够多的用户,你系统的每一种可观察到的行为都会被某人所依赖——不是文档中的契约,而是可观察到的行为。下游团队为某个 bug 编写了变通方案,而这个方案现在又依赖于这个 bug。API 响应中未记录的排序顺序。由于批处理作业总能按时完成,某份报告会在早上 6:02 到达,如果没到,三个部门之外的一张电子表格就会崩溃。

这些内容都没有以一种智能体可以忠实迁移的形式存在于代码中。智能体翻译的是代码表达的内容。而你的用户依赖的是系统在生产数据、生产规模以及与其他系统关联时所表现出的行为。这两者之间的鸿沟正是重写项目一直以来折戟沉沙的地方,而且在智能体出现后,这条鸿沟依然如故:

  • 数据迁移。 模式(Schema)在代码里,但数据质量不在。二十年来半途而废的后台填充、具有特殊含义的哨兵值(例如 “999999” 并不代表数量),以及违反新系统约束的行。每一个延期的迁移估算,都栽在了这里。
  • 事务和性能行为。 遗留系统,尤其是大型机,蕴含了非功能性的保障——批处理吞吐量、I/O 顺序、严格的 SLA——这些是平台的属性,而不是程序的属性。忠实的逐行翻译在功能上可能完全一致,但在运行层面可能是错误的。
  • 集成网络。 系统的每个调用者都是一个 Hyrum 定律的风险项。内部调用者你可以找到;但外部合作伙伴、定时文件投放和屏幕抓取脚本,你通常找不着——直到切换上线的那天晚上。
  • 运维肌肉记忆。 哪些告警是噪音,哪些故障会自动恢复,哪些需要叫醒财务部的某个人,这些都是值班知识。旧系统的运行手册在人们的脑子里,而新系统会让它失效。

挖掘这些埋藏的行为——而不是代码转换——才是任何迁移中最具价值的阶段,也是大多数项目视为走过场的阶段。智能体在这里也能提供帮助,但它们扮演的是考古学家而非打字员的角色:从日志中挖掘未记录的调用者,生成特征测试(characterization tests)以在任何人修改之前锁定当前行为。这项工作的成本并没有降低 10 倍。它可能只是略微降低了,而它一直以来都是整个工期中最长的那根杆子。

新的失败模式:连环烂尾重构

当重构的启动成本高昂时,成本本身就是一种过滤机制。在写下第一行代码之前,你需要高层支持、资金充足的团队以及跨季度的承诺。这种过滤挡住了许多优秀的重构方案,但也挡住了那些轻率的尝试。

Agent 移除了这种过滤。一名配备了 Agent 集群的资深工程师可以在一周内,在没有任何指令的情况下,利用业余时间开发出一个看起来很像样的内部系统 v2 版本。Demo 运行良好。Demo 总是运行良好。但 Demo 无法体现的是最后那 20% —— 等效性证明、数据割接、17 个集成点 —— 而这 20% 的成本依然如故。

绞杀者模式(strangler-fig)迁移数据中有一个极具启发性的数字:在最初 90 天内提取的单体功能不足 5% 的项目,失败率高达 92%,而失败的迁移留下的沉没成本中位数为 210 万美元。早期势头一直是预测指标,而停滞则永远是杀手。现在想象一下,当启动成本几乎为零时这种动态会如何演变:组织累积的不是一个停滞的重构,而是好几个 —— 一个个完成度 80% 的替代品构成的坟场,每一个都足够现代,能吸引新的功能开发,但没有一个足够完备到能让旧系统寿终正寝。

这种最终状态绝对比从不重构更糟糕。你现在必须维护旧系统加上 N 个部分完成的后继者,而且每一个 bug 修复都必须在所有系统中同步考虑。旧的建议是“永不重构”;失败模式是一个昂贵的重构。新的失败模式是五个廉价的重构,但没一个能完工。廉价的启动需要一种昂贵启动自动强制执行的纪律:如果没有规划好“切换”(cutover)—— 包括日期、等效性标准以及关闭旧系统的计划 —— 就不要开始重构。

真正发生变化的权衡逻辑

这并不意味着“永不重构”的戒律仍然坚不可摧。它意味着决定性变量发生了变化。问题不再是“我们负担得起重新编写这个系统吗?” —— 你负担得起 —— 而是“这个系统承载了多少未记录的行为,以及我们验证等效性的成本有多低?”这种重新定义将遗留系统分成了两类。

廉价重构时代真正释放了那些行为可验证且影响范围可控的系统:

  • 你拥有所有的客户端。内部工具、管理面板、后台工作流。当所有消费者都在你的代码库中时,海勒姆定律(Hyrum's Law)的风险是可以枚举的。这就是为什么“自建还是购买”的界线正在这个细分领域移动 —— 一项 2026 年的行业调查发现,35% 的组织在过去一年中用内部构建的工具替换了至少一种主要的 SaaS 产品,78% 计划构建更多。
  • 存在可执行规范。一套真实的测试套件,或者更好的,可回放的生产流量。如果你可以将上个月的请求同时通过两个系统并对比输出差异,等效性验证就不再是一个研究项目,而变成了一个批处理任务。
  • 数据模型稳定且规模较小。重写服务是一回事;迁移数据则是另一回事。
  • 之前只是因为成本原因而“保留”。每一个因为现代化改造报价高达七位数且失败率对半开而无人问津的系统,都值得重新评估。报价确实变了。

而它让那些原本就危险的系统依然危险:庞大的接口表面积、无法枚举的外部消费者、数十年来累积的行为,以及数据迁移本身就是风险。对于这些系统,绞杀者模式 —— 在路由层后面进行增量替换,在切换前针对实时流量验证每个切片 —— 仍然是唯一具有可靠记录的模式,无论有没有 Agent。Agent 只是让每个“绞杀切片”构建得更快;它们并没有消除切片化的必要。

预算应花在“考古”而非“打字”上

实际的启示是重构预算分配的倒置。在 Agent 时代之前,预算大部分用于构建,只有一小部分用于验证。在 Agent 时代之后,预算应该大部分用于验证 —— 翻译前的特征测试、过程中的流量回放和输出比对、之后带有即时回滚机制的分阶段切换 —— 围绕着一个几乎变得微不足道的构建阶段。

在 2026 年批准任何重构之前,请核对清单:你能枚举每一个消费者吗?你能针对两个系统回放真实流量吗?数据迁移是否被列为一个拥有独立负责人的独立项目?是否有明确的切换日期和关闭旧系统的标准?如果答案是肯定的,那么在 2020 年显得不负责任的重构,在今天可能就是直接而正确的选择 —— 而基于继承来的教条守着一个腐朽的系统才是真正的错误。

如果答案是否定的,Agent 并没有改变你的处境。它只是让你以更低的成本发现,打字从来都不是你的问题所在。

References:Let's stay in touch and Follow me for more thoughts and updates