一件反直觉的工程事件

9 月 16 日,GitHub 在官方博客上发了一篇复盘,讲他们怎么把 Copilot 的智能体运行时整体改写成 Rust。规模是 80 万行上下的生产代码,耗时约 14.5 周,过程中合入 128 个拉取请求。

传播最广的角度是「用 Copilot 重写了 Copilot 自己」。这个说法不算错,但容易盖住真正有价值的部分:他们是怎么在不停机的前提下换掉自己大脑的,以及这份复盘里哪些数字经得起追问。

先把背景补齐。这个运行时不是一个窄组件,而是 Copilot 命令行工具、Copilot 应用与 Copilot SDK 共同的底座。用 GitHub 自己的话说,VS Code、Visual Studio、Copilot 代码评审、Copilot 协作、Copilot Studio,还有表格、邮件与演示文稿里的 Copilot 支持,架构上都是「同一套运行时加各自的定制外壳」。这些产品早期各自实现过自己的智能体循环,后来陆续换成统一的 SDK。

问题出在被共享的东西本身。原先整套栈用 TypeScript,Node.js 做框架、V8 做执行引擎,界面层用 Ink 与 React。对命令行工具来说,这是合理选择;但 SDK 把命令行工具当成宿主进程——每建一个客户端就新起一个进程,再通过 JSON-RPC 跨进程通信,单客户端工作集内存因此多出约 100MB。启动速度、吞吐与服务器密度都受牵连。事后复盘里有一句坦白的描述:命令行工具当初写得很快,界面与运行时缠在一起,没有拆成独立的层;等到需要 SDK 时,又反过来把 SDK 叠在命令行工具之上。

拆开之后,性能差了多少

来源:GitHub Blog 复盘 · 本地端到端测试,已排除模型推理与网络延迟指标迁移前 TS/NodeRust 进程外Rust 进程内建客户端→会话→一轮→销毁(秒)5.251.330.292吞吐(会话/秒,1000 会话)7.5557.45120十客户端额外内存(MB)1383247126运行时与终端界面分层:既可走 C 应用二进制接口在进程内调用,也可走原有 JSON-RPC 服务器进程外调用。SDK 现支持 TypeScript、Python、Go、C 井号、Java 与 Rust。
这组数字衡量的是运行时外壳的开销,不是用户感知的完整问答耗时——测试已排除模型推理与网络延迟。

GitHub 给出的对照是本地端到端测试,并且明确排除了模型推理与网络延迟这两项。也就是说,这组数字衡量的是「运行时外壳」的开销,不是用户感知的完整问答耗时。

建客户端、开会话、跑完一轮、再销毁,这条完整生命周期的耗时从 5.25 秒降到进程外的 1.33 秒与进程内的 292 毫秒。一千个会话的生命周期测试里,吞吐从每秒 7.55 个会话升到进程外 57.45、进程内 120。十个客户端并发带来的额外内存,从 1383 兆降到 247 兆与 126 兆。

重写后的运行时与终端界面分了家,以原生二进制形式暴露:既可以走 C 应用二进制接口在进程内调用,也可以继续走原来的 JSON-RPC 服务器进程外调用。SDK 现在支持 TypeScript、Python、Go、C 井号、Java 与 Rust,各自用自己的外部函数接口访问同一份运行时。

这里有个容易被忽略的细节:进程内比进程外又快了约四倍。这个差距本身就说明跨进程通信的开销有多大——它不只是「慢一点」,而是在高频短会话的场景里直接决定了架构选择。

同一件事,三种数字

代码行数是变量,口径也要对齐80 万行GitHub 官方博客口径:超过 80 万行生产 Rust约 83 万行部分技术拆解文章沿用的近似值832378 行一份中文复盘给出的精确值,并配 469000 行 Rust 单测、TypeScript 生产代码归零配套数字:约 1363 亿 token、约 12 万美元模型费用,其中缓存输入 1306 亿 token。
三个值并不互相矛盾——官方给的是取整下限,精确值更像仓库统计结果。看到「N 万行」先问统计的是哪个仓库、哪个层次。

代码规模这件事,不同来源给了三个值。GitHub 博客自己写的是「超过 80 万行生产 Rust」;一篇技术拆解文章给到约 83 万行;一份中文复盘给出了精确到个位的 832378,并同时给出 469000 行 Rust 单元测试、TypeScript 生产代码归零这两个配套数字。

这几个数并不冲突——官方给的是取整下限,832378 更可能是仓库统计的真实值。但它们指向同一个提醒:看到「N 万行」时,先确认说的是哪个仓库、哪个层次、统计口径是物理行还是逻辑行。

成本和耗材一侧,一家印度科技媒体的报道给出了约 1363 亿 token、约 12 万美元模型费用,其中缓存输入 1306 亿 token;子智能体里用得最多的模型包括若干 Claude 与 GPT 系列版本。另一家媒体则明确写了「GitHub 没有披露项目时间线、团队规模、成本数字,也没有说明用的是哪个模型配置」。这两句可以同时成立:前者引用的是第三方补充的细节,后者说的是官方博客本身的克制。读到具体成本时,值得先看它出自哪一侧。

还有一条细节值得记:GitHub 说主导这件事的开发者大约只投入了三周时间,其余工程师补的是互通性、打包、构建性能与评审。

「让一整类项目变得可行」这句话怎么读

复盘里被引用最多的一句来自微软的一位杰出工程师。他说自己并没有简单地让智能体「把整个代码库从 TypeScript 移植到 Rust」,并补了一句:即使行业正朝那个方向走,现在也还远没到。他的另一个短句被多家媒体转述成标题——移植代码很容易,把它做对很难。

这个区分是全文最实用的部分。主导者大部分时间花在评审改动、测试行为、质疑设计决策、检查完整性上,而不是下达最初的编码指令。也就是说,智能体承担的是机械翻译层——模式匹配、样板生成、接口面复制——而架构、正确性与性能验证仍留在人手里。

所以「让项目变得可行」的准确含义,是让一类过去因为成本与风险被长期搁置的迁移变得可以排期,而不是让工程判断消失。这两件事的差别,恰好是能不能把它抄回自己团队的关键。

回归与质量:一个容易被略过的数字

迁移过程报告了数十处回归,类型包括不完整的移植、被改变的行为契约、状态与生命周期错误、宿主平台要求、库差异与变基冲突。

值得注意的是这批问题存在——大规模重写必然有——而是公共质量问题占比在迁移期间与之后保持在 23.7%,而迁移之前是 22.9%。换句话说,在换掉整个运行时底座的同时,对外可见的质量水平没有出现明显恶化。

这个数字比任何性能倍数都更能说明「增量上线」策略的价值:128 个拉取请求分步合入主线并随常规发布上线,新代码从很早就在真实流量里被检验,而不是憋到最后一次性切换。对多数团队来说,这是可以照搬的那一条。

可以带走的四条

其一,用「分步合入加常规发布」代替「一次性切换」。这是不停机的来源,也是回归能被及时发现的原因。

其二,把智能体限定在翻译与样板层,把设计与验证留给人。这条比任何提示词技巧都重要。

其三,先补测试再迁移。四十多万行 Rust 单测不是开销,而是让机器生成的移植代码可以上线的安全网。

其四,看到规模数字先问口径。同一个项目可以同时是 80 万行、83 万行和 832378 行。

需要标注的边界

其一,GitHub 既是工具供应方又是这个案例的客户方,有直接动机展示智能体在自家艰巨任务上的表现。这一点值得在阅读时放在心里。

其二,官方博客没有公布缺陷率、评审开销与性能提升的完整对照方法,也没有说明 80 万行里机器生成与人工编写各占多少。已有第三方媒体明确指出了这些缺口。

其三,性能数字来自排除模型推理与网络延迟的本地端到端测试,不能直接外推成用户感知的响应改善。

其四,这是一个关于「迁移」的案例,不是关于「从零构建」的案例。原代码库存在本身,为智能体提供了可对照的语义与行为契约;从零开始的项目没有这层参照。

目前官方及行业暂未披露更多细节,后续将持续跟进迭代动态。