让 2000 个 AI Agent 自己重写自己:Prime Agent 的 Rust 自举重构,冷启动快 14 倍
让 2000 个 AI Agent 自己重写自己:Prime Agent 的 Rust 自举重构,冷启动快 14 倍
2026 年 10 月 9 日,Prime Intellect 正式发布用 Rust 从零重写的 Prime Agent。这场重写最特别的地方不在语言,而在干活的人:一个根 agent 指挥 2000 多个子 agent,用两周时间把代码库从 TypeScript 整体搬到了 Rust。
一、这件事为什么值得写
先摆几个关键数字,感受一下规模:
|
指标 |
数值 |
|
参与重写的 AI Agent |
2000+ 个 |
|
消耗的 Prime Sandbox |
10,000+ 个 |
|
消耗 token |
200 亿+(GLM-5.3 推理端点) |
|
重写耗时 |
约 2 周 |
|
原版累计下载 |
30 万+ 次 |
|
原版累计处理 |
8 万亿+ token |
这不是实验室玩具。Prime Agent 是一个真实生产环境里几十万开发者正在用的 coding agent 框架,把它整体迁移到另一种语言,放在两年前是十几个工程师干几个月的活。而现在,一个"智能体工厂"两周就干完了。
更值得琢磨的是他们是怎么保证 2000 个 agent 重写出来的代码不跑偏的。这个方法论,比"重写成功"这个结果本身更有价值。
二、为什么要从 TypeScript 搬到 Rust
Prime Intellect 在官方博客里把 TypeScript 的痛点说得很直白,总结下来有四条:
- 类型在运行时消失——TS 的类型擦除意味着错误只能以未检查的异常形式出现。
- 单事件循环竞争——CPU 密集的渲染和会话解析,会跟键盘输入抢同一个事件循环,直接拖慢交互。
- JS 运行时 + GC 的固定开销——每个进程都要背一个 JavaScript 运行时和垃圾回收器的成本。
- 长驻守护进程的可靠性——Prime Agent 是一个常驻 daemon,每个 session 一个 worker 进程,长时间跑下来 GC 抖动和异常处理都是隐患。
而 Rust 给出的答案正好对症:
- 无 GC,内存成本可控;
- Send / Sync trait 在编译期检查线程安全——这点很关键,因为"当代码大部分是 agent 写的、而非人逐行 review 时,编译期保证的价值被放大";
- 穷举 enum + 所有权 + 生命周期 + Clippy lint,把一大类"能跑但会错"的问题挡在编译期。
一句话总结动机:不是 TS 不行,是 TS 在"长驻、多进程、agent 量产代码"这个场景下,成本结构不对。
三、2000 个 agent 是怎么协作的:四角色流水线
这是整场重写的核心工程,也是我认为最值得学的地方。
3.1 一个只"管"不"写"的根 agent
根 agent(root agent)一行产品代码都不写。它只做四件事:
- 把整个重写任务拆成一个拓扑排序的任务图(按依赖关系排序);
- 跟踪每个任务的进度;
- 合并已完成的工作;
- 跟人类团队同步优先级和决策。
这个设计很妙。根 agent 一旦自己也下场写代码,就会失去全局视角,陷入"既当运动员又当裁判"的困境。让它保持"工程经理"角色,它才能客观地监督每个任务、及时发现哪个分支卡住了。
3.2 每个任务都要过四道关
每个被派下去的任务,都会依次经过四个独立 agent:
|
角色 |
职责 |
关键设计 |
|
Planner(规划者) |
产出功能规格:特性设计 + TypeScript 的 ground-truth 行为 + 校验器(parity check) |
用原版 TS 行为当"标准答案" |
|
Implementer(实现者) |
在独立 worktree 里写 Rust 代码 |
隔离,让特性可并行开发 |
|
Reviewer(审查者) |
以对抗姿态审查 PR,找"这个改动错在哪" |
用不同模型 + 独立上下文 |
|
Verifier(验证者) |
在全新 Prime Sandbox 里编译、跑 parity 检查和测试 |
干净环境,避免污染 |
只要 Review 或 Verify 任一环节失败,任务就带着发现打回 Implementer 重来;两边都通过,PR 才合并。
flowchart TD
Root["🟣 根 Agent(Root Agent)<br/>只调度,不写代码"]
Root -->|"拓扑排序拆解任务"| P
subgraph TaskLoop["每个任务 × 2000+ 个 agent"]
P["📋 Planner<br/>规划规格 + TS 行为基准"] -->|"特性规格"| I
I["🟢 Implementer<br/>独立 worktree 写 Rust"] -->|"提交 PR"| R
R["🔴 Reviewer<br/>不同模型 对抗审查"] -->|"通过"| V
R -->|"❌ 打回"| I
V["🔵 Verifier<br/>全新沙箱编译 + parity 检查"] -->|"通过"| Merge["✅ PR 合并"]
V -->|"❌ 打回"| I
end
Root -.->|"监控进度 合并成果"| Merge
style Root fill:#c084fc,color:#1e1e2e,stroke:none
style P fill:#f9e2af,color:#1e1e2e,stroke:none
style I fill:#a6e3a1,color:#1e1e2e,stroke:none
style R fill:#f38ba8,color:#1e1e2e,stroke:none
style V fill:#89b4fa,color:#1e1e2e,stroke:none
style Merge fill:#94e2d5,color:#1e1e2e,stroke:none
这里有两个容易被忽略、但极其重要的设计决策:
- 生成和验证分离——"写代码的 agent 评估自己写的代码是有偏见的"。所以 Reviewer 特意换一个模型、换一套上下文,以"找茬"的心态去审。
- 并行 worktree——每个特性在独立工作区开发,互不阻塞,这是 2000 个 agent 能同时干活而不互相踩脚的前提。
3.3 算力怎么调度
重写跑在两台 8 核 CPU 节点上,每台持续承载 100+ 并发子 agent。编译、类型检查、diff 这些重活全部卸载到 sandbox,避免打爆单台机器。这个"把重计算甩给沙箱"的做法,是规模化的关键。
四、如何保证重写不跑偏:四类 parity 校验
重写类项目最大的风险是"功能悄悄丢了"。Prime Intellect 建了四类客观校验,让 agent 能自己量化进度、在合并前拦住回归:
- 差分测试(Differential test)——把 TS 和 Rust 两个二进制并排跑,喂同一套 scripted model,对比两者渲染的终端帧。覆盖启动、菜单、工具调用、session 恢复、子 agent、崩溃恢复。
- Harness parity——对比两者的 session 转录 和发给模型供应商的 请求内容。
- Protocol parity——把 daemon 的每个消息类型跟原实现逐一比对。
- Agent audit——让 agent 把 TS 产品逐组件审计,标记为「匹配 / 部分实现 / 缺失」。
第四类尤其重要:前三种是"点对点比对",只能验证被测试覆盖到的行为;第四种是"面覆盖",专门抓"整个功能被漏掉"的情况。
但官方也诚实承认了这套校验的边界:"parity check 只能验证它们实际执行到的行为"。所以后面才会有一整段 dogfood 的故事。
五、性能到底提升了多少
先声明:这些是厂商自测数据,且排除了模型推理时间,测的是"harness 开销"(启动 + 渲染 + 进程调度),不是端到端编码速度。看数据时要清楚这一点。
|
指标 |
TypeScript |
Rust |
提升 |
|
冷启动输入就绪延迟 |
736.1 ms |
51.9 ms |
约 14 倍快 |
|
10 MiB 会话进程树内存 |
1130.0 MB |
237.3 MB |
约 4.8 倍低 |
内存这一项含金量更高。单个大 session 从占 8GB 沙箱的约 14% 降到约 3%,意味着同一台机器能塞下更多常驻 session 和子 agent——这对做 agent 编排的人是真金白银的成本节约。
那 684ms 的冷启动省下来值不值?官方也提示:它只在每次 session 启动时省一次,能不能缩短用户的实际编码任务,取决于被排除在外的推理时间占比。所以"14 倍快"的正确理解是"harness 启动快 14 倍",别误读成"编码快 14 倍"。
六、架构重构带来的长期收益
语言切换之外,这次重写顺带把代码库结构也重塑了,长期收益可能比性能数字更大:
- 9 个 crate + 单向依赖图,由 Cargo 强制。TUI 唯一的内部依赖是 shared types crate。
graph LR
subgraph 架构层
Types["📦 shared-types<br/>协议定义 · 单一来源"]
end
subgraph 平台层
Platform["🔧 platform<br/>transport / 进程控制 / 文件锁"]
end
subgraph 核心层
Daemon["⚙️ daemon<br/>守护进程"]
Worker["🏗️ worker<br/>会话进程(每 session 一个)"]
Supervisor["🛡️ supervisor<br/>进程监控与恢复"]
end
subgraph 界面层
TUI["🖥️ tui<br/>终端界面"]
end
subgraph 外部
Catalog["📋 catalog<br/>模型 & 插件(运行时拉取)"]
Sandbox["🧪 sandbox<br/>编译 / diff / 类型检查"]
end
TUI --> Types
Daemon --> Types
Daemon --> Platform
Worker --> Types
Worker --> Platform
Supervisor --> Platform
Daemon -.->|"启动"| Supervisor
Supervisor -.->|"管理"| Worker
Daemon -.->|"拉取"| Catalog
Worker -.->|"卸载重活"| Sandbox
style Types fill:#f9e2af,color:#1e1e2e,stroke:none
style Platform fill:#89b4fa,color:#1e1e2e,stroke:none
style Daemon fill:#a6e3a1,color:#1e1e2e,stroke:none
style Worker fill:#a6e3a1,color:#1e1e2e,stroke:none
style Supervisor fill:#c084fc,color:#1e1e2e,stroke:none
style TUI fill:#f38ba8,color:#1e1e2e,stroke:none
style Catalog fill:#94e2d5,color:#1e1e2e,stroke:none
style Sandbox fill:#94e2d5,color:#1e1e2e,stroke:none
- 最大源文件从 ~15,000 行降到 ~2,500 行;原来有 4 个文件超过 5,000 行,现在一个都没有。
- 进程隔离:每个 session 跑在独立 worker 进程 + 小型 supervisor 下,一个 session 崩了不影响其他;session 落盘持久化,客户端重启后可重新 attach。
- 平台抽象:transport、进程控制、文件锁全部藏到 trait 后面。所以 Windows 支持从"重连 daemon"变成了"实现几个 trait"。
- 单一协议定义:client、daemon、worker 都编译同一份 shared types 里的消息类型,改协议时全链路强制检查。
- catalog 驱动:模型列表和 MCP 列表拆成运行时拉取的独立 catalog,发新模型、新插件不用再发版 Prime Agent。
这几条里的「单向依赖图」「平台 trait 抽象」「协议单一来源」,都是架构课上反复讲的理想状态,但很少有项目能在"业务迭代压力"下真做到。这次借重写的机会一次性落地了。
七、踩坑与经验教训(最实在的部分)
- parity 过了 ≠ 能上线。脚本测试覆盖不到的行为,在真实使用里会漏。Prime Intellect 的做法是分两步 dogfood:先把重写 agent 自己迁到 Rust 版跑(让 Rust 版"递归地自我改进"),再把内部团队切到 Rust 版日常使用——这才暴露出差分测试覆盖之外的 bug 和缺失行为。
- "达到发布质量"的收尾活比想象重。从 parity 达成到正式发布,又花了好几周:补完特性、修 bug、调性能、打磨界面。而这些收尾活,依然是人类在 loop 里——找问题、定方向、审结果。
- hillclimb 优化也要给 agent 一把"尺子"。为了优化运行时性能,他们先搭了一个 benchmark harness 量化各种运行时指标,然后让一个 orchestrator 跑三天 hillclimb 循环(单一目标:不破坏 parity 的前提下改善 benchmark)。三天下来记录了 144+ 次实验和审计,合并了 69+ 个有效变更。优化方向集中在:把活从启动/渲染路径挪走、把轮询换成事件触发、大 session 加载后释放内存。
- "根 agent 不写代码"是被验证的好设计。让协调者保持纯净,是整套流水线能自洽运转的前提——这跟人类世界"好的工程经理不下场抢活干"是同一个道理。
八、对开发者的启示:可复用的方法论
剥掉"2000 个 agent"的噱头,这套东西其实是一份可以抄走的工程清单:
- 生成与验证必须分离,且 reviewer 要用不同模型、独立上下文。
- 重写项目用旧实现当 oracle——老程序就是规格说明书,任何偏离都会以 diff 形式现形。
- 给 agent 一把可量化的尺子,让它们能自己判断"我改的是不是变好了",否则规模化无从谈起。
- 先造测试 harness,再谈优化。没有 benchmark 的优化都是拍脑袋。
- 人退到"设计验证装置"的位置,而不是逐行 review 代码。人的精力用在定义"什么是对的",agent 负责"做到"。
- dogfood 是补齐测试盲区的唯一解。测试只能验证你想到的行为,真实使用会告诉你没想到的。
结语
Prime Agent 的这次 Rust 重写,与其说是一次语言迁移,不如说是一次"AI 规模化重构生产软件"的公开压力测试。它同时证明了两个方向:
- 可行:2000 个 agent、两周、几十万用户的生产工具,确实能搬完并比原版更快更省。
- 但没到"无人值守":parity 通过只是开始,收尾、dogfood、优化,每一环都离不开人在 loop 里。
对我们这些还在观望"AI 到底能不能重构大项目"的开发者,最好的态度是:别把 agent 当替代者,把它当一支执行力拉满、但需要你定标准、设校验、审结果的工程团队。
- 点赞
- 收藏
- 关注作者
评论(0)