使用 AI 擴展 Rust 開發:來自 10 萬行共識引擎的經驗教訓

AI 輔助編碼的承諾往往在「氛圍編碼」(vibe coding)的炒作與維護複雜系統的現實之間波動。然而,當應用於像分散式共識這樣嚴謹的領域時,AI 可以超越簡單的自動完成,成為生產力的主要驅動力。

在最近的一個專案中,一名開發者透過實作一個基於 Rust 的 multi-Paxos 共識引擎,對 AI 編碼代理(agents)的極限進行了壓力測試。目標是將 Azure 的 Replicated State Library (RSL) 現代化,解決長達十年的限制,例如缺乏流水線(pipelining)、缺乏非揮發性記憶體 (NVM) 支援,以及對 RDMA 硬體感知能力的不足。結果是生產力的大幅躍升:在約四週內寫出了 10 萬行 Rust 程式碼,隨後的效能調優將吞吐量從每秒 2.3 萬次操作提升到了 30 萬次。

AI 驅動的工作流程

要達到這種規模的產出,不僅僅需要單一工具。該開發者使用了一套代理工具,包括 GitHub Copilot、Claude Code、Codex、Augment Code、Kiro 和 Trae。目前的主要驅動力是 Claude CodeCodex CLI,並以 VS Code 作為差異比對(diffs)和微調的介面。

一個值得注意的觀察是向以 CLI 為中心的工作流程轉變,這允許了非同步的開發週期。透過將 AI 視為主要的實作者,而將人類視為架構師,開發者能夠在傳統開發時間的一小部分內,實作 RSL 的完整功能集——包括領導者選舉(leader election)、日誌複製(log replication)、快照(snapshotting)以及配置變更。

確保正確性:由 AI 為 AI 建立的程式碼合約

實作像 Paxos 這樣複雜的協定是充滿風險的;單一邏輯錯誤就可能導致災難性的狀態分歧。為了應對這一點,該專案超越了標準的單元測試,轉而採用 程式碼合約 (code contracts)

程式碼合約為關鍵函數定義了前置條件(preconditions)、後置條件(postconditions)和不變量(invariants)。在此專案中,AI 在三個不同的層次被利用:

  1. 合約生成: 使用高端模型(如 GPT-5 High 或 Opus 4.1)來編寫詳細的合約。例如,Paxos 實作中的 process_2a 方法利用了 16 個不同的合約來確保狀態轉換是有效的。
  2. 針對性測試生成: 一旦合約建立,AI 會生成特定的測試案例,旨在觸發這些合約的後置條件。
  3. 基於屬性的測試 (Property-Based Testing): AI 將這些合約轉換為基於屬性的測試,使用隨機輸入來探索狀態空間並尋找手動測試可能會遺漏的邊緣案例。

當一個 AI 生成的合約識別出一個細微的 Paxos 安全性違規時,這種方法證明了其價值,否則該問題將導致嚴重的複製一致性問題。

輕量化規格驅動開發 (SDD)

雖然僵化的 SDD(需求 $\rightarrow$ 設計 $\rightarrow$ 任務列表)可能會成為維護負擔,但該專案採用了使用 spec kit 的「輕量化」版本。

工作流程包括透過 /specify 生成包含使用者故事和驗收標準的規格 Markdown 文件,然後使用 /clarify 讓 AI 自我批判並建議缺失的場景。一旦規格被完善,AI 會為單個使用者故事生成計畫——這是目前 AI 代理的「甜蜜點」——並執行實作。

激進的效能優化

由於任務的迭代性質,效能調優是 AI 擅長的領域。開發者遵循一個緊密的迴圈來將吞吐量從 23K 提升到 300K ops/sec:

  • 儀器化 (Instrumentation): AI 在所有程式碼路徑中加入延遲指標。
  • 分析: AI 編寫 Python 腳本來分析追蹤日誌並計算分位數,以找出瓶頸。
  • 優化: AI 提出並實作變更,例如最小化分配(allocations)、應用零拷貝(zero-copy)技術,並減少非同步(async)開銷。
  • 驗證: 重新測量並重複。

批判性觀點與反論

儘管數據令人印象深刻,但該專案在開發者社群中引發了關於 AI 生成程式碼性質的重大辯論。

「AI 垃圾內容」的擔憂

幾位評論家指出,原始的 RSL 函式庫僅有 36K 行 C++。AI 生成的 Rust 版本達到 130K 行,這表明可能缺乏效率。正如一位評論者所說:

"Rust 應該要更具表達力且簡潔。然而,AI 生成了 130k LoCs。我猜沒人理解這段程式碼如何運作,也沒人能說出它是否真的有效。"

Borrow Checker 的掙扎

AI 生成 Rust 的一個常見痛點是 LLM 有「對抗」borrow checker 的傾向。與其重新思考所有權模型,AI 往往預設以大量使用 .clone() 或將所有東西包裝在 Arc<Mutex<...>> 中來滿足編譯器。

"LLMs 直接走捷徑。問題:程式碼無法編譯。解決方案:多用 clone()。"

這表明,雖然 AI 可以生成可以 編譯通過測試 的程式碼,但它並不總是能產生 慣用 (idiomatic) 的 Rust,可能會為了安全性而犧牲了活躍性(liveness)問題(例如死鎖)。

測試密度

對於 130K 行程式碼,僅有 1,300 個測試,有些人質疑對於像共識引擎這樣複雜的系統,測試與程式碼的比例是否過低,特別是當測試本身也是由 AI 生成且可能未經完整的人工審核時。

結論

在幾週而非幾個月內構建一個 10 萬行以上的系統,證明了如果由一位稱職的架構師引導,AI 代理可以處理大規模的架構提升。透過結合程式碼合約、輕量化規格和迭代的效能優化迴圈,開發者成功地現代化了關鍵的基礎設施。然而,「程式碼行數」與「慣用品質」之間的張力,仍然是下一代 AI 輔助工程的中心挑戰。

Sources