关于Bun在全量重构中的经验
我之前提到过 基于过程的质量控制 ,其实从 How Anthropic runs large-scale code migrations with Claude Code | Claude by Anthropic 这篇文章中也能看到相似的地方,他们对整个重构运作的核心强调点即是「过程」。
The core insight is that you don’t fix the code. You fix the process (loop) that produced the code.
不要专注于修复代码,而是专注于修复过程(循环)。这点可以说是证明了我目前正在做的——至少我始终认为这就是未来的正确方向。随着代码数量的膨胀,想要依靠纯粹的人工去保持短期内进行的百万级代码迁移的质量,是基本不可能的。
他们对迁移划分了以下的步骤:
先建立可验证的、严格的退出标准,测试、判别器。皆为保证代码在迁移之后还能确保其与之前的一致性——机械化乃至是形式化的可验证性测试是唯一的办法。甚至为了这一步可能要单独制作一个迁移所用的测试框架。
然后确立可迭代完善的规则手册、依赖关系图、定义明确的目标。这一步的关键点在于确保迁移的过程中不发生漂移,尤其是关键的架构决策和依赖结构,以及当前距离结束还有多远——这一步就和第一步联动了。
设立以怀疑为直接目的的审查员agent,对抗性的审查——这就和我之前所做的一样。但不同的地方是他们设置了两个以上,独立且交叉的审阅,当两者发生矛盾时还有第三审阅者出场。这一步显然是极其耗费token的,但对抗却是稳健性在非机械化测试外的必要保证,这是能最好模拟人类的方式。到底要设置几个我觉得取决于项目的重要度和规模,同时还有预算限制。
对「规则本身」进行压测。这个做法我觉得很值得学习。他们在大型迁移之前会先做试点,去实际跑一次规则,然后观察可能出现的问题。不够这里分两种情况,一种是结构迁移形式的测试,这种的核心点是结构不变但是要换语言,所以观察规则的模式是跑完之后看是否有维持结构上的不变,可以人工来检查。但如果并非是此种迁移,官方推荐的做法就是「对抗性审查」,同时用e2e测试来保证。我觉得这里的关键还是行为和特征是否固定,因为后者这种典型的情况就是迁移的时候可能会顺便进行大规模重构,所以不能只是观察结构是否改变,因此用e2e测试来固定行为和特征就很关键了,但是单测可能就会因为结构的改变而作废。核心的关键点是保证输入、输出来保证(如果原先有副作用、且这个副作用还是关键功能的话,这种设计不良的结构一旦改变,大概率会在e2e上出错)。
接下来就是实际开始跑loop了,实施-审阅-修复的循环结构。这个地方的整个workflow应该是机械化的,就是纯粹的定义好就开始执行——如此才能最小化成本。而且很多任务不见得要用最好的模型,小模型显然在执行速度和成本上都有优势。而根据规模的不同,这一步的后半部分还可以单独拆分出来——构建、冒烟测试、审阅、修复。他们在这里比较有意思的是构建了一个串行化的批量执行测试的守护进程,可以防止一堆子agent重复执行全量测试带来的成本,先聚集测试需求,然后集中在一次性执行中解决这些需求,并发回结果。对大规模软件来说这个确实很重要,否则每个子agent写完都要跑三十分钟测问题,那时间成本会被拉长到十数倍。
整个过程中他们一直很强调「过程」,即不要过度关注于个别故障,而是保持一个稳健运行的过程。而代码审查应当是对抗性的,验证应当是机械化的——也印证了我之前在 关于代码阅读 里面说的,可检验的反馈对agent开发的质量控制来说至关重要。尤其是当前RL为主流的训练会不断奖励agent去满足这些可验证的结果。当然这也导致一个问题,就是不择手段的完成问题,以至于搞出各种表面完成但实际上可能破坏总体任务结果的操作,这时候就需要对抗agent。对后者来说,他的任务就变成了检查,这同样是一个可检验的目标。一个负责构建,一个负责攻击,两者进入一个循环时,反馈平衡才能建立起来。
而最终,我们对整体结果的评估和验收也并非是通过「看代码」来实现的。对大型系统的重构来说,一行行看代码基本不可能,也不现实。但是验收的标准却可以很直接,那就是「查看循环运作的最终结果」。功能正常只是基本,核心点是——我重构最初的目的到底是什么?比如bun的目的就是内存泄漏,那泄露成功降低就是重构是否有效的黄金标准。如果你的目的是性能,显然性能减少了多少直接表明了这次重构的收益如何。因此,验收标准取决于最初的目的,但无论如何,确保功能都是首要前提。
一百万行的重构,全程只需要1个人+11天,这是一个前AI时代难以想象的速度。当然,我觉得更加稳妥的方式可能还是采用 绞杀榕模式,用逐步替代、缓步上线的方法去完成整体迁移。bun毕竟有取之不竭的token和最先进的模型,但对于一般的公司来说,我们都不具备他们的条件,过于激进的进行全量重构可能导致未预料的问题。
但是,时代仍然是变了。诚如文章中所说,重构至少不再是一个决定生死存亡的决策——这一点显然也在提醒决策者。哪怕是同样的行为,也无法再用过去的眼光等同看待。如果重构带来的收益足够高,那么重构就应该是最佳选择。剩下的区别只在于采用什么模式去稳妥、健壮的重构而已。