- Published on
Bun 把 Zig 重写成 Rust 的 11 天 — AI 大规模迁移里真正能带走的东西
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 引言 — 写文章比重写本身还费时间的项目
- 用数字看这 11 天
- 让这套代码库格外好迁的三个条件
- 人仍然必须做的事 — 修的是循环,不是代码
- 反驳 — 「未经评审的糟粕」与六周后的仓库
- 这套方法在你的代码库里会崩掉的地方
- 结语 — 11 天是预言机的函数,不是 AI 性能的函数
- 参考资料
引言 — 写文章比重写本身还费时间的项目
2026 年 7 月 8 日,Bun 公开了 Rewriting Bun in Rust。工作本身从 5 月 3 日开始,5 月 14 日合并进主分支,所以 Jarred Sumner 花了将近两个月,来整理一件 11 天就干完的事。Simon Willison 在 自己的博客里 点出这是一篇「从 5 月 9 日就一直在许诺」的文章,说的也是同一回事。
数字已经传得够多了 — 不算注释的 53 万 5,496 行 Zig、1,448 个 .zig 文件、6,502 个提交、最多 64 个并发的 Claude 实例、按 API 标价折算约 16.5 万美元。这些数字很好引用,但并不是能带走的东西。你的团队明年迁移遗留服务时用得上的,不是「11 天」,而是为了让 11 天成立、必须事先就位的那些条件。
而那些条件比想象中苛刻。本文把 Bun 的发布文、Anthropic 的方法论总结、Zig 作者 Andrew Kelley 的反驳,以及合并六周之后仓库的真实状态并排放在一起,看这套做法在哪里成立、又在哪里崩掉。先说结论:有预言机测试套件的重写,是所有迁移里最简单的一种。先承认这一点,后面的内容才用得上。
用数字看这 11 天
下面这张表把 Bun 发布文和 Anthropic 总结里给出的数值汇到一处。只收录两份文档说法一致的项目,说法分歧的项目留到下文正文里单独点明。
| 项目 | 值 |
|---|---|
| 周期 | 2026-05-03 至 05-14(11 天),全平台转绿是构建 #54202 |
| 原始规模 | Zig 535,496 行(不含注释)、1,448 个文件,此外还有约 20% 是 C++ |
| 最终 diff | 新增 1,009,272 行,提交 6,502 个(含合并提交 6,778 个) |
| 并行度 | 峰值 64 个实例(4 条工作流 × 16),整体约 50 条动态工作流 |
| 模型 | 预发布版 Claude Fable 5,评审与规则生成用 Opus 4.8 |
| token | 非缓存输入 59 亿、输出 6.9 亿、缓存输入读取 720 亿 |
| 成本 | 按 API 标价折算约 16.5 万美元 |
| 测试 | 删除与跳过的测试 0 个、6 个平台、每平台 5.7 万到 6 万个测试 |
| unsafe 占比 | 约 78 万行里 unsafe 块约 2.7 万行(约 4%),其中 78% 只有一行 |
| 合并后的回归 | 已知 19 件,全部修复 |
| 性能 | HTTP 吞吐提升 2.8% 到 4.8%,二进制体积缩小约 20% |
性能这一行是全表最安静的一行。花掉 16.5 万美元换来的只是几个百分点的吞吐,那本身构不成投资理由。Bun 真正买到的不是速度,而是内存安全 — Anthropic 总结里引用的泄漏基准显示,构建 2,000 次之后的累计内存从 6,745MB 降到 609MB(Bun 自己的发布文对同一件事的写法不同,说的是每次构建 3.3MB 的泄漏消失了。两份文档的表述对不上,所以这个数值当作单一来源处理更稳妥)。用户实际感知到的变化,大概就是 Linux 上 p50 的启动时间从 517ms 降到 464ms,快了 10% — 用 Willison 的说法,是一个「无聊就是好」的结果。
让这套代码库格外好迁的三个条件
第一,一套与语言无关的预言机本来就存在。Bun 的测试套件是用 TypeScript 写的。运行时不管用 Zig 写还是用 Rust 写,测试代码一个字都不变。每个平台五万七千个以上的测试和一百万条以上的断言,不需要人来判断就能裁定移植是否完成。删除与跳过的测试为 0 个之所以重要,原因就在这里 — 意思是没人动过裁判。
这个条件有多罕见,想一想反面例子就清楚了。测试贴死在内部实现上的代码库(直接调用模块内部函数、或者检查私有状态的测试),语言一换,测试也得跟着一起扔。裁判消失的迁移,就只是一次大规模的未经验证的提交。Anthropic 的文档把「先把裁判(the judge)立起来」钉在六个阶段的第 0 阶段,还要求拿故意弄坏的代码去跑裁判,先确认它会失败,正是出于这个原因。
第二,这是一次结构保持式的翻译。1,448 个 .zig 文件对应到同样数量的 .rs 文件。因为没有重新设计架构,工作单元就落到单个文件上,只要知道文件之间的依赖图,并行化的顺序就定了。而且判定「有没有做完」的方法不是人的判断,而是磁盘状态 — 输出文件存在就算完成。Anthropic 公开的 迁移套件 正是这样定义队列的,因此中断和恢复都变成了零成本。
第三,目标语言的编译器就是第二位裁判。Rust 在编译期强制所有权和生命周期,所以翻译一旦潦草,还没走到测试构建就先坏了。按 Pragmatic Engineer 的 梳理,约 1,600 个编译错误在 12 小时内被清掉,而这份错误清单本身就承担了自动写出下一批工作队列的角色。从强类型语言迁到强类型语言,这层反馈是白送的。从 Python 迁到 Python 的重构里,没有这位裁判。
把三个条件压成一句话就是 — 可以由机器判定的正确答案,早就存在了两层。11 天不是因为 AI 厉害才出现的,而是因为这在 11 天里始终是一道机器能自己批改的题。
人仍然必须做的事 — 修的是循环,不是代码
发布文里最贴近实务的一段,是写代码之前的那三个小时。Sumner 和 Claude 讨论了约 3 小时,确定 Zig 的惯用写法该怎么映射到 Rust,结论被序列化成一份约 600 行的 PORTING.md。Anthropic 套件给这份文档加的元规则说得很准 — 只要两个智能体可能给出不同答案,那个判断就该写进规则手册。
接下来是 3 个文件的预演。每个文件配一名实现者和两名对抗式评审者跑一遍,产出的译文全部丢掉,只留下并修改规则。这一步抓出了两个问题,要是就这么走下去,它们会扩散到全部 1,448 个文件。把人的时间集中砸在三个小时和三个文件上,这个安排才是这套方法论的核心。
正式作业里人介入的位置,同样是系统性的,而不是单个文件。最典型的是循环依赖。Zig 靠惰性编译能容忍循环 import,Rust 的模块系统不行,于是数千个模块错误一次性爆开。此时人做的不是去修文件,而是 把依赖该归入删除、移动还是边界重构,编码成逻辑。Anthropic 文档反复使用的一个说法概括了这种姿态 — 不是去修代码,而是去修产出这段代码的那个循环。
把套件推荐的队列结构压到最小,大致是这个样子。完成判定里既没有人也没有模型参与,这一点就是全部。
# manifest.tsv: <源路径>\t<目标路径> (按依赖图顺序排列)
# 「完成」的定义 = 目标文件存在于磁盘上。不设置其他任何判定标准。
while IFS=$'\t' read -r src dst; do
[ -f "$dst" ] && continue
echo "$src -> $dst"
done < migration/manifest.tsv > migration/queue.txt
wc -l < migration/queue.txt # 剩余工作量。中断免费,恢复不过是重新执行一次。
这个结构为什么重要,想想反面情形就很清楚。你一旦去问智能体「这个文件都迁完了吗」,进度本身就变成了模型输出,工作状态也就成了可以被幻觉编造的东西。
反驳 — 「未经评审的糟粕」与六周后的仓库
发布次日的 7 月 9 日,Zig 作者 Andrew Kelley 发出了 反驳。The Register 摘出的「未经评审的糟粕(unreviewed slop)」这个说法抢走了标题,但他抛出的论证本身要锋利得多。
核心是 测试套件的自相矛盾 。如果说可以合入一百万行未经评审代码的依据就是测试套件,那这套测试套件当初为什么没抓住现有 Zig 代码里的 bug?Bun 自己都说旧代码里内存 bug 不少,那么主张同一位裁判能充分验证新代码,就很难站得住。Kelley 还补了一句:问题的成因不在语言,而在项目的价值体系 — 他的要旨是,核心争点跟 Zig 和 Rust 的语言特性毫无关系,而在于两个项目的价值体系已经分道扬镳。
这个指摘是对的,同时也漏了一个方向。预言机抓不到的那一类缺陷,确实存在被目标语言的类型系统从结构上消除掉的情况 — use-after-free 和二次释放,在 Rust 里只要走出 unsafe 就在语法层面无法表达。所以「测试没抓到的 bug」里相当一部分,是编译器而不是测试抓住的。不过这套逻辑会随 unsafe 占比同步变弱,而 Bun 的这个占比约为 4%、约 2.7 万行。HN 讨论里出现的反驳正好戳在这一点上 — 跟一个五万行 Rust 项目只有 9 行 unsafe 的案例相比,2.7 万行不是能叫作「安全 Rust」的量级。
合并六周之后的状态也得一起看才算公平。Tom Lockwood 在 7 月 27 日 直接查看了仓库,当时最后一个发布标签还是 5 月 12 日的 v1.3.14,基于 Rust 的 v1.4.0 到那时仍处于 canary 状态。机器人账号开出的 open PR 从 7 月 9 日的 1,277 个涨到 7 月 27 日的 2,475 个,Lockwood 推算,把 CI 成本和随之而来的 token 用量算进去,实际成本会逼近 80 万美元。这个推算值是外部观察者自己的计算,并非 Bun 或 Anthropic 确认过的数字,所以不是可以照搬引用的数据。
另一边的事实同样清楚。基于 Rust 的 Bun 随 6 月 17 日发布的 Claude Code v2.1.181 一起出货,那时已经在数百万人手里跑着了。也就是说,「在生产环境跑着」和「发布完成了」之间错开了六周以上,而这段落差恰恰是该写进迁移计划里的条目。合并不是终点,而是剩余工作队列开始的地方。
这套方法在你的代码库里会崩掉的地方
没有预言机,到这里就结束了。这套方法论是靠机器判定替换人工评审来换速度的。没有判定者,就不是被替换掉了,而只是被省略了。HN 帖子里有个很好的例子 — 要按同样的方式迁一个游戏引擎,拿什么当裁判?输出是像素和声音的系统,本来就很难做出可移植的单元测试。同样的问题原封不动地适用于 UI 层、批处理报表和硬件控制。
一旦混进重新设计,并行化就会崩。Bun 保留了原结构,所以文件级队列才成立。如果决定一边迁一边重画模块边界,工作单元就从文件变成模块,源和目标也没法逐行对照,3 个文件的预演这道验证装置本身就失去了意义。这正是 Anthropic 套件把重新设计型单独拎出来、注明「规则手册会变成设计文档,预演会变成设计评审」的原因。想把迁移和重画一次做完的诱惑,是这套方法论最常见的失败原因。
评审的经济账算不过来。让人去读一百万行是没有办法的。Bun 承认了这一点,把判定交给了对抗式评审者、编译器和测试。这个选择对不对,说实话还没有定论 — 已知的 19 件回归是「被发现的那些」,没被发现的数量按定义就无从知晓。HN 上一位开发者留下的反应把这份张力说得很清楚:两周里放出 19 件回归,在他们公司大概正在给客户写道歉信。在一个下载量不是 22 万而是 2,200 万的运行时上,19 这个数字算大还是算小,由领域来决定。
而且这种规模的重写,仍然是例外性的选择。正如 Anthropic 文档坦率写下的,这类项目过去要 4 年、300 万到 400 万美元,如今是 16.5 万美元,所以不再需要「押上存亡的正当化理由」。门槛确实降低了。但门槛降低本身并不等于这是个好决定。如果迁移的理由不能收敛成一个慢性瓶颈(构建时间、内存 bug 的历史记录),那么不迁依然是默认选项。
结语 — 11 天是预言机的函数,不是 AI 性能的函数
总结一下。
- 造出这 11 天的不是模型,而是三重机器判定 — 与语言无关的测试套件 + 文件对文件的结构保持 + 强类型编译器。三者缺一,同样的方法就跑不出同样的速度。
- 人花掉的时间集中在前段。3 小时的规则手册讨论和 3 个文件的预演,提前掐断了本会扩散到 1,448 个文件的问题。之后人的介入,是系统性错误的分类规则,而不是单个代码。
- 批评也有实体。用测试没抓到的 bug 去论证重写的正当性,同时又用同一批测试为新代码背书,这个论证有洞;而约 2.7 万行 unsafe,让「变安全了」这个说法大幅走弱。
- 合并和发布之间还压着六周以上的剩余工作。迁移排期里若把合并日当成完工日,这一整段就会凭空消失。
有预言机的重写,是迁移里最简单的问题。在你自己的项目上,首先要确认的既不是模型也不是预算,而是有没有一套迁移前和迁移后都能照样跑的测试。如果没有,本文里的 11 天就不是参考资料,而是另一个世界的故事。
参考资料
- Rewriting Bun in Rust — Bun 官方发布文 (2026-07-08)
- How Anthropic runs large-scale code migrations with Claude Code — 方法论总结
- anthropics/code-migration-kit-with-claude-code — 提示词、模板与脚本
- Andrew Kelley — My Thoughts on the Bun Rust Rewrite (2026-07-09)
- The Pragmatic Engineer — What can we learn from Bun's rapid Rust rewrite with AI?
- Simon Willison — Rewriting Bun in Rust (2026-07-08)
- Tom Lockwood — How is the Bun Rewrite in Rust Going? (2026-07-27,含外部推算值)
- Hacker News — Rewriting Bun in Rust 讨论串
- 用 AI 迁移代码库的实战流程 — 方法论篇 (相关文章)