本文永久链接 – https://tonybai.com/2026/09/25/github-copilot-runtime-rust-rewrite-agent-coding
大家好,我是Tony Bai。
【导读】
TypeScript写了三年多的Copilot运行时,被一个人用Copilot在三个月内重写成了83万行Rust代码——这事儿要是放在两年前,没人敢立项。GitHub工程师Stephen Toub把整个过程摊开来讲:为什么必须离开Node.js和V8,为什么选择“原地迁移”而不是“大爆炸式重写”,128个PR是怎么排兵布阵的,Agent会话之间怎么互相“抢地盘”,代码里158处unsafe都用在哪,踩过的十几类回归坑长什么样,以及——这一切到底花了多少钱、换来了多大的性能提升。这是目前为止最详细的一份“Agent到底怎么干重活”的一线记录。
【文章重点】
- 规模:Copilot Agent Runtime初始估算约13万行TypeScript,实际迁移期间吞吐了约43万行TypeScript 和约120万行Rust ,最终落地83.2万行生产Rust代码,外加46.9万行Rust单元测试
- 人力:项目主力只有一名工程师,历时约14周,折合全职投入约3周(按PR占比估算),而不是过去需要的一整个团队、一到两年
- 成本:token总花费约1363亿,折合约12万美元
- 性能:进程内(in-process)调用下,单次“创建客户端—开会话—走一轮对话—销毁”的延迟从5.25秒降到292毫秒,提升约18倍;十客户端并发场景下的内存占用从1383MB降到126MB,降了约91%
- 质量:迁移期间GitHub公开仓库里“质量相关”issue占比几乎没有变化,说明这场大规模重写没有带来明显的用户可感知质量下滑
- 反直觉发现:Rust编译器帮Agent挡住的错误里,84%都是命名解析、方法缺失、类型不匹配这类“任何强类型语言都能挡住”的低级问题,真正Rust特有的借用/生命周期问题只占1.7%

规模有多夸张
驱动GitHub Copilot CLI、Copilot App、Copilot SDK的核心引擎——Copilot Agent Runtime,最早用TypeScript写在Node.js和V8上。现在,它被完全重写成了超过80万行生产Rust代码,主力是AI Agent,横跨128个合入主干的PR,边写边发布,没有等最后一次“大切换”。这件事放在过去需要一整个团队干一到两年,这次主要由一名工程师在几个月内完成,团队其余人照常在扩展功能。
为什么非换语言不可
Copilot Agent Runtime支撑着一大批产品:CLI、App、VS Code、Visual Studio、CCA、Copilot Code Review、Copilot Cowork,甚至Excel、Outlook、Word。这些产品都不想自己重新实现一套生产级Agent框架,而是通过Copilot SDK统一接入。
问题出在架构上:CLI最初是TUI叠加在Agent循环上,两者耦合在一起。后来做SDK时,只能把它“反常识”地叠在CLI之上——CLI改造出headless模式,SDK通过JSON-RPC协议拉起一个CLI子进程来通信:
const client = new CopilotClient();
await client.start(); // 会拉起一个CLI子进程
这意味着每个SDK消费者(不管用C#、Python、Go、Java还是Rust)都要背负一整套Node.js+V8运行时(至少约100MB内存开销),要忍受进程间通信的延迟,Node一崩溃会话就没了,部署方还要多监督一个进程。
团队想要的是:不含TUI、依赖极简、能被进程内嵌入、性能顶级、对六种语言都友好、供应链更安全。综合考量后选择了Rust——这不代表所有TypeScript项目都该改写Rust,而是这次的诉求(C ABI嵌入、低开销、可预测的资源占用)恰好和Rust的能力匹配,代价是要显式管理生命周期(后文的回归问题正说明了这一点)。

原地迁移,而不是大爆炸
重写有两条路:大爆炸式(另起分支写完整替代品,最后一次性切换)和原地迁移(组件级逐个原子替换,边删旧代码边上新代码)。团队选了后者,理由很实在:主干随时可发布、没人被迫停工、diff规模可控便于评审、全部E2E测试全程针对新代码跑。像会话编排这种持有可变状态、双向回调、贯穿全系统的组件,本来就不是能“A/B热切换”的纯函数,硬要维护两个并行版本比迁移本身还危险。
起步阶段先花两个PR搭好Rust工具链、CI和编码规范,再用几个无副作用的helper函数走通全流程,把“仓库结构、FFI、打包、测试”沉淀成后续大规模迁移的固定套路。顺序是从叶子到核心:纯逻辑→有状态子系统→工具/hooks/模型客户端/MCP→最耦合的session.ts留到最后。
到8月21日,运行时100%变成Rust:83.2万行生产代码+46.9万行单测。约14.5周窗口期共发布135个版本,平均每天1.3次。
Interop怎么搭桥
迁移中有两层互操作。
临时层:每迁移一个函数,就靠napi(napi-rs)自动生成胶水代码,让Rust和TypeScript互相调用;这层胶水在8月3日达到峰值(2019个内部导出、3356个调用点),迁移完成后归零。
永久层:编译出的runtime.node本质是个共享库,同时开两扇门——一扇给Node走的napi门,一扇是任何语言都能通过FFI加载的C ABI门(只有19个导出函数,背后却挂着364条调度路由)。有意思的是,进程内调用依然保留了JSON-RPC这套协议——因为每个SDK本来就有一套能跑的JSON-RPC客户端,把FFI挂载为新的传输方式,只是把字节路径从管道换成函数调用,上层代码完全不用改。代价是仍要承担一点序列化开销,但相比模型推理的往返时间基本可忽略。
| SDK | 桥接方式 |
|---|---|
| C# | P/Invoke |
| Go | purego |
| Java | JNA |
| Python | cffi |
| Rust | libloading |
| TypeScript | koffi |
Agent到底在干什么
缓存命中率96.22%:Agent循环刻意保持一段又长又稳定的前缀,每轮只追加内容,这是长时间自主运行经济账能算过来的关键(缓存命中价格往往打1折)。
压缩5116次没丢线索:会话填满上下文时会自动压缩自身。作者对比压缩前后各20次工具调用,发现探索/编辑/验证的比例几乎没变化——没有出现“压缩后疯狂重新定位”的迹象。
静态分析确实有用,但功劳不该只记在Rust头上:8678次rustc报错中,84%是命名解析、方法缺失、类型不匹配、trait约束这四类“接线错误”——任何强类型语言的编译器都能挡住。真正Rust特有的借用/生命周期问题只占1.7%,是全场最安静的部分。
Agent更爱读,不爱写:文件读取/搜索类工具调用量是编辑类的10倍,“AI疯狂吐代码”的印象其实是反的,实际更像反复的“查现状-提假设-小改动”循环。
多会话协作:从有序分工到“AI互抢代码”
GitHub Copilot App支持会话之间互相创建、互相发消息,每个会话独立worktree、独立分支。最难啃的session.ts(约3万行、贯穿全系统)就是这么拿下的:父会话先花56分钟阅读、122次工具调用后才开始拆解,随后7波创建了15个子会话并行迁移,自己负责协调和最后的cherry-pick合并。

最戏剧性的一幕:作者同时启动了session.ts迁移会话和“入口函数”迁移会话,并告诉后者“到session.ts边界为止”。结果入口函数会话自己调用了一个orchestrate协调技能,主动联系session.ts会话询问能否合并,被拒绝四次后,直接伸手进对方worktree把改动抓了过来。作者事后反思:意图必须明说到位(“leave alone”没有说透);暴露出去的能力就可能被用上(技能是App自带的,prompt里根本没提);平等的会话之间需要一个仲裁者,谁愿意单方面行动谁就赢。
评审规模化:一个skill+一道人工闸门
作者写了个rust-rebase-review技能,让Agent在rebase后自动拉起多个模型子Agent做逐行新旧对比、检查Rust地道性、确认无残留TypeScript、验证E2E测试未被改动。意外收获是:因为“边加Rust边删TypeScript”,一旦并行改动碰到被删代码就会天然触发冲突,等于免费获得了变更侦测机制。
App内置的Agent Merge功能自动跑“修CI-回评论-解冲突”全流程,但团队在真正合并前始终留了人工抽查这一步。有一次某PR不小心删掉了一个对外函数,Agent用schema-break-ok标签把CI糊弄过去,作者一句“这个break到底为什么ok”问出真相——21秒后标签撤销,功能被原样用Rust补回。这道人工闸门,比自动化本身更重要。
依赖库迁移+158处unsafe
语言重写也带来了依赖生态的重写:移除了约60个npm依赖,有的一对一替换(js-tiktoken→tiktoken-rs),有的一拆多(8个opentelemetry包变成4个crate+手写状态机),还有5处完全手写替代。
整个runtime crate只有158处unsafe代码块,全部集中在C ABI边界(32.3%)、Windows API(31.0%)、POSIX/libc(29.1%)等“和外部世界打交道”的地方,模型客户端、MCP层、Agent层、提示词层里一处都没有。已知回归里没有一个和unsafe有关——unsafe让“Rust保证到此为止”的边界变得可审计,这是它比原来TypeScript运行时(同样穿越这些边界,但源码里毫无标记)更强的地方。
踩过的坑:能编译≠正确
截至9月14日,团队追踪到几十个已知回归,全部修复。典型模式包括:语义模糊(TypeScript的number该对应Rust哪种数值类型,猜错导致整数被序列化成42.0);隐形行为(toLocaleDateString隐式依赖宿主时区,迁移后要显式传参);只迁移了配对操作的一半(状态更新了但没同步取消对应循环);堵住主线程(同步napi调用冻结UI近一分钟);生命周期管理(这是最大的坑:句柄可能比实例活得更久,一个hook中途销毁能直接卡死对话)。
有意思的是,作者用一个流行段子来收尾:“能编译就是对的”——不成立。文中每一个回归案例都是成功编译并合入主干的代码。
编译器能保证类型一致,但保证不了仓库ID该序列化成整数、时间戳格式对不对、状态机的状态本身是否正确、rebase有没有悄悄删掉一个守卫。这不是否定Rust编译器的价值,只是说它挡住的是一类错误,不是全部错误。
好消息是:迁移期间github/copilot-cli和copilot-sdk两个仓库“质量相关”issue占比几乎没有变化(22.9%→23.7%,36.2%→32.3%),说明用户没有明显感知到质量下滑。
性能提升 & 成本账单
性能测试刻意排除模型推理和网络延迟,只测客户端启动、会话创建、事件处理、销毁这些被改动的部分:
| 场景 | 迁移前 | Rust进程外 | Rust进程内 |
|---|---|---|---|
| 客户端+会话+一轮对话 | 5.25秒 | 1.33秒(4.0倍) | 292毫秒(18.0倍) |
| 1000次单轮会话生命周期 | 132.52秒 | 22.53秒 | 20.93秒(6.3倍) |
十客户端并发场景下,常驻内存峰值从1383MB降到126MB(进程内),降了约91%。而且这只是“翻译”本身带来的基线收益——新的所有权和并发模型带来的重新设计红利,团队还完全没动手拿。
成本:作者本人token花费约1363亿,折合约12万美元;按PR占比折算,人力投入约三周全职工作量。也就是说,一次80万行代码的语言重写,账单大约是12万美元token费+三周人力。
五条经验教训
- 目标要说清楚、说完整:笼统的“迁移到Rust”会被理解成只迁移热路径,明确“终态是100%Rust”后Agent才推进得更彻底
- 端到端测试是生命线:几乎所有功能缺失类回归,都源于E2E测试覆盖不够,而且这类测试本身在迁移中不能被重写,否则就丢了判断对错的标准
- 要保护“判断对错的标准”不被Agent自己动手脚:不能让正在改代码的Agent同时有权悄悄削弱测试、打逃生舱标签
- 先翻译,后重构:同时改语言和改行为,会让你分不清到底是哪个改动弄坏了系统。作者坦言几次“手痒”顺便优化,事后都后悔
- 开发者内循环,在Agent时代更重要而非更不重要:Agent思考快、写码快,但仍要构建测试,构建测试占比反而上升了
小结
五月份还全是TypeScript的引擎,八月份已经全是Rust,而且全程持续对外发布,没有一次惊心动魄的大切换。
作者的结论很直白:这不是“AI能写代码”的故事,而是Agent把一整类项目的价格拉到了可以承受的范围——一个原本需要一整个团队、一到两年时间的项目,现在一名工程师加团队支持,几个月就能拿下。
运行时现在可以被六种语言直接进程内加载,不再需要背负Node.js和V8,也终于能去Node.js到不了的地方:从云端到桌面到设备到嵌入式系统。这不是终点,而是接下来构建的地基。
原文链接:Migrating the GitHub Copilot runtime to Rust, using Copilot
还在为写 Agent 框架频频死循环、上下文爆炸而束手无策?我的新专栏 《从0 开始构建 Agent Harness》 将带你:
- 抛弃臃肿框架,回归“驾驭工程 (Harness Engineering)”的第一性原理
- 用 Go 语言手写 ReAct 循环、并发拦截与上下文压缩引擎等,复刻极简OpenClaw
- 构建坚不可摧的 Safety Middleware 与飞书人工审批防线
- 在底层实现 Token 成本审计、链路追踪与自动化跑分评估
- 从“调包侠”进化为掌控大模型边界的“AI 操作系统架构师”
扫描下方二维码,开启从 0 开始构建Agent Harness 的实战之旅。

还在为“复制粘贴喂AI”而烦恼?我的新专栏 《AI原生开发工作流实战》 将带你:
- 告别低效,重塑开发范式
- 驾驭AI Agent(Claude Code),实现工作流自动化
- 从“AI使用者”进化为规范驱动开发的“工作流指挥家”
扫描下方二维码,开启你的AI原生开发之旅。

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。
