DC娱乐网

53万行代码、1448个文件、11天——全部重写

导读一个真实53万行代码AI重写案例的完整拆解:从被骂到合并,从方法论到四个硬前提——读完你会对自己的项目能不能复制这种

导读一个真实53万行代码AI重写案例的完整拆解:从被骂到合并,从方法论到四个硬前提——读完你会对自己的项目能不能复制这种效率,有一个清醒的判断框架。01掌握AI辅助大规模重写的四步方法论——不是一句prompt02获得判断自己项目是否适合类似方式的四个前提自诊框架03理解「AI替代程序员」这个说法的逻辑漏洞在哪里

"一开始我完全不信这能成。"

Jarred Sumner 说的是实话。2025 年 12 月,他把自己一手打造的 JavaScript 运行时 Bun 卖给了 Anthropic。一个当时月下载量 720 万、收入为零、靠 2600 万美元融资撑了四年的开源项目。收购后他拿到的不是资金或职位,是一件事:Claude Fable 5 的预发布版,当时外界还没有人能用。

于是他产生了一个想法。Bun 的代码库是 535,496 行 Zig,不含注释,总共 1,448 个文件。这些代码他自己写的。每一个模块的取舍、每一处手动管理内存的代价、每一条 unsafe 路径的 tradeoff,他都亲自尝过。安全 Rust 的编译器承诺把这些内存 bug 全部变成编译器错误。但手动重写,需要冻结功能开发整整一年。

他决定让 AI 试试。11 天后,他合了代码。

全部测试通过。53 万行代码,从 Zig 变成了 Rust。一百万个断言,一条没少。

01. 一个见了鬼的内存 bug 清单

搞懂方法论之前,先问一个更基本的问题:为什么要重写?

Bun 的 Zig 代码库里埋着一种反复出现的痛苦:use-after-free。一个对象被释放了,后面还有代码在用。double-free。内存泄漏。race condition。Zig 给了 Jarred 一套内存管理工具。但工具和保险是两回事。Zig 没有析构函数,defer 要手动写在每一个调用点。编译器不会阻止你把已释放内存的指针传给下一个函数。

Jarred 自己的原话更狠:

「"Just be really smart and don't make mistakes?"」

这是他自己写的一个小节标题,一个问号放在句尾,嘲讽拉满。

Bun 的 C++ 依赖占了代码库大约五分之一,主要来自 JavaScriptCore 引擎。JavaScriptCore 自带一套保守栈扫描的垃圾回收器,它会扫描整个栈来找指针。但这套 GC 和 Zig 的手动内存管理混在一起时,问题就变得特别棘手。C++ GC 认为是活着的对象,Zig 侧可能已经手动释放了。反过来,Zig 侧觉得应该还活着的内存,C++ GC 可能早就收走了。这种混合在工业级系统里是一种罕见的需求,也因此鲜有现成的最佳实践。每一个新版本都可能在某台特定机器上、某个特定 load pattern 下触发一个跑了半年都没被发现的 use-after-free。

结果就是 bug 列表越来越长。代码本身没有写得不好。但 53 万行手动管理内存,这个规模本身已经超过了人类的容错边界。你可以写一万行的 C 不出错,但 53 万行?你开始依赖风格指南、code review、团队纪律、运气。而每一条你加进风格指南的规则,Rust 的编译器在十年前就已经把它变成了编译错误。

安全 Rust 给的答案是编译器强制执行,不是给人更好的工具。在 safe Rust 里,use-after-free 和 double-free 是编译错误。你的 PagerDuty 永远不会因为一条已释放指针被凌晨三点叫醒。borrow checker 在你写完代码的那一刻就告诉你哪条生命周期断了,不等用户撞上 crash。

问题是:你怎么把 53 万行 Zig 变成 Rust,同时不废掉一整年的开发速度?

02. 他让 AI 搞了一场生产线

大部分人对 AI 重写代码的想象很简单:代码丢进去,说「用 Rust 重写」,等结果。Jarred 的实际操作完全是另一码事。这是他推了四年的代码,他知道每一行的骨头长什么样。但他没有自己动手翻——他搭了一条生产线。

第一步,3 小时对话,产出一本翻译词典。

Jarred 没有直接丢代码。他和 Claude 聊了 3 个小时,逐条讨论 Zig 中每种模式在 Rust 里的等价写法。Zig 的 std.mem.Allocator 对应 Rust 的什么?手动 defer 怎么映射到 Drop trait?Zig 的编译期反射如何在 Rust 里用宏和 trait 实现?他本质上在做一件事:把自己大脑里对所有代码路径的理解,翻译成 AI 能读懂的显性规则。

对话的产物是一个文件:PORTING.md,一本从零到全量的机械翻译指南。接着他又让 Claude 分析了每一个 struct 字段的生命周期,产出了第二个关键文件:LIFETIMES.tsv。逐字段标注:这个指针谁拥有、谁借用、何时释放、有没有跨线程传递。

没这两个文件就没有后面的任何事。AI 能翻译代码,靠的不只是大模型的聪明。它靠的是把隐性知识显性化。Jarred 在自己脑子里知道每条内存路径的意图,但 AI 不知道,代码里也没写。这两个文件就是知识传递的载体。换句话说,他不是让 AI 凭空理解他的代码——他把他自己的理解先写给了 AI。

第二步,先试 3 个文件。

他没有一上来就全量跑。挑了 3 个最有代表性的文件跑 trial run:一个解析器模块、一个 I/O 调度模块、一个 HTTP 处理路径。跑通后回到 Zig 原版对比行为,确认机械翻译没有引入语义偏移。3 个文件全绿之后,他才把流程推到剩下的 1,445 个文件。

这里有一个隐藏的技术条件,是整个实验能成立的前提:Bun 的测试套件是用 TypeScript 写的,与实现语言完全无关。同一个 ts 测试文件,底层是 Zig 还是 Rust,它只认一个东西:断言结果。HTTP 请求返回的 status code 是 200 吗?文件读出来的哈希值对吗?WebSocket 的帧顺序对吗?一百万条断言,每一条都是一条行为契约。对于 AI 重写来说,这个测试套件就是客观裁判。它不关心代码是怎么写的,它只问结果对不对。

绝大多数项目没有这个东西。你有多少测试是用被测语言本身写的?你的测试里有多少 mock 和 stub 对实现细节做了硬编码假设?没有语言无关的测试套件,AI 重写就失去了唯一的客观反馈信号,你只能靠人肉看代码来判断对错,而这个过程的成本会直接吞噬所有效率。

第三步,50 个 Claude Code 动态工作流,连续跑 11 天。

1 个 prompt 不够,50 个 prompt 也不够。需要的是 50 个动态工作流,每个工作流内部包含一串步骤:读 PORTING.md 建立上下文,读一个 .zig 文件,生成对应的 .rs 文件,修复编译器错误,跑相关测试,查看失败的断言,定位错误,修改代码,重新编译,重新跑测试。反复迭代直到通过。

Jarred 的角色在流程层面把关:这个工作流的 prompt 设计是否合理?翻译后的 Rust 代码质量用什么方式验证?当测试失败时,是修改工作流还是手改代码?他自己的原则很明确:修复产生代码的流程,不要手动修代码。手修了一个 bug,明天同样的 bug 会在另一个文件里重新出现。修了流程,这一个 fix 会应用到所有 1,448 个文件。

第四步,对抗性审查。

这是整个方法论里最聪明的一步。

Jarred 发现了一个问题:让同一个 Claude 既写代码又审查自己写的代码,它会有确认偏误。实现者倾向于认为自己的实现是对的,会在审查时放过那些看起来合理的错误。于是他拆成了三个角色,每个角色跑在独立的上下文窗口里:

一个实现者看到原始 Zig 代码、PORTING.md、以及自己的翻译推理过程。两个以上的对抗审查者只看到 Rust 版本的 diff,不知道实现者的推理过程,不知道代码的意图。审查者的唯一指令是:「假设这段代码是错的,找出 bug。」

这种信息不对称是刻意制造的。审查者不被实现者的思路带偏,只能从纯结果角度判断——这段代码的行为,在边缘条件下,会不会出错?

审查者抓出来的问题是真实存在的,每个都有 commit 引用可回查。三个典型案例:

第一例,Box 的 use-after-free 加 double-free。异步 uv_close 把 Pipe 释放了,但后面还有代码在用这段内存。Rust 编译器不会报错,因为 unsafe 块跳过了 borrow check。这种 bug 在 Zig 原版里是被手动 defer 保证的,到了 Rust 里,实现者机械地翻译了控制流但漏了生命周期约束。

第二例,f64 负数的 trunc 和 floor 行为差异。负 0.5 的 trunc 返回 0,但纳秒计算需要向下取整到负 1。实现者用了 trunc,结果生成了一个在数学上不可能的值,传给系统调用后越界 panic。编译通过,语义错了。

第三例,unwrap_or 的急切求值。Rust 的 unwrap_or(b()) 在参数是 Some 时仍然会执行 b()。如果 b() 有副作用,比如修改计数器或清理资源,逻辑就会在无意中偏离原版。实现者把它当成了 C 的短路求值来翻译。

三条都是编译通过的代码。三条都看起来合理。三条都是人仔细读才能发现的 bug。

对抗审查的底层逻辑值得单独拎出来说。不是审查 AI 的态度是否认真——是利用 AI 之间的信息不对称来逼近真相。实现者有全部上下文但可能自欺,审查者没有上下文只能靠结果反推。

分歧之处,bug 藏身之所。

03. 被骂了 6 天,然后甩出一篇博客

这套方法论的首次公开,源于一次「翻车」。

2026 年 5 月,有人在 Bun 的 GitHub 仓库里发现了一个分支,名为 claude/phase-a-port。里面放了一份 PORTING.md,Zig 到 Rust 的翻译指南。有人在 Hacker News 上发了帖,标题直白:Zig → Rust porting guide。帖子爆了,723 分,555 条评论。

然后社区炸了。

有人说这是 AI 鬼画符,一个 stochastic parrot 的产出,连编译都未必能过,遑论跑生产。有人搬出了 Jarred 几个月前在 X 上的爆论:"I expect OSS to go the opposite direction: no human contribution allowed. Slop will be a nostalgic relic of 2025 & 2026." 再加上 Bun 当时刚出过内存泄漏 crash 生产环境的新闻,vibed code 变成了流行的嘲讽标签。社区潮水般的评论里出现了一个清晰的叙事:Bun 被收购后创始人飘了,用 AI 乱搞,代码不审就敢公开推分支。其中有条评论的点赞数飙升——大意是「一个被 Anthropic 收购的高调项目,branch 名带 claude/ 前缀,这不叫实验,这叫表态。」

Jarred 亲自下场了,在这条帖子第一页就打出了自己的评论:

「"This whole thread is an overreaction. 302 comments about code that does not work. We haven't committed to rewriting it. There's a very high chance all this code gets thrown out completely."」

但这话淹没在了 555 条评论的噪音里。HN 的一个用户用一句话戳中了要害:「当你在一个被全世界最受关注的公司拥有的高调开源项目上工作时,你的分支名和提交信息本身就是一种对外沟通。人们会把它解读为意图。」

6 天后,Jarred 在 Bun 的官方博客上发表了《Rewriting Bun in Rust》。

没有辩解,没有回应争议。直接亮出结果:合并了。所有测试通过。11 天。

社区的反应从「他在瞎搞」变成了「他怎么做到的」。

被骂了 6 天,然后甩出结果——这才叫回应。

04. 11 天顶一年?边界比数字更重要

现在必须说清楚一件事:这个 11 天顶 3 个工程师一年的对比,在什么前提下成立?

第一个前提:有一个语言无关的、包含一百万个断言的测试套件。测试本身就是行为规格,它告诉你做对了还是做错了,不需要人去判断。绝大多数项目没有这种东西。你的测试里有几个是纯行为断言?有几个底层实现一换就全部崩掉?

第二个前提:有精确的行为规格,原始代码本身就是。Bun 的 Zig 版本已经在生产环境跑了四年,月下载量从零涨到千万级。它的行为不是凭空猜测——它就是一个活的规格说明书。AI 重写的任务是做到一模一样,不必从需求出发重新实现。这件事比从零开发要容易得多。但比你以为的容易,不是 AI 的功劳,是规格的功劳。

第三个前提:操作者自己写了所有原始代码。Jarred 面对的不是陌生代码库。他 2021 年 4 月 16 日写下 Bun 的第一行 Zig,在奥克兰一个狭小的公寓里,LLM 还没出现。他对每一行的意图、每一个边际条件的取舍、每一条 unsafe 理由都有肌肉记忆。PORTING.md 的本质是他的隐性知识翻译成了 AI 能读懂的显性规则。换个工程师来,光理解这些代码可能就要几个月。

第四个前提:用的是最前沿的 AI 模型。Claude Fable 5 在当时是预发布版,Jarred 能拿到是因为 Bun 已经被 Anthropic 收购。普通用户当时没有这个版本。粗略估算,你今天用的 AI 编程工具跟他当时用的,推理能力可能差了一个数量级。

这四个前提缺任何一个,11 天会直接坍塌。你会面对 AI 写的看起来合理但在特定场景下崩溃的代码,花大量时间调试却找不到 root cause,最后怀疑整个方案是否可行。你会重新回到人肉重写的轨道上,但已经浪费了几周的时间。

这正是这件事最有价值的地方。它不是证明 AI 已经能替代程序员了。它是在证明:当满足这四个条件时,AI 能让一个顶级程序员的产能放大一个数量级。

这不是 AI 和人类的零和博弈。这是有 AI 的人,和没有 AI 的人,差距在被急剧拉大。

Jarred 的方法论里藏着三个可迁移的原则:把隐性知识翻译为显性规则、用信息不对称做对抗审查、修复流程而不是修复代码。这三条原则里的每一条,都不依赖 Bun、不依赖 Zig、不依赖 Anthropic。它们依赖的是一个东西:你对你的项目有足够的深度掌握。

当每一个对自己项目了如指掌的 senior engineer 都可以用类似方式把积累多年的架构直觉变成 AI 工作流时,软件工程的成本结构会变。一个人加一台 AI 能做的事情会超过一个没有 AI 的五人团队。那个用了四年的 53 万行 Zig 代码,11 天就变成了 Rust。下一次,可能不只是重写。可能是从一个代码库自动生成另一个针对不同硬件的优化版本。

这些问题还没有确定的答案。但有一件事情已经确定了。Jarred 说了一句话,值得刻在脑子里:

「"Compiler errors are a better feedback loop than a style guide."」

他不只是在说 Zig 和 Rust。当反馈闭环从代码审查加生产事故缩短到写完就报错,我们写软件的整个节奏都会改变。而当 AI 能帮你完成这种级别的转换时,谁能设计更好的反馈闭环,谁就赢。

据 Jarred 自己在 Bun 官方博客的披露,Rust 版已经合入主分支并随新版本发布,Claude Code 也以 Bun 可执行文件的形式分发给了几百万用户。这不是一篇 PR 稿——这是一个在真实项目里跑了 11 天、通过了百万断言、经历了社区误读和 6 天沉默之后被端出来的、可以被任何人复现的实验。

多留意那些能把隐性知识翻译成显性规则的人。

他们手里的 AI,和你手里的不一样。