编程 AI 为 Bun 做了"换心手术":从 Zig 到 Rust 的 96 万行代码迁移深度拆解

2026-07-17 13:44:16 +0800 CST views 10

AI 为 Bun 做了"换心手术":从 Zig 到 Rust 的 96 万行代码迁移深度拆解

2026年5月,编程界上演了一出让无数工程师脊背发凉的戏码——Bun,这个曾以 Zig 语言为傲的 JavaScript 运行时,在短短 6 天内,由被它拖累的 Claude AI 亲手把自己从 Zig 重写成了 Rust。**96 万行代码,99.8% 测试通过率,6755 次提交,几乎全部由 AI 完成。**这件事的荒诞之处在于:创造者用一条推文宣告了亲手养大的孩子(Zig 版本)的死亡,然后让 AI 在不到一周内再造一个全新的版本。

这不是一次普通的技术迁移。这是一场关于 AI 编程能力边界的公开实验,也是一面照出"测试通过率不等于安全"这一被忽视真相的镜子。

本文将深入拆解这次迁移的技术细节、背后的 Claude Code 动态工作流工程体系、迁移策略的深层逻辑、unsafe 代码块的争议,以及这场实验对整个软件工程行业的深远影响。


一、背景:为什么是 Bun,为什么是现在

1.1 Bun 的诞生与 Zig 之选

Bun 由前 Node.js 核心贡献者 Jarred Sumner 于 2022 年创建,定位是"All-in-One"的 JavaScript 工具链——集运行时、打包器、测试运行器和包管理器于一身。选择 Zig 而非 C/C++ 作为底层实现语言,是 Bun 早期最大的技术标签之一。

Zig 以"没有隐藏控制流、没有隐式内存分配、没有宏 magic"著称,其编译期执行(comptime)特性让 Bun 能够实现极致性能优化。Benchmark 数据亮眼:Bun 的启动时间约 3ms,比 Node.js 快 4 倍,比 Python 快 15 倍;HTTP 服务器吞吐量是 Node.js 的 4 倍

然而,Zig 的代价也在累积。

1.2 暗疾缠身的 Zig 版 Bun

内存泄漏问题是压垮骆驼的第一根稻草。

2026年3月,GitHub Issue #33453 记录了 Claude Code 主进程的严重内存泄漏:运行 3 小时后,RSS 内存从约 1.7GB 膨胀到 14GB 以上。另一份 Issue #11377 更夸张——运行 14 小时后,进程占用 23GB 虚拟内存,CPU 占用 143.8%,最终系统卡死。

问题的根源在于 Bun 运行时依赖的 WebKit Malloc 分配器与 Zig 代码中手动内存管理之间的交互。Jarred Sumner 本人也曾公开表示:"花了大量时间调试内存相关问题,厌倦了。"

1.3 Anthropic 收购:Bun 成为 Claude Code 的"心脏"

2025年12月,Anthropic 收购 Bun,意图明确——让 Bun 成为 Claude Code 的底层运行时。Bun 极快的启动速度和 JavaScript 工具链能力,正是 AI 编程助手密集启动子进程场景下的最优解。

但讽刺的是,Bun 自身的内存问题正好影响了它的最大客户。Claude Code 每启动一次子进程执行命令,就触发一次 Bun runtime 的加载——一个内存泄漏的 runtime,在高频 AI 交互场景下会快速膨胀到系统崩溃。

这形成了一个技术债务的死结:Anthropic 越依赖 Bun,Bun 的内存问题就越致命;越想修 Zig 的内存问题,越感觉是在填一个无底洞。

1.4 Zig 社区的"no-AI policy":哲学上的决裂

更深层的裂痕在于价值观冲突。Bun 团队曾 fork Zig 并做了大量私有优化,但无法 upstream 回 Zig 官方——因为 Zig 社区有严格的 "no-AI policy",禁止 AI 生成 issue 和 PR。这一政策与 Anthropic 的 AI-first 战略完全对立。

2026年5月11日,Jarred Sumner 在 X 上发推:

"Bun v1.3.14 将于明日发布。如果我们合并 Rust 重写版本,这将是 Zig 的最后一个版本。"

四年之路,一朝终结。


二、技术拆解:Claude Code 是如何完成这次迁移的

2.1 动态工作流(Dynamic Workflow)工程体系

这次迁移的核心工程支撑是 Anthropic 的 Claude Code 动态工作流(Dynamic Workflow)系统。这是一个将大语言模型嵌入可编程执行环境的新型 AI 工程范式,与传统对话式代码生成有本质区别:

维度对话式代码生成动态工作流
状态管理每个会话独立,无跨会话上下文任务状态持久化,可中断/恢复
并行能力单会话串行64 个 Agent 并行分布式执行
验证闭环手动验证自动触发测试,自动分析失败原因
决策能力被动响应 prompt主动规划、子任务分解、自主决策
规模上限约 5000-10000 行/会话无理论上限制,线性扩展

动态工作流的核心运行机制如下:

Phase A (Port) → Phase B (Build/Cyclebreak) → Phase C (Panic Fix) → 
Phase D (Blocked Resolve) → Phase E (Tier) → Phase F (Cycle Fix) → 
Phase G (Fill) → Phase H (Verification)

每个 Phase 又细分为多个子工作流(workflow),例如:

  • phase-b0-cyclebreak.workflow.js — 打破编译循环依赖
  • phase-b1-tier.workflow.js — 按依赖层级推进迁移
  • phase-c-panic-swarm.workflow.js — 并行修复 panic 错误
  • phase-d-blocked-on-resolve.workflow.js — 解除文件间相互依赖的阻塞

2.2 Zig-to-Rust 迁移的技术策略

迁移团队发布了一份 576 行的 Zig-to-Rust 迁移指南,确立了核心策略:逐文件忠实翻译(Literal Translation)

这一策略的具体含义是:

// Zig 原代码(Bun 的 HTTP 实现片段)
const std = @import("std");
const http = @import("http.zig");

pub fn serve(allocator: std.mem.Allocator, port: u16) !void {
    var server = try http.Server.init(allocator, port);
    defer server.deinit();
    try server.listen();
}

Claude Code 被要求将上述 Zig 代码忠实地翻译为 Rust,而不是重新设计架构:

// Rust 翻译版本
use std::alloc::{Allocator, Global};
use http::Server;

pub fn serve(allocator: impl Allocator, port: u16) Result<(), Box<dyn Error>> {
    let mut server = Server::init(allocator, port)?;
    defer!(server.deinit()); // defer 宏模拟
    server.listen()?;
    Ok(())
}

忠实翻译 vs. 惯用 Rust 写法的区别至关重要:

  • 忠实翻译:逐行转换 Zig 语法到 Rust 语法,保持相同的控制流和数据结构,使用 unsafe 绕过借用检查器的限制。产出快,但本质是"披着 Rust 外衣的手动内存管理"。
  • 惯用 Rust 写法:用 Rust 的所有权/生命周期系统重新设计数据结构,利用 VecBoxArc 等智能指针替代手动内存管理,真正发挥 Rust 的内存安全优势。需要更多人工介入和设计决策。

Claude Code 在无额外约束的情况下,默认选择了忠实翻译策略——因为这是 LLM 在无显式限制时最容易、最快速产出的结果。

2.3 迁移时间线:从"根本跑不起来"到"Zig 的最后一个版本"

时间节点里程碑
2026年5月初claude/phase-a-port 分支建立,数十万行 AI 生成的 Rust 代码出现
2026年5月7日~4000 次 commit、96 万行代码,只剩 3 个编译错误;help menu 可显示,bun run 可执行 JS
2026年5月9日Linux x64 glibc 下测试套件通过 99.8%
2026年5月10日向 Rust 社区请教底层问题,底层架构未完全稳定
2026年5月11日Jarred 宣告 Zig 版本终结
2026年5月14日PR #30412 合并:超过 100 万行 Rust 代码、6755 次 commit

值得玩味的是,Jarred 在 5 月 5 日还在 Hacker News 上说"这些代码根本还跑不起来,最后被全部扔掉的概率非常高"。六天后,同一批代码变成了"Zig 的最后一个版本"。


三、争议焦点:99.8% 测试通过率背后的 unsafe 深渊

3.1 数据对比:uv vs. Bun Rust

迁移完成后,开发者 Theodore(t3dotgg)对两个 Rust 项目做了令人不安的对比:

指标uv(Astral 公司,Python 打包器)Bun Rust 版本
代码行数~35 万行~68.1 万行
unsafe 代码块数73 个超 13,000 个
生成方式人工编写,经代码审查AI 生成、AI 审查、AI 合并
人均 unsafe极低~1.7 unsafe/文件

Rust 生态中另一个著名项目 rusqlite(SQLite 绑定)约 2 万行代码,只有约 50 个 unsafe 调用。Bun Rust 版本的 unsafe 密度是正常 Rust 项目的 2 个数量级以上

3.2 为什么 unsafe 这么多:技术根因分析

unsafe 在 Rust 中允许绕过借用检查器的限制,直接操作原始指针、调用不安全函数、访问可变静态变量。Bun 迁移中大量出现 unsafe 的直接原因是:

原因一:Zig 的手写内存管理模型无法直接映射到 Rust 安全模型

Zig 代码中大量使用显式 allocator 参数进行手写内存管理:

// Zig 风格:所有内存操作显式传 allocator
const buf = try allocator.alloc(u8, size);
defer allocator.free(buf);

直译到 Rust 时,如果不重新设计架构,就必须用 unsafe 包装这些操作:

// 直译风格:unsafe 无法避免
unsafe {
    let layout = Layout::from_size_align_alignment(size, align);
    let ptr = alloc(layout) as *mut u8;
    (*ptr).write_bytes(0, size);
}

原因二:借用检查器无法跨越语言边界工作

Zig 代码中的大量全局状态、单例模式、直接内存地址操作,翻译到 Rust 时如果保持相同的架构设计,就会在 Rust 的借用检查器下产生大量"不满足生命周期要求"的冲突。使用 unsafe 是绕过这些限制的最快路径。

原因三:迁移指南的约束条件

迁移指南要求"保持相同架构、数据结构",而非"重新设计为惯用 Rust"。这一约束条件直接锁定了 Claude Code 的探索空间。

3.3 unsafe 的危险性:不是数字游戏

unsafe 代码在 Rust 中的危险性被很多开发者低估。以下是核心风险:

// 示例:一个看似无害的 unsafe 块
unsafe {
    let ptr = some_raw_pointer();
    (*ptr).field = value;  // 如果 ptr 是悬空指针,这里就是未定义行为
}

关键问题:一个 unsafe 代码块中的错误,可以让周围所有依赖 Rust 类型系统保护的代码瞬间失去安全保障。未定义行为不会温和地崩溃——它可能被编译器优化掉、被安全代码当作"正常结果"接受,或者以完全无法预测的方式表现出来。

历史数据:即便是 Rust 标准库本身,过去也曾出现 20+ 个可追溯到 unsafe 代码的 CVE 漏洞。标准库的 unsafe 代码由 Rust 核心团队人工编写、严格审查——即便如此也无法完全避免问题。

Amazon + Rust 基金会的验证项目:2025年,Amazon 联合 Rust 基金会发起了对 Rust 标准库 unsafe 代码的形式化验证项目。这个项目规模远小于 Bun(仅聚焦标准库本身),但仍需要大量人力和形式化规范工具。

Bun 的 unsafe 代码规模:700+ 文件、10,000+ 个 unsafe 块,即便每个块的平均复杂度远低于标准库,总体验证工程量也远超当前学术界形式化验证能力的上限。

3.4 99.8% 与 10,000 个 unsafe:为什么两者同时成立

这是本次事件中最具教育意义的技术矛盾:

99.8% 测试通过率衡量的是:新实现对外暴露的行为与旧实现是否一致

10,000+ unsafe 代码块反映的是:新实现的内部实现方式是否安全

这两个指标描述的是代码质量的不同维度,完全不矛盾

  • 测试通过率高 → 行为一致性好 → 迁移忠实度合格 ✓
  • unsafe 数量多 → 内部安全性差 → Rust 惯用性不合格 ✗

"行为一致性"可以通过大量测试验证;但"内部安全性"需要逐个审查 unsafe 块——这是测试套件无法测量的属性。

核心教训:当有人用测试通过率来证明某种安全属性时,首先应确认测试套件是否真的在测量那个属性。行为一致性和内存安全性是两个完全不同的维度。


四、Claude Code 动态工作流的技术架构解析

4.1 工作流设计哲学

Claude Code 动态工作流的设计哲学是:将工程决策结构化为带置信度的输出

传统 AI 编程范式中,AI 是被动的响应者——人类写 prompt,AI 产代码,无法处理需要跨文件理解、依赖分析和迭代验证的复杂工程任务。

动态工作流则将 AI 提升为工程决策的接管者。工作流引擎维护任务状态图,每个节点是一个可执行的子任务,AI Agent 根据当前状态自主决定下一步行动,并持续将结果反馈到状态图。

4.2 多 Agent 并行架构

Bun 迁移中使用了 64 个 Claude 实例并行运行,这意味着:

64 个 Agent  ×  24 小时/天  ×  6-11 天  =  ~9,000-16,000 Agent-hours

每个 Agent 有独立的上下文窗口和工具调用能力,可以:

  • 读取和修改源文件
  • 运行编译器获取错误信息
  • 执行测试套件验证结果
  • 分析编译错误并自主修复
  • 向其他 Agent 提交 PR/MR

4.3 关键工作流详解

Phase B: 打破循环依赖(Circular Dependency Resolution)

Zig 代码中大量文件间存在相互依赖。在逐文件迁移时,如果 A.zig 依赖 B.zig 但 B.zig 也依赖 A.zig,迁移就会陷入死锁。

Claude Code 的策略是:

  1. 先用桩代码(stub)填充所有文件,使编译通过
  2. 按依赖层级从叶子节点向上逐层实现
  3. 循环依赖处插入 trait object 或 dynamic dispatch 打破静态依赖

Phase C: Panic 修复并行化

Rust 编译器在遇到 panic(未捕获异常)时会中止整个编译过程。在迁移初期,大量 Zig 代码的 panic 模式无法直接映射到 Rust,Claude Code 以并行 swarm 模式同时处理数千个 panic 修复。

Phase H: 跨平台验证

Rust 版本最初只验证了 Linux x64 glibc 平台。后续工作流(phase-h-windows-testfix.workflow.js)专门处理 Windows/macOS/musl 跨平台兼容性问题。

4.4 成本分析

据 Jarred Sumner 披露:

指标数值
API 费用约 16.5 万美元
耗时约 11 天(最终合并)/ 6 天(首次可运行)
并行 Agent 数最多 64 个
总代码量~100 万行 Rust

对比人工重写:同等规模的团队人工迁移预计需要 1 年时间。AI 方案的成本约是人工的 1/300(按 16.5 万美元 vs. 1 年团队工资)。


五、性能影响:Rust 重写后 Bun 变快了还是变慢了

5.1 基准测试结果

从已公布的数据来看:

指标Zig 版 BunRust 版 Bun变化
HTTP 吞吐量基准持平或略高
启动时间~3ms~3ms
二进制体积(Linux x64)~93MB缩小数 MB
内存占用不稳定(泄漏)更稳定↑ 稳定性
编译时间较短较长

Rust 版本在性能上没有明显倒退,在稳定性上有改善。但这并不是因为 Rust 本身带来了性能提升,而是因为 Rust 重写过程中:

  1. 去掉了一些 Zig 特有的 hacky 实现
  2. 利用 Rust 的 std 库替代了部分手写代码
  3. 编译器优化在 Rust 层面上更可预测

5.2 编译时间的代价

Rust 的慢编译速度是出了名的。Bun 的完整 Rust 编译在 M2 Max MacBook Pro 上需要 约 7 分钟(相比 Zig 版本的分钟级别)。这对于 CI/CD 流程和开发体验都有影响。

# 编译时间对比(Linux x64 release build)
Zig 版 Bun:  ~45 秒
Rust 版 Bun: ~4-7 分钟

不过 Rust 的增量编译优化正在快速进步,这一差距有望缩小。


六、软件开发范式的转折点:这次迁移告诉行业什么

6.1 AI 能做什么 vs. AI 应该做什么

这次迁移清晰地划出了边界:

AI 擅长(已被验证)

  • 语法层面的语言间翻译(Zig → Rust)
  • 大规模重复性代码生成
  • 编译错误自动修复
  • 测试用例批量生成
  • 依赖关系图的自动化分析

AI 难以胜任(仍在探索)

  • 架构级别的重新设计(忠实翻译 ≠ 优化设计)
  • 安全性属性的形式化验证
  • unsafe 代码的逐块安全审查
  • 边界条件和未定义行为的系统化识别

6.2 "代码生成速度 > 代码审查速度"的新难题

Hacker News 上获得 708 热度的一个讨论帖指出:

"一个 Agent 在 9 天内生成的 100 万行代码,到底是谁审核的?"

答案是:没有人以审查关键基础设施代码应有的方式去完整阅读它。按照代码生成速度阅读这些代码,不是人类能够做到的事情。

这引出了一个全新的工程验证问题:

传统模式:代码生成速度 << 代码审查速度
AI 模式:代码生成速度 >> 代码审查速度(10-100x)
验证需求:必须有自动化工具填补这一差距

6.3 正确使用 AI 重写的工程方法论

Todd Smith(开发者社区的重要声音)提出的方法论值得参考:

Phase 1:编写外部行为规范

# Bun HTTP Server 外部行为规范(示例)
1. 监听指定端口,接受 TCP 连接
2. 解析 HTTP/1.1 请求行和头部
3. 对有效请求返回 200 + 指定 body
4. 对无效请求返回 400
5. Connection: close 情况下主动关闭连接
6. 超时设置:读取头部 30s,读取 body 60s

Phase 2:迁移时禁止 unsafe(Git pre-commit hook)

#!/bin/bash
# pre-commit hook: 检查新增的 unsafe 代码
rust_files=$(git diff --name-only --diff-filter=ACM | grep '\.rs$')
for file in $rust_files; do
    unsafe_count=$(git diff -- "$file" | grep -c 'unsafe' || true)
    if [ "$unsafe_count" -gt 0 ]; then
        echo "Error: New unsafe blocks in $file. Rewrite using safe Rust patterns."
        exit 1
    fi
done

Phase 3:规范 + AI 协同
将规范作为主要依据,现有 Zig 代码作为参考资料。Claude Code 看到"禁止 unsafe"的约束后,会被迫寻找真正的内存安全实现方式——但仍需要大量人工审查来验证安全性。

6.4 行业影响:AI 重写软件的临界点已至

2026年,Bun 并不是孤例:

项目时间规模AI 工具
Cloudflare Next.js API 重新实现1 周中等Claude Code
Ladybird JS 引擎 C++→Rust2 周大型AI Agents
Bun Zig → Rust6-11 天96 万行Claude Code
C 编译器(Rust 实现)2 周10 万行16× Claude Opus 4.6

Jarred Sumner 预言的开源软件未来——"禁止人类贡献代码"——正在以另一种形式到来:不是禁止人类写代码,而是让 AI 重写成为解决历史债务的默认手段。


七、安全审视:现在应该信任 Bun Rust 版本吗

7.1 理性评估:不恐慌,不轻视

不恐慌的理由

  • 99.8% 测试通过率意味着日常场景下行为稳定
  • 许多大型 Rust 项目(包括 Linux 内核的 Rust 部分)也使用大量 unsafe
  • 绝大多数用户不会触发 unsafe 相关的边缘路径
  • 未定义行为不一定会被主动利用

不轻视的理由

  • unsafe 代码中的内存安全漏洞可能多年不暴露(CVE 潜伏期长)
  • musl libc 等非主流 libc 环境未充分测试
  • 边缘平台(ARM32、RISC-V)测试覆盖有限
  • 随着 Bun 服务于 Claude Code 的百万用户,攻击面在扩大

7.2 当前状态与后续工作

截至 2026年7月,Bun Rust 版本的状态:

  • Canary 渠道已发布(供早期测试)
  • 主线分支已合并但仍在高频修复
  • unsafe 数量已从 ~13,000 降至约 ~11,000(仍有大量工作要做)
  • 多平台支持(Windows、macOS ARM/musl)仍在完善中

Bun 团队未来需要:

  1. 逐步将 unsafe 代码替换为安全的 Rust 惯用写法
  2. 引入 Miri(Rust 的 undefined behavior 检测器)进行静态分析
  3. 为核心路径(HTTP 解析、文件系统操作)编写内存安全证明
  4. 建立 unsafe 代码块的注册表和审查流程

八、结语:工具无罪,使用者有责

Bun 事件给软件行业留下的最重要教训,不是"AI 能重写百万行代码",而是:

AI 是强大的工具,但它不会主动为你的安全承诺负责。

Rust 版 Bun 有 10,000+ 个 unsafe,不是因为 Claude Code 不能写安全的代码——而是因为没有人告诉它必须写安全的代码。当"忠实翻译 Zig"成为迁移目标时,AI 忠实地实现了这个目标,只是这个目标本身并不等于"内存安全"。

软件开发者的新职责:在 AI 编程时代,理解工具的能力边界,比任何时候都更重要。知道什么时候该约束 AI("禁止 unsafe"),什么时候该引导 AI(提供规范而非现有代码),什么时候该取代 AI(人工审查 unsafe 块)——这些决策的价值正在飞速上升。

Bun 的 Rust 版本最终会成为什么样?乐观地看,这是一次被大胆执行的激进实验,过程中暴露的问题会推动整个行业建立更好的 AI 代码验证工具链。悲观地看,我们可能正在用 AI 加速生产一种新型的技术债务——只是债务的形态从"老旧的 C 代码"变成了"无法审查的 AI 生成代码"。

时间会给出答案。但在答案揭晓之前,我们至少应该清楚地知道自己在做什么。


选题来源:AI技术突破 2026 | Bun Zig Rust迁移
字数:约 12,800 字
标签:AI编程|Claude Code|Bun|Zig|Rust|代码迁移|unsafe|动态工作流|系统编程

推荐文章

php腾讯云发送短信
2024-11-18 13:50:11 +0800 CST
2024年公司官方网站建设费用解析
2024-11-18 20:21:19 +0800 CST
浏览器自动播放策略
2024-11-19 08:54:41 +0800 CST
PHP 代码功能与使用说明
2024-11-18 23:08:44 +0800 CST
智能视频墙
2025-02-22 11:21:29 +0800 CST
程序员茄子在线接单