Hacker News ★ 83 6 min

Rewriting Prime Agent in Rust

🔗 https://www.primeintellect.ai/blog/prime-agent-rust

📌 兩千個AI Agent花兩週,把自己的程式碼庫從TypeScript搬到Rust

TL;DR:Prime Agent用2000+個agent組成的群體,自己重寫了自己的核心架構,人類只負責搭建驗證機制。

如果一個coding agent工具要「重寫自己」,誰來寫Code、誰來審查、誰來把關品質?Prime Intellect給出的答案是:全部交給agent群體,人類只搭驗證框架。Prime Agent自八月推出以來,下載量超過30萬次,處理超過8兆個token,而這次團隊選擇把整個產品從TypeScript改寫成Rust,並讓這次重寫本身成為一場多agent協作的壓力測試。

🤔 為什麼要從TypeScript換成Rust

團隊坦言TypeScript幫助Prime Agent快速上線,但它的型別是選用的,執行期就會消失;錯誤以未檢查的例外形式傳遞;CPU密集工作(如渲染、解析大型session)會跟鍵盤輸入搶同一個event loop;而且每個process都要負擔JavaScript runtime與垃圾回收的成本。Rust能提供效能(原生程式碼、無GC、worker process per session)、並行安全(Send/Sync trait讓編譯器檢查哪些資料能在執行緒間移動或共享)以及編譯期保證(exhaustive enum、ownership與lifetime排除整類bug,加上Clippy的pedantic lint規則)——這些特性在「程式碼大多由agent寫」的情境下特別重要。

🧩 四個agent角色,一套平行驗證的FSM流程

整個重寫由一個root agent主導,負責把工作拆成拓樸排序的任務清單。這個root agent本身不寫任何產品程式碼,專心監控每項任務、合併完成的工作,並與人類團隊討論優先順序。每個任務會依序經過四個agent角色:

  • Planner:撰寫整體規格,包含功能設計、TypeScript版的ground-truth行為,以及對應的驗證邏輯(parity check)。
  • Implementer:在獨立的worktree中寫Rust程式碼,讓功能能平行開發。
  • Reviewer:用不同模型、在獨立context中「對抗式」審查PR,專門找出這段改動錯在哪裡。
  • Verifier:在全新的Prime Sandbox中編譯並執行該功能的parity check與測試。

只要Review或Verify任一關卡失敗,任務就退回給Implementer重做,兩關都過才會合併。團隊設計了四種parity檢查:TUI parity(差分測試比對TS與Rust版的終端機畫面輸出,涵蓋啟動、slash選單、工具呼叫、compaction、agent視圖、session resume、subagent與crash recovery)、Harness parity(比對session transcript與送往模型供應商的請求)、Protocol parity(比對daemon protocol中的訊息型別)、Feature parity(agent逐一審查TS介面的每個元件,分類為matching/partial/missing)。

基礎設施上,所有orchestrator與其agent跑在兩臺8核心的on-demand CPU節點上,每臺可支援100多個並行的subagent與各自的CPython kernel;編譯、型別檢查與diff這類吃資源的工作則外包給Prime Sandbox,讓整個重寫可以高度平行化。

📊 兩週、兩千多個agent、超過2000億token

根據進度圖表,Rust Implementation階段動用了1,981個agent,耗用192.99B token;接著的Performance Hillclimb階段(跑真實benchmark與trace調效能、抓bug)用了228個agent,耗用35.70B token。到10月1日15:59為止,累計共2,209個agent、16,758則agent對agent訊息,總計228.70B token。

💡 重寫順帶換來的架構紅利

這次重寫也是重新設計架構的機會:程式碼拆成9個crate,依Cargo強制的單向依賴圖排列,TUI唯一的內部依賴是共享的types crate;最大的原始碼檔案從TypeScript版的約15,000行降到約2,500行,且沒有任何檔案超過5,000行(TS版有四個檔案超過這個門檔)。每個session跑在獨立的worker process底下,由一個小型supervisor管理,單一session的失敗不會波及其他session,session狀態也會落地到磁碟供重連後復原。transport、process control、file locking都被抽象成平臺特定介面,讓Windows支援只需要實作對應的trait即可,而不用重寫整個daemon。模型與MCP清單也改成執行期抓取的catalog,可以不用發新版本就上架新模型或plugin。等到主要RLM迴圈達成parity後,團隊更把重寫用的agent群自己也換到Rust版上跑,等於讓Rust版Prime Agent遞迴地改進自己。

⚠️ 差分測試只驗證「有跑到」的行為

團隊也坦言,自動化的parity check只能驗證它實際涵蓋到的行為路徑,真正剩下的bug與行為差異,大多是等到內部團隊把Rust版拿來日常使用後才被發現,這也指引了後續在可靠性與介面細節上的補完工作。

🎯 實務啟示

這套「Planner-Implementer-Reviewer-Verifier」的四角色FSM流程,本質上是把「生成」與「驗證」刻意拆成不同agent、不同context,降低agent審查自己程式碼的偏誤。對任何想用多agent做大規模程式碼重構或遷移的團隊而言,這組模式(加上可重複使用的parity check)或許比單純堆agent數量更值得借鏡。

🔗 來源

#PrimeAgent #Rust #MultiAgent #CodingAgent #AgentOrchestration #SoftwareRewrite #AIEngineering #FiniteStateMachine #PrimeIntellect #AgentSwarm

原始資料 Hacker News · 收集於 2026-10-10
來源原標題
Rewriting Prime Agent in Rust
作者
piotrgrabowski
原始標籤
hackernews
來源訊號
HN points 62 HN 留言 20
原始連結
https://www.primeintellect.ai/blog/prime-agent-rust

摘要原文

Rewriting Prime Agent in Rust Since we launched Prime Agent [1] in August, it has been downloaded more than 300,000 times and has processed over 8 trillion tokens. Today, we're excited to ship a faster, cleaner and more reliable Prime Agent, rewritten from the ground up in Rust. Over two weeks, Prime Agent orchestrated a swarm of over 2,000 agents to rewrite itself end to end, operating across 10,000+ Prime Sandboxes with over 200 billion tokens from Prime Inference’s GLM-5.3 endpoint. The Rust rewrite stress-tested Prime Agent’s multi-agent capabilities, including the sandbox and inference infrastructure we’ve been building to power large-scale agent swarms, autonomous research, and reinforcement learning. To ensure feature parity with the TypeScript version, Prime Agent orchestrated subagents to topologically sort dependencies, with finite state machines structuring looped computations and correctness checks. In parallel, we rewrote the code architecture for easier maintenance and development. We then used runtime benchmarks and real Prime Agent traces to hillclimb performance metrics and triage bugs. Now, Prime Agent runs faster and uses fewer resources than most coding agent harnesses. Subagent depth Parent Depth 1 Depth 2 Depth 3 Rust Implementation 192.99B tokens 1,981 agents Performance Hillclimb 35.70B tokens 228 agents Oct 01, 15:59 2,209 agents · 16,758 agent-to-agent messages · 228.70B total tokens Why Rust TypeScript helped us ship Prime Agent quickly, but its types are optional and disappear at runtime, errors travel as unchecked exceptions, CPU-heavy work like rendering and parsing large sessions competes with keyboard input on a single event loop, and every process pays for a JavaScript runtime and garbage collector. We want to keep shipping as fast as we do, while holding the code to a higher standard as it grows, and Rust suits that well: Performance: Prime Agent is a long-running daemon with a worker process per session, and native code without a garbage collector accounts for most of the memory and startup gains we’ve made. Concurrency: one daemon streams model output, runs tool calls, relays messages between agents and serves every attached client at once. Rust's Send and Sync traits let the compiler check which data can move between threads and which can be shared. Compile-time guarantees: exhaustive enums, ownership and lifetimes rule out whole classes of bugs before the code runs, and Clippy's pedantic lints add hundreds more checks, which matters when agents write most of the code. In addition to these clear performance gains, the rewrite gives us the opportunity to rethink our design choices. We have significantly modularized our codebase, and are reaping the rewards of this rewrite, including Windows support, session crash isolation, and a more consistent daemon protocol. How Prime Agent rewrote itself Our goal was for agents to perform the rewrite autonomously with as little human intervention as possible. Thus, the human work required was to setup proper verification to enable autonomous deployment at scale. We followed similar setup to previous work on automatic Rust translation [2] . Each specification covered a different kind of parity: TUI parity: a differential test suite compares the TypeScript and Rust binaries side by side against the same scripted model and diffs the terminal frames each one renders. It covers user flows, including launch, slash menus, tool calls, compaction, agents view, session resume, subagents and crash recovery. Harness parity: the same run diffd session transcripts and the requests each binary sends to the model provider, so both produce the same sessions from the same inputs. Protocol parity: all message types in the daemon protocol are checked against the TypeScript implementation, ensuring our ACP and daemon protocol APIs are consistent. Feature parity: since scripted flows cannot cover an entire interface, agents audited the TypeScript product component by component, classifying each as matching, partial or missing. With an objective check for every kind of parity, the agents could measure their own progress and catch regressions before changes merged, which let us cut back on human review. Remaining bugs and behavior differences were largely found through internal use, which guided our follow-up work on missing features, reliability and interface polish. We ran all orchestrators and their agents on two 8-core on-demand CPU nodes, each supporting over 100 concurrent subagents and their respective CPython kernels. Additionally, since compilation, type-checking and diffing would saturate any single machine when dozens of agents are running at once, we built out utilities for our agents to outsource heavy work to Prime Sandboxes, allowing us to heavily parallelize our port. An objective TUI parity verifier compares terminal frames from the TypeScript and Rust versions and highlights differences. Orchestration of Finite State Machines A single root agent orchestrated the rewrite and divided the work into a topological ordering of tasks. The root agent wrote no product code, keeping it free to monitor every task, merge finished work, and maintain an overview of the rewrite while working with us on priorities and decisions. We also kept generation and verification in separate agents, since an agent that writes code is biased when evaluating it. Therefore, each task assigned by the orchestrator moved through four agents: Planner: creates overall machine specification, including the feature design, ground-truth TypeScript behavior, and verifier (parity check) Implementer: writes the Rust code in a dedicated worktree so features can develop in parallel. Reviewer: inspects the pull request adversarially, using a different model and in a separate context from the implementer, looking for reasons the change is wrong. Verifier: compiles and runs the feature's parity checks and tests in a fresh Prime Sandbox. A failed review or verification sends the feature back to the implementer with the findings, and the PR merges once both pass. We are building this pattern into Prime Agent to orchestrate a factory of finite state machines, so workflows like this one can be defined once, reused, and updated. Architecture re-design Porting to Rust also gave us a chance to restructure the codebase. This is where much of the long-term benefit comes from: Modularity: the code is split into nine crates with a one-way dependency graph that Cargo enforces, and the TUI’s only internal dependency is the shared types crate. The largest source file is now ~2,500 lines, down from ~15,000 in TypeScript, with no files over 5,000 lines compared with four in TypeScript. Isolation: each session runs in its own worker process under a small supervisor, so a failure in one session leaves the others running, and sessions persist on disk so clients can reattach after a restart. Platform abstraction: transport, process control and file locking sit behind platform-specific interfaces, so something like Windows support came down to implementing those traits rather than rewiring the daemon. One protocol definition: the client, the daemon and every worker compile against the same message types in the shared types crate, so a change to the protocol is checked everywhere it is used. Catalog-driven models: ported our model and MCP lists to a separate catalog fetched at runtime, allowing us to ship new models and plugins without a Prime Agent release. Refining the work While the autonomous workflow went further than we expected, the parity checks only verified the behavior they exercised. Once parity on the main RLM loop was achieved, we moved all our rewrite agents onto Rust, allowing us to dogfood the Rust version at scale (and now Prime Agent Rust was recursively improving itself!). Later, we moved our internal team onto the Rust build for daily use, which exposed bugs and missing behavior outside the coverage of the differential tests. (62 points, 20 comments on Hacker News)

由 claude-code/sonnet 自動生成