一份重写提案如果只有旧系统和新系统两个数字,评审基本无法判断钱花得值不值。代码从 TypeScript 或 Zig 换成 Rust,进程边界、启动路径、缓存、测试和后续调优往往也一起变化。最终快了 14 倍,只能说明交付结果变快了,无法说明 Rust、AI 或架构分别贡献了多少。
对技术负责人而言,更可执行的问题是:重写前的真实瓶颈是什么,迁移过程中它移动了几次,每次移动由哪项变更触发。
本文把 2026 年 GitHub Copilot、Bun 和 Prime Agent 三个公开案例改写成一套重写评审方法。重点不是比较谁的倍数更大,而是学习怎样保留可归因的中间状态。
阅读时间: 8 分钟 | 字数: 约 2500 字
先做一张归因表,再讨论要不要重写
立项会上先要求团队填写三行,不接受把全部收益都记到新语言名下。
| 收益层 | 需要隔离的变量 | 应保留的证据 |
|---|---|---|
| 语言与运行时 | V8、GC、原生启动、静态链接、所有权检查 | 架构不变时的旧实现和新实现基线 |
| 架构边界 | 子进程、IPC、轮询、状态归属、故障隔离 | 同一实现改变边界前后的数据 |
| 验证与后续优化 | 编译反馈、差分测试、基准、Fuzz、Dogfood | 从冻结基线开始的逐次实验记录 |
这三层通常连续发生。第一次迁移可能移除运行时开销,第二次把进程外调用改为进程内,第三次才把工作移出启动关键路径。如果团队只保存最终版本,因果信息也会随旧代码一起被删除。
Prime Agent 展示了中间基线的价值
Prime Agent 的数据适合先看,因为它保留了三列:TypeScript、性能优化前的 Rust、经过三天性能爬坡后的 Rust。
| 指标 | TypeScript | Rust 优化前 | Rust 优化后 |
|---|---|---|---|
| 冷启动可输入延迟 | 736.1 ms | 293.3 ms | 51.9 ms |
| 热启动可输入延迟 | 552.3 ms | 276.7 ms | 41.4 ms |
| 10 MiB 会话内存 | 1130.0 MB | 554.9 MB | 237.3 MB |
| 安装体积 | 172.1 MB | 206.7 MB | 59.6 MB |
| Agent 视图切换 | 78.0 ms | 118.8 ms | 12.8 ms |
初始 Rust 版本让冷启动改善约 2.5 倍、内存下降约一半,同时让安装体积和视图切换变差。后续性能爬坡才把冷启动继续压到 51.9 毫秒,并修复前两项退化。
因此,最终约 14 倍对应的是一组连续动作:语言和运行时变化、架构重组、基准驱动优化。官方还说明,跨工具结果来自自建 Runtime 套件,测试排除了模型推理,也没有公共行业标准。它适合做项目内阶段比较,不能直接变成 Coding Agent 排行榜。
评审时应该复制 Prime 的三列表,而不是复制 14 倍这个标题数字。哪怕最终选择继续使用原语言,只要团队能保留迁移前、机械迁移后和显式调优后三个状态,讨论质量就会高很多。
GitHub 案例说明,进程边界可能比语言更重要
GitHub 把 Copilot Agent Runtime 迁移为超过 80 万行生产 Rust。约 14.5 周内,128 个迁移 PR 逐步进入主分支,同期发布了 135 个版本。旧 SDK 会为每个客户端启动 Node/V8 子进程,再通过 JSON-RPC 通信;新版本同时提供进程外模式和基于 C ABI 的进程内模式。
官方结构化表格中的客户端创建、会话创建和一轮交互路径为:
- TypeScript:5.25 秒;
- Rust 进程外:1.33 秒;
- Rust 进程内:292 毫秒。
从 1.33 秒到 292 毫秒的约 4.6 倍改善,更直接对应进程与 IPC 边界的移除。5.25 秒到 1.33 秒则混合了语言、运行时和迁移期间的其他代码变化,归因强度更弱。
这组测试使用本地确定性模型服务,刻意排除了模型推理和网络时间。它证明 Runtime 的启动、事件、持久化与销毁路径改善了,不能外推完整 Coding Agent 任务。官方同页另有约 55 毫秒的近似表述,现有说明不足以与结构化表对齐。稳妥做法是固定采用表格口径,同时披露差异。
GitHub 的另一项重要资产是渐进替换。每个 Rust 切片继续运行已有端到端测试,主分支保持可发布,再用真实消费者反馈发现逃逸问题。重写带来的长期收益因而包含一套更细粒度的验证和回滚路径。
Bun 是一个有用的对照组
Bun 的案例可以防止团队形成语言决定一切的错觉。一名工程师持续调度 Claude 工作流,11 天内让 CI 达到六个平台全部通过。初始机械翻译仍留下约 1.6 万个编译错误。官方统计表列出的三个代表平台,分别有 57,337、58,850 和 60,624 项测试。合并后又记录并修复了 19 个已知回归,安全审查和持续 Parser Fuzzing 继续进行。
性能变化远小于 Prime 的标题数字。官方列出的 HTTP 与应用工作负载改善为 2.2% 至 4.8%,下游 Claude Code 的 Linux 启动约改善 10%。Bun 将这组变化与 Rust 和 C/C++ 之间的跨语言链接时优化联系起来,但这不是隔离变量实验。
其他结果还要单独记账:
- 重复构建的内存泄漏改善来自明确的清理与所有权问题;
- 二进制体积下降同时包含 ICU 精简和相同代码折叠;
- 稳定性依赖借用检查器、Miri、Sanitizer、跨平台测试、对抗审查和持续 Fuzz 的组合;
- 超过 100 万行的落地 Diff 不等于最终生产代码,官方描述的 Rust 代码约为 78 万行。
Bun 证明了另一种成功:性能只小幅改善,但验证基础设施、资源清理和长期维护条件变好。这些收益值得记录,只是不能全部装进性能倍数。
编译器负责拒绝机械错误,行为 Oracle 负责验收系统
GitHub 收集到的 Rust 编译器诊断中,名称与导入、缺失方法或字段、类型不匹配和 Trait 约束四类普通连接问题占 84%。所有权、借用和生命周期错误合计只有 1.7%。编译器为 Agent 提供了高频、机器可读的拒绝信号,但 GitHub 的已知回归同样都能编译。
RustAssistant 研究给出了更清楚的边界。在 GPT-4、每次 5 个 completion 的设置下,182 个真实历史提交中有 134 个恢复可编译。对这 134 个提交的人工分类里,9 个提交改变了运行时行为。
因此,编译成功只是最内层门禁。完整行为 Oracle 至少需要五层:
- 编译器与静态分析,拒绝局部无效状态;
- 单元测试和跨平台测试,检查已知行为;
- 与旧实现的差分测试,保护迁移契约;
- 协议、轨迹、状态持久化和失败路径检查;
- 生产 Canary、Dogfood、遥测与可执行回滚。
缺少后四层时,Agent 只是在更快地产生能通过编译的候选实现。
用五本账控制重写项目
重写项目的周报可以直接改成五个账本。每项都要有旧基线、当前值、测量条件和负责人。
| 账本 | 必须记录什么 |
|---|---|
| 运行时 | 启动、稳态延迟、CPU、内存、二进制和安装体积 |
| 架构 | 进程与 IPC 边界、依赖方向、状态归属、故障隔离 |
| 状态与缓存 | 构建缓存、Prompt 缓存、检查点、仓库重新定位和重放成本 |
| 验证 | 编译拒绝、差分覆盖、Fuzz、逃逸缺陷、Canary 和回滚 |
| 总成本 | Token、算力、CI、人工指导、评审、修复和发布尾巴 |
这能避免两种常见错账。Prompt 缓存命中率解释迁移过程的 Token 经济性,无法解释产品 Runtime 性能。初始翻译耗时很短,也无法替代达到生产质量所需的后续测试、修复和发布周期。
每次有效改进后都要重新测量瓶颈。启动时间下降后,新的约束可能变成状态恢复、视图渲染、验证吞吐或人工评审。继续优化已经移除的旧瓶颈,只会增加在制品。
把发布决定拆成四道门
重写可以进入生产,至少要同时满足四项条件:
- 目标负载门: 改善发生在代表生产的工作负载,而不只发生在 Microbenchmark;
- 行为门: 关键状态、失败路径和跨平台行为有独立于新实现的等价证据;
- 成本门: 迁移、验证、人工指导和后续维护成本都进入总账;
- 约束门: 新架构确实移除了生产中的真实约束,并能说明下一个瓶颈在哪里。
任何一门缺证据,都应继续小范围迁移或停留在实验状态。最终倍数可以作为结果摘要,不能替代这四项验收。
三个常见判断
Rust 是否天然适合 AI 写代码?
Rust 提供严格类型、所有权检查和高质量诊断,能显著改善 Agent 的内循环。GitHub 数据也显示,大部分被拒绝的问题属于各种静态类型语言都会发现的连接错误。具体项目仍要看行为 Oracle、跨平台成本、Interop 和团队维护能力。
Prime Agent 的 14 倍能否用来预测自己的重写?
不能。它来自指定版本、自建基准和一次语言迁移加架构优化的连续过程。可复用的是三阶段测量设计,不是 14 倍这一结果。
什么时候应该停止重写?
当代表生产的瓶颈没有继续移动,新增收益低于验证和维护成本,或者行为等价证据无法覆盖关键风险时,就应停止扩大迁移范围。重写的完成标准是可验证地移除约束,而不是把旧语言代码全部删完。