智慧體軟體工程 #5 | 深度拆解 Anthropic 的 Rust 實作:AI 寫的程式碼憑什麼能上生產?

2026 年初,Anthropic 密集公開了一系列 Rust 專案和工程經驗:

2 月發布了由 16 個 Claude 智慧體並行構建的 C 編譯器(claudes-c-compiler),

3 月同時開源了 protobuf 函式庫 buffa 和 RPC 框架 connect-rust[1],並發表了兩篇深度工程部落格,一篇關於 C 編譯器的智慧體團隊經驗 Building a C compiler with a team of parallel Claudes[2],另一篇關於長時運行應用的 harness 設計 Harness design for long-running application development[3]。此外,Anthropic 還 fork 了兩個關鍵的 Rust 基礎函式庫:非同步運行時 anthropics/tokio[4] 和並發快取 anthropics/moka[5],對它們進行了針對性的修改,暴露了其在生產環境中的真實技術需求。

這些材料表面上各自獨立,但綜合分析後會發現,它們編碼了一套完整的、可複用的 AI 編碼方法論。本文從 Anthropic 的 Rust 應用佈局說起,逐層拆解這五個專案和兩篇部落格,最終提煉出系統性的 AI 編碼最佳實務。


一、Anthropic 為什麼用 Rust

Anthropic 是一家 AI 公司,但 Rust 在其工程體系中的份量遠超外界認知。

Anthropic 的建置系統職缺(2026 年 3 月)揭示了一個關鍵細節:公司的單體倉庫(Monorepo)橫跨 Python、Rust 和 Go 三種語言,建置目標覆蓋 TPUTrainiumGPU 多種加速器平台。該職缺明確要求「熟悉 Rust 建置工具鏈(cargo、maturin)和 Python-Rust 互通性」。

這說明 Rust 是 Anthropic 系統中的「承重牆」

透過分析截至 2026 年 3 月的 14+ 個在徵職缺,Rust 至少出現在以下團隊:

  • 推論服務:面向數百萬用戶的 Claude 推論,包括跨數千加速器的智慧路由和 LLM 推論優化。
  • 建置系統:Rust 是核心必備語言,用於密封建置基礎設施和遠端建置執行。
  • 沙箱(兩個獨立職缺):安全沙箱執行環境、核心優化、虛擬化和輕量級 VM 方案。
  • 安全工程(倫敦、舊金山、西雅圖多個職缺):認證架構、密碼學基礎、CI/CD 加固,以及「安全實驗室」中的實驗性安全研發。
  • Agent 基礎設施:自主 agent 執行環境、狀態管理和安全邊界。

此外還有推論部署強化學習研究(Horizons)可解釋性研究核心基礎設施等團隊。

開源五個 Rust 倉庫:三個原創專案 + 兩個深度 fork

Anthropic 的 GitHub 組織目前有三個原創 Rust 倉庫和兩個有實質性修改的 fork:

專案
定位
類型
說明
claudes-c-compiler
C 編譯器
原創,100% AI 編碼
10 萬行 Rust,零 unsafe,約 $20,000
buffa
protobuf 函式庫
原創,AI 主導 + 人類架構
README 標註 "Written by Claude ❣️"
connect-rust
RPC 框架
原創,人類主導 + AI 輔助
無 AI 聲明,有 .claude/agents
tokio (fork)
非同步運行時
fork,添加排程器卡頓檢測
透過內部 Artifactory 發布
moka (fork)
並發快取
fork,修復 TOCTOU 競態(目前還未合併)
多執行緒下 10-15% 資料遺失

三個原創專案構成了 AI 參與梯度(100% AI → AI 主導 → 人類主導),兩個 fork 則暴露了 Anthropic 生產環境的深水區需求,只有在高並發生產服務中才會遇到的運行時級別問題。


二、五個 Anthropic 開源的 Rust 專案的技術解讀

claudes-c-compiler:100% AI 自主編碼的壓力測試和能力展示

2026 年 2 月,Anthropic 安全研究員 Nicholas Carlini 用 16 個並行的 Claude Opus 4.6 agent 從零構建了一個 Rust C 編譯器。兩週時間,約 2,000 個 Claude Code 會話,花費約 $20,000,產出 10 萬行 Rust 程式碼。

claudes-c-compiler 編譯器支援 x86-64、i686、AArch64 和 RISC-V 後端,內建組譯器和連結器,能編譯未修改的 Linux 6.9 核心,加入了 GCCClang/LLVMIntel oneAPI 的行列。它還能編譯 QEMUFFmpegSQLitePostgreSQLRedis,並通過了 GCC torture test 的 99% 測試用例。以及通過了開發者的終極試金石:能編譯運行 Doom。Anthropic 用編譯運行 Doom 最終可以證明 AI 生成的程式碼不僅能編譯通過,還能在運行時正確執行複雜的即時邏輯

這是程式員文化中一個有趣的傳統。1993 年 id Software 發布的 Doom 是第一批真正意義上的 3D 第一人稱射擊遊戲之一。John Carmack 寫的引擎在當時極其高效,它能在 386 處理器上流暢運行,原始碼在 1997 年以 GPL 協議開源。從那以後,「能不能跑 Doom」變成了一個半開玩笑的技術驗證標準。社群裡有人在印表機上跑 Doom、在驗孕棒的螢幕上跑 Doom、在 ATM 機上跑 Doom、在 Minecraft 裡跑 Doom。它變成了一種 meme,但背後有嚴肅的技術含義。Doom 的原始碼雖然只有大約 4 萬行 C,但它對編譯器的考驗非常全面:覆蓋了大量 C 語言特性、有即時可見的正確性驗證、依賴鏈條長、實際的效能壓力。

這是一個 clean-room 實作,即,Claude 在開發期間沒有網際網路存取,僅依賴 Rust 標準函式庫。程式碼中零 unsafe 區塊。

但它有明確的儕限:缺少 16 位 x86 編譯器(引導 Linux 需要調用 GCC)、生成的機器碼效率低於 GCC 關閉所有優化的輸出、Rust 程式碼品質「合理但遠非專家級」。Carlini 坦言:「編譯器已接近 Opus 能力的極限。」

架構極其簡潔,一個 bash 無限迴圈:

while true; do
    claude --dangerously-skip-permissions \
            -p "$(cat AGENT_PROMPT.md)" \
            --model claude-opus-X-Y &> "$LOGFILE"
done

16 個 Docker 容器各跑一個迴圈,透過 git 同步。沒有 orchestrator agent,沒有複雜編排框架。協調機制是檔案鎖,agent 在 current_tasks/ 目錄寫檔案占位,git 的衝突機制自然解決競爭。

雖然這個專案公布以後被技術社群嘲諷,但值得說明的是,這個專案只是用來作為 Opus 4.6 的能力展示,而非生產級的替代。很顯然,這無法替代 GCC。我之前把這個專案稱之為「演員」。

我們只要以正確的角度看待這個專案,就可以從中學習一些東西,把噪音轉變為訊號

claudes-c-compiler 專案原始碼,我好奇一個問題:為什麼沒有 CLAUDE.md?

隨後才反應過來,CLAUDE.md` 是人類給 Claude 的操作手冊,適合人機協作模式。

claudes-c-compiler 的模式則完全不同,它是自主運行。回到這個 Bash 迴圈(只在容器中運行):

#!/bin/bash
while true; do
    COMMIT=$(git rev-parse --short=6 HEAD)
    LOGFILE="agent_logs/agent_${COMMIT}.log"
    claude --dangerously-skip-permissions \
            -p "$(cat AGENT_PROMPT.md)" \
            --model claude-opus-X-Y &> "$LOGFILE"
done

這個 bash 程式碼其實就是一種 Ralph Loop 的基本形式。「Ralph loop」(全稱 "Ralph Wiggum loop")是 Claude Code 社群中流行的一種讓 AI agent 持續自主工作的方法,名字來自《辛普森一家》中那個天真、不知疲倦的小男孩 Ralph Wiggum。

--dangerously-skip-permissions 在這裡是跳過所有權限確認。Ralph loop 在個人機器上跑時可能還有人偶爾看一眼,Carlini 的版本是真正的「啟動後走開」,所以必須跳過權限提示(否則 Claude 會卡在「是否允許運行 cargo build?」這類確認上),代價是用容器隔離來兜底安全。

Carlini 在部落格裡還順帶提到一件「Claude Code 自殺」趣事:Claude 不小心執行了 pkill -9 bash,殺掉了自己所在的 bash 行程,導致迴圈終止。

每次迴圈,Claude 被扔進一個全新的 Docker 容器,讀取 AGENT_PROMPT.md,然後自主運行直到完成一個任務。沒有人類在旁邊互動,沒有「提交前檢查」的概念,Claude 自己決定做什麼、怎麼做、什麼時候 push。

在這種模式下,CLAUDE.md 的兩個功能被其他機制替代了:

  • 操作指令:由 AGENT_PROMPT.md 承擔(它包含「把問題分解成小塊、跟蹤進度、持續做到完美」的指令,沒開源,但是部落格裡有寫)。
  • 長期記憶:由 Claude 自己維護的檔案系統承擔。

為了並發執行,使用了一個目錄 current_tasks/ 作為分散式任務鎖。這個目錄是 16 個 agent 的協調總線。每個 .txt 檔案就是一個任務鎖:

current_tasks/fix_arm_asm_caspal_instruction.txt
current_tasks/fix_x86_standalone_kernel_link_errors.txt
current_tasks/fix_macro_param_prefix_substitution.txt
...

每個檔案的結構非常一致。看內容的話,你回發現 Claude 自己發明了一種半結構化格式

Fix ARM assembler: add support for CASP/CASPA/CASPL/CASPAL instructions
[問題描述]
[技術細節:指令編碼格式]
Files to modify: [具體檔案列表]
Started: 2026-02-05
Locked by: [commit hash] at [timestamp]

雖然並不是每個檔案都嚴格遵循這種結構,但 這個格式也能暴露了幾個重要的 AI 編碼實踐

  • 問題描述即規格說明:每個任務檔案不只是一個標題,而是包含了完整的 bug 分析。比如 fix_arm_asm_quad_prel64_relocation.txt 列出了三個互相關聯的 bug(解析器不分解 symbol+offset、ELF writer 用錯了 relocation 類型、缺少 Prel64 variant),以及具體的核心程式碼範例(__jump_table section 的 .quad 指令)。這讓下一個拿到這個任務的 agent 不需要重新分析問題。
  • 修改範圍預聲明:即,"Files to modify" 列表。這不只是文件。它是給其他 agent 的訊號:「我要改這些檔案,你避開」。在 16 個並行 agent 的場景下,這比 git 衝突後處理要高效得多。
  • 鎖機制Locked by: [commit hash] at [timestamp] 是 Carlini 在部落格中描述的檔案鎖的實際樣貌。注意它用的是 git commit hash,不是 PID 或主機名稱。因為每個 agent 在獨立的 Docker 容器裡,PID 沒有意義。

Claude 自己也維護了一個知識庫,或者是記憶:ideas/

ideas/ 目錄是整個專案中最有價值的 AI 編碼實踐樣本。它完全由 Claude 自己創建和維護,功能等價於 buffa 的 DESIGN.md,但是 運行時動態生成的

後面內容會介紹 buffa。

ideas 中有專案狀態追蹤(new_projects.txt / new_projects_myasm.txt)

這兩個檔案加在一起超過 400 行,跟蹤了 150+ 個開源專案的編譯測試結果。格式極其規範:

redis: PASS (all 4 backends: x86, i686, arm, riscv)
zstd: PASS x86, FAIL arm (runtime crash in fullbench)

new_projects_myasm.txt 更精細,每個專案有四列(x86/i686/arm/riscv),FAIL 的附帶具體原因和修復記錄。比如 zstd 條目記錄了 RISC-V 的失敗根因:"get_expr_type 對 UIntLiteral 在 64 位目標上返回 U64(應該是 U32),導致 narrow pass 遺漏 LShr 窄化 → mulw 的符號擴充套件結果被送入 64 位 srl → DeBruijn 陣列越界 segfault"。

這不是人寫的 bug 報告,這是 Claude 自己在修 bug 過程中留下的調查記錄。它的功能和 buffa DESIGN.md 中「被拒絕方案」章節一樣:防止未來的 agent 重新踩同一個坑。

ideas/ 下的檔案按 HIGH/MEDIUM/LOW 分級:

high_codegen_runtime_perf.txt     — 運行時效能瓶頸(帶 profiling 資料)
high_compile_speed_improvements.txt — 編譯速度瓶頸(帶 callgrind 指令計數)
high_sema_expansion_typed_ast.txt  — 型別系統重構計劃(7 步,5 步已完成)
low_structured_error_infrastructure.txt — 錯誤報告基礎設施

每個檔案的內部結構都很驚人。以 high_compile_speed_improvements.txt 為例:

Profiled on sqlite3.c (callgrind, 20.2B instructions after fixes).
Previous profile: kernel/softirq.c (2.31B instructions).
FIXED: Peephole loop trampoline O(n*labels) quadratic scan was 19.76%
of total compile time. Pre-built reverse index reduces it to 0.21%.
Overall 22.7% instruction count reduction (26.1B -> 20.2B).

Claude 在用 callgrind 做效能分析,發現了一個 O(n×labels) 的二次方掃描佔了總編譯時間的 19.76%,修復後整體指令數降低了 22.7%。然後它把修復前後的資料都記錄下來。這和 buffa DESIGN.md 中的效能因果分析完全同構。

我猜測 buffa 的 AI 實踐也來自於這個專案。

docs_verified_2026_01_29.txt 是最驚人的檔案之一:Claude 自己審計了自己寫的文件,記錄了每個 README 中發現的不準確之處和修復:

Accuracy Audit (2026-02-03):
  src/frontend/README.md:
  - Fixed `$` in identifiers claim (always permitted, not gated by gnu_extensions)
  - Fixed Token described as tuple -> struct with named fields
  - Fixed Parser::new() signature (takes only Vec<Token>)

這直接呼應了 Carlini 在部落格中的警告:"The docs may be wrong and make claims that are false"。Claude 意識到了自己的文件可能不準確,所以建了一個審計機制。但注意,這個審計是 Claude 自己做的,沒有外部 evaluator。這就是為什麼 Carlini 仍然說「文件可能有錯」,自審的可靠性有限,和 harness design 部落格中「AI 自評系統性過於寬容」是同一個問題。

projects/cleanup_code_quality.txt 這個檔案是 Claude 的程式碼品質改進跟蹤。它列出了「一個 Rust 專家會標記的問題」:

Items a Rust expert would flag, roughly ordered by impact:
1. [DONE] GVN pass parameter threading -> GvnState struct
   - gvn_dfs had 14 params, process_block had 10 params
2. [DONE] Functions with 10-20+ parameters
   - parse_declaration_rest: 22 params -> DeclContext struct
3. [PARTIAL] Visibility: was 836 pub + 18 pub(crate), now improved

對比 buffa 的 rust-code-reviewer.md 的 16 個維度(後面介紹),Claude 在這裡自己發明了一個簡化版審查框架。但它的覆蓋面遠不如 rust-code-reviewer(見附錄詳細解讀),只關注了引數過多、可見性過寬、字串分配、程式碼嵌套等「結構性」問題,完全沒有 unsafe 安全論證、並發安全、API 設計品味這些需要判斷力的維度。

這恰恰驗證了 Anthropic 官方 harness design 部落格的核心發現:AI 自審的維度和深度不如外部審查。

claudes-c-compiler 專案中我們可以提煉出的 AI 編碼實踐可以總結出以下幾點:

  • Claude 自然趨向結構化。沒有人告訴 Claude 要在 current_tasks/ 檔案中寫 "Files to modify" 列表或 "Started" 時間戳。它自己發展出了這種半結構化格式。這說明在長期執行的專案中,AI 會自然地發明資訊管理結構,但品質取決於 prompt 的引導。Carlini 的 AGENT_PROMPT.md 可能包含了「跟蹤進度」的指令,Claude 據此演化出了這套檔案系統。
  • 150+ 專案追蹤是 "測試即導航" 的極端形式。new_projects_myasm.txt 追蹤了 150+ 個專案在 4 個架構上的編譯結果,每個 FAIL 都有根因分析和修復記錄。這是 Carlini "測試品質決定程式碼品質"原則的極端實現,Claude 把整個開源生態當作測試套件。
  • DESIGN_DOC.md 設定專案架構的全域性記憶。claudes-c-compilerDESIGN_DOC.md 有完整的管線圖、原始碼樹結構、資料流描述和「設計哲學」章節(Claude 自己寫的)。但對比 buffa 的 DESIGN.md(見附錄詳細解讀),它缺少兩個關鍵內容:決策演進歷史(為什麼不採用另一種做法)和被拒絕方案的基準測試資料。這些內容散落在 ideas/*.txt 檔案中,但沒有被整合到 DESIGN_DOC 裡。

這說明 Claude 能寫出好的架構文件,但不會自發地把決策歷史提煉成防退化的知識。在 buffa 中,是人類(McGinniss)決定在 DESIGN.md 中記錄 Cell<u32>AtomicU32 的演進和預掃描的失敗資料。Claude 也記錄了類似資訊(ideas/ 下的修復記錄),但沒有把它們提升到「防止未來 AI 退化」的設計文件級別。

對於為什麼實現語言選擇 Rust,而不是 C/Cpp?這個答案官方並沒有給出顯式論證,但 10 萬行 Rust 程式碼中unsafe 區塊這個事實本身就是最有力的回答。

如果用 C/Cpp 寫 C 編譯器,AI 生成的程式碼中每一個指標操作、每一個陣列訪問、每一個記憶體分配都可能藏著 bug,而且這些 bug 在編譯時不會被捕獲,只有在運行時崩潰或產生錯誤結果時才被發現。

用 Rust,編譯器本身就是第一道審查。16 個並行的 AI agent 無人監督地跑了兩週,如果生成的程式碼有記憶體安全問題,cargo build 直接拒絕編譯。不需要人類 review,不需要 sanitizer,不需要 fuzzer。Rust 的型別系統把一大類 bug 從「運行時發現」變成了「編譯時阻止」。

對於一個 --dangerously-skip-permissions 全自主運行的場景,這不是「加分項」而是「必要條件」。

buffa:AI 主導的生產級 protobuf 函式庫

buffaconnect-rust(後面介紹)的 protobuf 基礎層,由 Anthropic 安全工程師 Iain McGinniss 主導架構設計,Claude 完成大部分編碼。它填補了 Rust protobuf 生態的空白:prost(事實標準)處於被動維護、不支援 protobuf editions;Google 官方 protobuf-v4 支援 editions 但需要 C 編譯器。buffa純 Rust、no_std 相容的實作,以 editions 為核心抽象,通過了 protobuf 二進位制和 JSON 一致性測試全集

核心創新是雙層型別系統。每條 protobuf 訊息生成兩種 Rust 型別:MyMessage(owned,堆分配)和 MyMessageView<'a>(零拷貝借用)。view 模式解碼達到 1,772 MiB/s,比 prost156%OwnedView<V> 透過 transmute 將 view 的生命週期擴充套件為 'static,使其可安全跨越 async 邊界。

與 C 編譯器不同,buffa 被明確定位於生產級程式碼。「已在 Anthropic 生產環境運行」,而非能力展示。區別在於驗證的完整性:buffa 有權威的、完備的測試套件(Google 的 protobuf conformance),而 C 編譯器的驗證雖然廣泛但不完備。

Anthropic 開源的三個 Rust 專案中,buffa 是最值得研究 AI 編碼實踐的一個,因為它處在一個獨特的位置它是 AI 寫的程式碼中,唯一被明確用於生產環境的。

claudes-c-compiler 是能力展示,README 寫著 "I do not recommend you use this code"。connect-rust 沒有 AI 生成聲明,核心程式碼是人寫的。只有 buffa 同時標註了 "Written by Claude ❣️" 和「已在 Anthropic 生產環境運行」。

這意味著 buffa 的工程實踐不是學術討論,它們經過了生產環境的檢驗。從 buffa 中提取的方法論是「被證明有效的」,而不是「聽起來合理的」。

而且 buffa 寫的是 protobuf runtime + codegen 狀態機複雜(wire format)、邊界條件極多(unknown fields / enum / recursion)、效能敏感(decode loop)、API 設計要求高(Rust 型別系統 + 人體工學)、需要長期維護。這是目前 AI 最容易翻車的程式碼型別。buffa 沒有翻車。

由於篇幅有限,我會在下一篇文章裡單獨拆解 Buffa 的 AI 工程實踐。

connect-rust:人類主導的 RPC 框架

connect-rustConnectRPC[6] 協議的 Rust 實作,同樣由 McGinniss 開發。它基於 Tower 中介軟體框架,在同一組 handler 上同時支援 Connect、gRPC 和 gRPC-Web 三種協議。Anthropic 已提交 RFC 007[7],申請將其作為 ConnectRPC 的標準 Rust 實作。

ConnectRPC 是 Buf Technologies 創建的一個 RPC 協議,目前是 CNCF(雲原生計算基金會)Sandbox 專案。它的核心定位是gRPC 的簡化替代品,解決 gRPC 在實際使用中的幾個痛點:

  • gRPC 的問題:強制要求 HTTP/2(很多基礎設施不支援)、自定義的二進位制幀格式(無法用 curl 除錯)、瀏覽器端需要額外的 grpc-web 代理、錯誤資訊是二進位制編碼的 protobuf(不可讀)。
  • ConnectRPC 的解決方案:在 HTTP/1.1 和 HTTP/2 上都能工作、unary RPC 就是普通的 POST 請求(可以用 curl 直接調用)、錯誤資訊是 JSON、瀏覽器原生支援(不需要代理)、同時相容 gRPC 和 gRPC-Web 協議(同一組 handler 三種協議通吃)。

官方已有 Go、TypeScript、Swift、Kotlin、Python 的實作。Rust 一直是缺失的。

目前 connect-rust 的優勢:

  • 效能資料驚人:延遲僅為 tonic 的約一半(1.95× 更低),高並發(c=256)下吞吐比 tonic 高 33%(112K vs 84K req/s)。CPU profiling 顯示分配器壓力僅佔 3.6% CPU(tonic+prost 為 9.6%)。
  • connect-rust 通過了全部 12,800+ 項一致性測試,修復了包括解壓縮炸彈和無界 TLS 握手超時在內的多個安全漏洞。

和前面兩個專案的關鍵區別是,connect-rust 沒有 "Written by Claude" 標記。倉庫有 .claude/agents 目錄(包含 rust-code-reviewer.md),說明 AI 參與了程式碼審查等輔助環節,但核心程式碼由人類編寫。

connect-rust 這個專案中雖然是人類主導,但也有讓 AI 進行程式碼 Review。所以我在附錄裡增加了 rust-code-reviewer.md 的詳細解讀。

另外兩個 fork 的 Rust 專案暴露的生產環境需求

除了三個原創專案,Anthropic 還 fork 了兩個 Rust 生態的關鍵基礎函式庫,並對它們做了實質性修改。這兩個 fork 不是「鎖版本」的保險性操作,它們各自修復或增加了只有高並發生產環境才會暴露的問題。

tokio fork:排程器卡頓檢測

Anthropic 的 tokio fork 有 6 個已合併 PR。其中 5 個是 CI/釋出基礎設施(Artifactory 釋出流水線、OIDC token 認證等),說明 fork 後的 tokio 透過內部私有 Artifactory 倉庫發布為內部 crate。唯一的程式碼修改是:

feat: add scheduler stall detection — 添加非同步排程器卡頓檢測功能。

tokio 的 work-stealing 排程器在正常情況下,任務在多個 worker 執行緒間快速流轉。但如果某個任務阻塞了 worker 執行緒(意外的同步 IO、持鎖時間過長、CPU 密集計算未 yield),整個排程器的吞吐會悄無聲息地降級。原版 tokio 沒有內建機制檢測這種情況。

結合 Anthropic 的使用場景,connect-rust 在高並發下每秒解碼 560 萬條日誌,推論服務跨數千加速器路由,排程器卡頓哪怕幾毫秒都會造成請求延遲尖刺。這個功能讓運維團隊能實時發現哪個 task 卡住了排程器。它和 rust-code-reviewer.md(見附錄)中 "Observability" 維度(第 16 條:tracing spans、metrics exposure)直接呼應,排程器卡頓檢測本質上是運行時級別的可觀測性。

moka fork:並發快取的 TOCTOU 競態修復

moka 是 Rust 生態中最流行的高效能並發快取函式庫,對標 Java 的 Caffeine。Anthropic fork 了它並提交了一個修復嚴重並發 bug 的 PR:

fix: TOCTOU race in and_compute_with under multi-threaded tokio

問題出在 and_compute_with 方法——這個 API 的語義是「查到就返回,沒查到就算計並快取」,是並發快取最核心的操作。在 try_computetry_compute_if_nobody_else 中,waiter 在快取實際寫入之前就被從 waiter map 中移除了,創造了一個 TOCTOU 時間視窗:「並發調用者可以插入自己的 waiter → 讀到舊值 → 兩個調用者都基於過時資料執行寫入」。後果是多執行緒 tokio runtime 下靜默資料遺失,8 個並發寫入者的計數器測試中,10-15% 的增量被遺失。

修復方案是將 waiter 移除推遲到快取寫入完成之後,確保 waiter 在更新期間阻塞並發調用者。

fork 暴露了什麼?一些推論

Anthropic fork moka 說明其內部服務大量使用並發快取。結合技術棧,最可能的使用場景包括:

  • 推論服務的熱路徑快取。LLM 推論中最大的效能優化是 KV Cache 複用(多個請求共享 prompt prefix 的注意力計算結果)。快取「哪些 prefix 在哪個 GPU 上已計算好」的索引表需要極高並發讀寫,moka 的 and_compute_with(就是被修 TOCTOU 的那個方法)正是「查到就返回,沒查到就算計並快取」的模式。模型路由表(哪個請求發到哪個加速器叢集)也是典型的讀多寫少快取場景。
  • Token 計數與速率限制。按使用者、按 API key 的請求計數和配額追蹤。每個請求都要 increment 計數器。TOCTOU 導致「8 個並發寫入者遺失 10-15% 增量」,在速率限制場景下意味著使用者可以超額使用——這是直接的收入損失。
  • 認證 token 快取。JWT/OIDC token 的驗證結果快取。驗證需要密碼學操作(簽章驗證),結果可快取到過期時間。結合 rust-code-reviewer 中 Security 維度要求的 zeroize(敏感資料安全清零),token 快取過期後需要安全清零記憶體。
  • RPC 層的 schema 快取。buffa 的 JSON registry 和 Any registry 按 type URL 查詢訊息描述符,這種查詢在高吞吐 RPC 中每秒發生百萬次。

那個 TOCTOU bug 本身也很說明問題。10-15% 的遺失率在低並發下可能不明顯,但在 Anthropic 的規模上(數百萬使用者、數千加速器),意味著每秒有大量請求的計數或狀態被靜默遺失。這個 bug 一定是在生產環境中觀察到資料不一致(速率限制不準、快取命中率異常),然後構造了最小覆現才發現的。

兩個 fork 加在一起畫面很清晰:Anthropic 不是在「實驗 Rust」,他們在深水區運行 Rust 生產服務,遇到了只有高並發生產環境才會暴露的運行時級別問題,並且有能力在 tokio/moka 這個層面修復它們。

AI 參與程度的差異及其暗示

三個原創專案的對比揭示了 Anthropic 對 AI 編碼適用邊界的判斷:

C 編譯器適合 100% AI。有成熟的測試基礎設施(GCC torture test、大量開源專案作為驗證目標),任務高度可並行化(不同測試、不同檔案、不同後端),但程式碼品質不要求生產級。

buffa 適合 AI 主導。有完整的規格說明(protobuf wire format spec)、自動化驗證(conformance test suite)、高度區域性化(編碼一個 int32 不需要理解整個系統)、有限的決策空間。人類負責架構設計(DESIGN.md)和品味判斷。

connect-rust 需要人類主導。面臨協議互動的組合爆炸(Connect × gRPC × gRPC-Web × HTTP/1.1 × HTTP/2)、跨庫整合複雜度(Tower × hyper × rustls × tokio)、安全判斷需要攻擊者思維、API 設計是品味問題而非正確性問題。

共同點:五個專案都選擇了 Rust。對於 AI 編碼,Rust 的編譯器充當「第零道審查」。型別檢查器不會被說服、不會寬容、不會「覺得差不多就行了」。claudes-c-compiler 的零 unsafe 區塊證明了這一點。而兩個 fork(tokio 的排程器卡頓檢測、moka 的並發競態修復)則證明 Anthropic 的 Rust 服務已經進入需要在運行時層面定製的深水區。


三、官方 Harness Design 工程部落格的核心洞察

Prithvi Rajasekaran(Labs 團隊,2026 年 3 月釋出)的部落格解決了一個在 C 編譯器和 buffa 專案中都未被正面觸及的問題:AI 如何評判自己工作的品質?

質樸方案為什麼失敗

部落格開頭描述了一個實驗,讓單個 Claude agent 獨立完成一個完整應用。結果是:應用介面看起來還行,但核心功能根本跑不通。比如一個 2D 復古遊戲製作器,精靈編輯器能用,但實際遊玩時角色不響應任何輸入,實體定義和遊戲運行時之間的接線是斷的,而且 UI 上沒有任何提示告訴你在哪裡出了問題。

問題出在兩個層面。第一是上下文退化:隨著上下文視窗填滿,模型的連貫性下降。部分模型(如 Sonnet 4.5)還會表現出「上下文焦慮」,提前收尾工作,因為它們以為快要到達上下文上限了。第二個問題更深GAN 結構的工程化應用中對抗思想的應用,我總結可以有三個方向:

  1. 生成、審查和驗證分離,產生對抗結構
  2. 不同的模型交叉審查,比如 claude code 和 codex,產生對抗結構
  3. 使用外部真實測試來驗證,產生對抗結構層:自我評估的系統性偏差。當被要求評價自己剛剛生成的程式碼時,AI 會自信地表揚那些,在人類看來明顯平庸的工作成果。這種偏差在主觀任務(前端設計)上最嚴重,但即使是有可驗證結果的任務(功能正確性),AI 也會「說服自己」某個 bug 其實不算嚴重。

這和 buffa 專案形成了有趣的對比。buffa 透過 Google 的 protobuf conformance test suite 來驗證正確性,這是一個外部的、獨立的、權威的測試套件,AI 的自我評估完全不參與。claudes-c-compiler 用 GCC torture test 和 150+ 個開源專案做驗證,同樣繞開了 AI 自評。但在沒有這種權威外部測試套件的領域(比如「這個前端設計好不好看」),自評偏差就成了核心障礙。

GAN 結構的工程化應用

Rajasekaran 從 GAN(生成對抗網路)中借鑑了核心思路:Generator 和 Discriminator 的對抗驅動品質提升。

GAN(Generative Adversarial Network,生成對抗網路)是 2014 年 Ian Goodfellow 提出的一種深度學習架構。它的核心思想極其簡潔:讓兩個神經網路互相博弈,一個造假,一個驗假,在對抗中共同進步。Generator(生成器),目標是生成儘可能逼真的假資料(比如假圖片)。它從隨機噪聲出發,學習輸出看起來像「真實資料」的東西。Discriminator(判別器),目標是區分真實資料和 Generator 生成的假資料。它接收一張圖片,輸出一個機率:「這是真的還是假的?」。如果 Generator 相當於偽鈔製造者,Discriminator 則相當於驗鈔員。偽鈔越來越真,驗鈔員越來越精,最終偽鈔製造者的水平被逼到極致。

他設計了一個三 Agent 系統:

Planner,把使用者的 1-4 句話擴充套件為完整的產品規格。這個 agent 被刻意約束為「只寫產品上下文和高層技術設計,不寫具體實現細節」。理由是:如果 planner 試圖在前期指定細粒度的技術細節,一旦某個細節搞錯,錯誤會沿著管線級聯到所有下游實現中。約束交付物,讓執行者自己找路徑。這和 buffa 的設計原則("descriptor-centric",只給 codegen 一個結構化輸入,讓它自己決定怎麼生成 Rust 程式碼)是同一個哲學。

Generator,按 sprint 逐個實現功能,使用 React + Vite + FastAPI + SQLite 技術棧,有 git 做版本控制。每個 sprint 開始前,generator 和 evaluator 會協商一個 sprint contract,雙方約定這輪做什麼、怎樣算完成。這個 contract 存在的原因是產品 spec 被刻意保持高層次(避免 planner 細節出錯),需要一個中間步驟來橋接「使用者故事」和「可測試的實現」。generator 提出方案,evaluator 稽核方案是否對齊 spec,雙方迭代直到達成一致,然後 generator 才開始寫程式碼。

這個 sprint contract 機制和 buffa 的 CLAUDE.md 有異曲同工之妙。CLAUDE.md 規定了「改了 codegen 就要重新生成型別」、「提交前跑 reviewer agent」,本質上也是在程式碼編寫之前或之後嵌入強制檢查點。區別是 buffa 的檢查點由人類預定義,harness 的 contract 由兩個 agent 動態協商。

Evaluator,這是整個架構中最關鍵的角色。evaluator 透過 Playwright MCP 像真實使用者一樣與運行中的應用互動,導航頁面、截圖、點選按鈕、填表單、檢查 API 響應和資料庫狀態。它不是看靜態程式碼或截圖打分,而是實際操作應用後再給出評判。每個 sprint 結束後,evaluator 按預定義的評分標準(稍後詳述)逐條打分,任何一條低於閾值則 sprint 失敗,generator 拿到具體反饋後重做。

Evaluator 透過 Playwright 做端到端測試的思路,和 Carlini 在 C 編譯器專案中用 GCC 作為「已知正確 oracle」來驗證編譯結果,本質上是同一個模式,用外部的、客觀的驗證來替代 AI 的自我評估。buffa 用 Google conformance test,C 編譯器用 GCC + 150 個開源專案,harness design 用 Playwright 端到端互動。介質不同,原理一致。

GAN 結構的工程化應用中對抗思想的應用,我總結可以有三個方向:

  1. 生成、審查和驗證分離,產生對抗結構
  2. 不同的模型交叉審查,比如 claude code 和 codex,產生對抗結構
  3. 使用外部真實測試來驗證,產生對抗結構

三個方向對應了三種不同的「判別器」來源,構成了一個從弱到強的對抗梯度。

方向一:角色分離產生的內部對抗

同一個模型(甚至同一家的模型),但拆成不同角色、不同權限、不同 prompt。對抗來自職責的結構性分離

這是 Anthropic 實踐中證據最充分的方向。buffarust-code-reviewer(Opus,只讀權限,16 維度)審查 Claude Sonnet 寫的程式碼。Harness Design 的 Generator-Evaluator 迴圈。claudes-c-compiler 的 "編碼 agent" vs "程式碼品質 agent" vs "去重 agent"。

對抗強度取決於三個設計引數:

模型層級差,buffa 用 Sonnet 寫、Opus 審。審查者比生成者「聰明」,這產生了真實的判斷力落差。如果用同一個模型同時做生成和審查,對抗會弱化。Harness Design 部落格發現 evaluator 預設仍然對 LLM 輸出寬容,需要額外校準。

權限不對稱,reviewer 只有 Read/Glob/Grep,不能改程式碼。這個約束看起來是限制,實際上是對抗結構的保障。如果審查者能改程式碼,它就會傾向於「改一下就過了」而不是嚴格打回。

評判標準的外化,16 個審查維度、四維前端評分體系、sprint contract。標準不在 agent 的腦子裡而在檔案裡,可審計、可校準、可迭代。

這個方向的儕限是,對抗的天花板是模型本身的判斷力。 兩個 Claude 之間的對抗再怎麼設計,也超不過 Claude 對問題的理解深度。Harness Design 部落格坦承即使校準後仍有未被發現的深層 bug。

方向二:跨模型交叉審查產生的異構對抗

不同廠商的模型有不同的訓練資料、不同的對齊方式、不同的盲區分佈。用 Claude 寫、用 GPT 審(或反過來),對抗來自認知盲區的不重疊

這是 Anthropic 公開材料中沒有直接實踐的方向,他們的專案全部使用自家模型。但從對抗理論的角度看,這個方向的對抗強度理論上更高:

Claude 可能系統性地在某類模式上寬容(比如對自己生成的程式碼風格天然熟悉),換一個模型審查就能打破這種「同源偏見」。就像人類團隊中,同一個學校出來的工程師容易有相似的盲區,引入不同背景的人能發現更多問題。

實操中的難點是標準對齊。buffa 的 rust-code-reviewer.md 是為 Claude 寫的,16 個維度的優先順序排序、輸出格式要求、few-shot 校準,都是針對 Claude 的行為特徵調過的。換成 Codex 或 Gemini 來讀同一個 prompt,審查品質不一定更好,因為它們對 prompt 的響應模式不同。

但這個方向有一個獨特的優勢:防止單點失敗。如果整個工具鏈都依賴同一個模型,這個模型的系統性缺陷就是不可發現的。claudes-c-compiler 的程式碼品質被 Carlini 描述為「合理但遠非專家級」,如果用一個對 Rust idiom 有不同偏好的模型來審查,可能會發現 Claude 系統性地忽略了某些模式。

方向三:外部真實驗證產生的絕對對抗

判別器不是另一個 AI,而是現實世界本身。程式碼要麼通過測試要麼不通過,要麼能編譯 Linux 核心要麼不能,要麼 Playwright 能點通流程要麼點不通。

這是三個方向中對抗強度最高的,因為現實世界不會被說服、不會被校準、不存在寬容偏差。

在 Anthropic 的實踐中,這個方向有四種具體形態:

權威測試套件,buffa 用 Google protobuf conformance test,claudes-c-compiler 用 GCC torture test(99% 通過率)。這些測試由第三方維護,覆蓋了人類和 AI 都可能遺漏的邊界條件。

真實專案編譯,C 編譯器用 150+ 個開源專案(SQLite、Redis、PostgreSQL、FFmpeg、Linux 核心)作為整合測試。每個專案都是幾十萬行程式碼中無數隱含約束的總和,比任何人為設計的測試套件都更不可預測。

端到端使用者互動,Harness Design 的 Evaluator 透過 Playwright MCP 實際操作應用。不是檢查程式碼邏輯,而是檢查「使用者能不能完成任務」。

已知正確實現對比,C 編譯器用 GCC 作為 oracle。隨機選檔案用 GCC 編譯、用 Claude 編譯,對比結果。這是最純粹的對抗——不需要定義什麼是「正確的」,只需要和已知正確的實現對比。

這個方向的儕限是,不是所有品質維度都有外部驗證。 「程式碼能不能跑」有外部驗證(測試),「API 設計好不好」沒有(品味)。「前端好不好看」部分有(Playwright 能驗證可用性),部分沒有(美學是主觀的)。這就是為什麼需要三個方向互補。

三個方向的互補關係

三個方向不是替代關係,而是覆蓋不同品質維度

品質維度
方向一(角色分離)
方向二(跨模型)
方向三(外部驗證)
功能正確性
弱(AI 可能共享盲區)
中(不同盲區分佈)
(測試通過就是通過)
API 品味
(reviewer 16 維度)
強(不同模型有不同審美)
無(沒有客觀標準)
效能
中(能審 benchmark 資料)
(benchmark 不騙人)
安全性
中(能審 unsafe 論證)
強(不同攻擊者視角)
中(fuzzer / sanitizer)
可維護性
(程式碼風格審查)
弱(沒有自動化指標)

buffa 同時使用了方向一和方向三:reviewer agent 做角色分離審查(方向一),conformance test 做外部驗證(方向三)。C 編譯器主要依賴方向三(GCC oracle + 150 個專案),輔以方向一(程式碼品質 agent)。Harness Design 三個方向都用了:Generator/Evaluator 分離(方向一)、Playwright 端到端測試(方向三),但沒有跨模型(方向二)。

最完整的實踐應該是三層疊加:外部測試套件兜底功能正確性,跨模型審查捕捉單一模型的系統性盲區,同模型角色分離處理品味和風格等主觀維度。目前 Anthropic 的公開實踐覆蓋了一和三,方向二是你指出的一個有價值的空白。

自評偏差的解剖

部落格對自評偏差的分析值得展開。單純把「做」和「評」分給不同 agent 不夠,分離後的 evaluator 仍然是一個 LLM,預設對 LLM 生成的輸出寬容。Rajasekaran 發現,他需要反覆閱讀 evaluator 的日誌,找到 evaluator 判斷偏離自己預期的地方,然後更新 evaluator 的 prompt 來修正這些偏差。這個校準迴圈經過了好幾輪才讓 evaluator 的評判達到他認為合理的水平。

即便如此,harness 的最終輸出仍然存在小的佈局問題、不直覺的互動、和未被充分測試的深層功能 bug。evaluator 的能力有上限——它在模型能力邊界附近的任務上最有價值,但對於超出模型理解範圍的問題(比如「這個遊戲關卡設計是否符合常識」),它和 generator 一樣無能為力。

這和 buffa 的 rust-code-reviewer.md 形成了直接對照。reviewer agent 用 model: opus(最強模型做審查)、tools: Read, Glob, Grep(只讀權限),以及 16 個明確的審查維度和結構化的輸出格式(Executive Summary → Findings by Category → Critical Issues → Recommended Improvements)。buffa 的審查框架是人類預定義的、靜態的、有明確標準的;harness 的 evaluator 是動態的、基於運行時互動的、需要迭代校準的。兩者互補:buffa 的模式適合「程式碼品質可以透過靜態審查評判」的場景,harness 的模式適合「品質需要透過實際使用來驗證」的場景。

claudes-c-compiler 的做法則是第三種變體,程式碼品質 agent(cleanup_code_quality.txt)是 Claude 自己發明的簡化版審查框架,只覆蓋了引數過多、可見性過寬等結構性問題,缺少 unsafe 安全論證、API 品味等需要深層判斷力的維度。這驗證了 harness 部落格的核心論點:AI 自審的維度和深度天然不如外部審查

前端設計評分:主觀品質的分級化

在應用到全棧開發之前,Rajasekaran 先在前端設計領域做了實驗。他為 generator 和 evaluator 共同定義了四個評分維度:

  • Design Quality(設計品質):顏色、排版、佈局、意象是否組合成了一個有統一情緒和身份的整體?
  • Originality(原創性):是否有自定義的設計決策,還是模板佈局、庫預設值、AI 生成模式?明確懲罰紫色漸變 + 白色卡片等 "AI slop"
  • Craft(技藝):排版層級、間距一致性、顏色和諧、對比度,技術執行力檢查
  • Functionality(功能性):獨立於美學的可用性評估

關鍵策略是加權 Design Quality 和 Originality,弱化 Craft 和 Functionality。因為 Claude 在 Craft 和 Functionality 上預設就不差,技術能力是模型天然具備的。但在設計品質和原創性上,Claude 傾向於生產平庸但「安全」的輸出。這和 buffa 的 rust-code-reviewer.md 把 API Design 排第一、Unsafe 排第八是同一個邏輯:在模型已經擅長的維度上加碼沒有意義,要在模型容易出錯的維度上加壓

一個意外發現是:評分標準的措辭會直接塑造生成的輸出。在標準中包含「最好的設計是博物館級的」這樣的措辭,推動了設計向特定的視覺方向收斂。這意味著評分標準不只是評判工具,給 generator 和 evaluator 看同一套標準,等於在生成方向和評判方向上同時施加了同一種品味壓力。這讓人聯想到 buffa 的 DESIGN.md 同時被 Claude Code(編碼 agent)和 rust-code-reviewer(審查 agent)讀取,設計原則既指導了程式碼的寫法,也定義了審查的標準。

在一個荷蘭藝術博物館網站的案例中,generator 經過 9 輪迭代後產出了一個乾淨的深色主題著陸頁,視覺上打磨過,但在預期範圍內。然後在第 10 輪,它徹底推翻了之前的方案,把網站重新構想為一個空間體驗:CSS 透視渲染的方格地板、自由懸掛在牆上的畫作、透過門洞而非滾動或點選來導航畫廊房間。這種創造性跳躍是 Rajasekaran 之前從未在單輪生成中見過的,它來自對抗壓力的持續積累。

從 Opus 4.5 到 4.6 的 Harness 演進

部落格中記錄了一個重要的演進過程。最初的完整 harness 是為 Opus 4.5 設計的,包含 sprint 分解、context reset(上下文重置)和每 sprint 做 QA。當 Opus 4.6 釋出後,Rajasekaran 逐一移除元件來測試哪些仍然承重。

Context Reset vs Compaction,這是一個關鍵區分。Compaction(壓縮)是把早期對話摘要化,同一個 agent 繼續工作。Context Reset(重置)是徹底清空上下文,啟動新 agent,透過結構化檔案傳遞狀態。Sonnet 4.5 的「上下文焦慮」(模型以為快到上下文上限了就開始草率收尾)嚴重到 compaction 不夠用,必須用 reset 給 agent 一個乾淨的起點。Opus 4.6 基本消除了這個問題,能連續工作兩個多小時不 reset。

claudes-c-compiler 走了更極端的路,每個 session 都是完全重置,2,000 個 session 中沒有任何 compaction 或 context carry-over。Claude 透過在檔案系統中寫 current_tasks/ideas/ 來補償會話歷史的缺失,把本該存在於對話歷史中的推理過程序列化了 git 倉庫。這是 "context reset + 檔案系統 handoff" 的最純粹形式。

Sprint 分解的取消,Opus 4.6 的能力提升讓 sprint 分解變得不必要。模型可以自主工作兩小時以上而不喪失連貫性,不再需要外部把任務切成小塊。

Evaluator 的角色變化,sprint 取消後,evaluator 改為在整個構建結束後做一次通過。這改變了 evaluator 的承重程度:對於模型已經能獨立處理好的任務,evaluator 成了不必要的開銷;但對於仍處於模型能力邊界的部分,evaluator 繼續提供真實的品質提升。

部落格由此得出一個普適原則:harness 的每個元件都編碼了「模型不能做什麼」的假設,這些假設會隨模型升級而過時。 新模型釋出時,正確的做法是逐一剝離不再承重的元件,同時增加新元件來實現此前不可能的更高能力。正如部落格最後所說:「有趣的 harness 組合空間不會隨模型進步而縮小。它會移動。」

這個原則也回溯性地解釋了 buffa 和 C 編譯器之間的架構差異:buffa(Opus 4.6 時代)不需要 context reset 和 sprint 分解,CLAUDE.md 只有兩條簡潔的規則;C 編譯器(同為 Opus 4.6)用了極端的每 session 全重置,但不需要 evaluator,因為它有 GCC torture test 和 150 個開源專案作為外部驗證。每個專案的 harness 形狀不同,是因為它們編碼的「模型不能做什麼」的假設不同。

實際成本與產出

部落格給出了直接的成本對比資料:

模式
時長
成本
產出品質
單 agent(無 harness)
20 分鐘
$9
核心功能不能用
完整 harness(Opus 4.5)
6 小時
$200
16 功能、10 sprint,功能完整
簡化 harness(Opus 4.6)
~4 小時
$125
DAW 應用,可實際作曲

20 倍的成本差距換來了「核心功能能不能用」的質變——不是線性改進,而是跨越了可用性門檻。

簡化 harness 的 DAW(數位音訊工作站)執行細節也值得關注。三 agent 的時間分佈是:Planner 4.7 分鐘($0.46)→ 第一輪 Build 2 小時 7 分鐘($71)→ 第一輪 QA 8.8 分鐘($3.24)→ 第二輪 Build 1 小時 2 分鐘($37)→ 第二輪 QA 6.8 分鐘($3.09)→ 第三輪 Build 10.9 分鐘($5.88)→ 第三輪 QA 9.6 分鐘($4.06)

Build 佔了絕大部分成本,QA 很便宜但每輪都抓到了真實的問題,第一輪發現多個核心 DAW 功能是 "display-only"(能看不能用),第二輪發現音訊錄製仍然是 stub、clip 不能拖拽和切分。generator 在沒有外部檢查時會傾向於「做完表面」而跳過互動深度,這和單 agent 模式下遊戲製作器「看起來能用但實際不能玩」是同一個問題。

對比 claudes-c-compiler 的成本結構(兩週、~$20,000),harness design 的單次執行便宜得多,但產出的複雜度也不同,一個是 10 萬行編譯器,一個是一個功能完整的 web 應用。有意義的比較是:在兩種方案中,人類的時間都不是花在寫程式碼上,而是花在設計 harness(測試環境、評分標準、agent 架構)上


四、綜合提煉:AI 編碼的工程實踐

以下實踐從五個專案(C 編譯器、buffa、connect-rust、tokio fork、moka fork)和兩篇部落格(C 編譯器 agent team、harness design)中綜合提煉。

DESIGN.md 是 AI 的長期記憶

buffaDESIGN.md 是整個專案中資訊密度最高的檔案。

CLAUDE.md 中寫道 See DESIGN.md for the architectural overview,意味著 Claude Code 每次啟動新會話時都會讀取它。

有人可能好奇,為啥這個檔案不命名為 Arch.md 呢?

  • Arch.md 暗示的是「系統長什麼樣」。模組劃分、資料流、介面定義。這些是靜態的、描述性的。
  • DESIGN.md 暗示的是「為什麼系統長這樣」。決策過程、被拒絕的方案、權衡取捨。這些是動態的、論證性的。

buffaDESIGN.md 中,真正的架構描述(模組邊界、資料流圖、型別對映)大約只佔 35%。剩下 65% 是五種功能性內容:

內容類型
佔比
對 AI 的作用
競品對比表
~5%
防止 AI 建議「用現有庫」或「fork X」
設計原則
~5%
硬約束排序,解決方案衝突
模組邊界
~30%
告訴 AI 每個檔案該改什麼、不該改什麼
決策演進歷史
~35%
防止 AI 退化到已否決方案
效能因果分析
~25%
防止 AI 「優化掉」有意的開銷

後兩種,決策歷史被拒絕方案,是專門為 AI 協作增加的。它們回答「程式碼為什麼不是別的樣子」,這正是 AI 最容易犯錯的地方。

buffa 是人機協作的,人類把決策歷史寫進文件,所以文件的性質從「架構描述」升級為「設計論證」。

C 編譯器專案中,Carlini 讓 Claude 自己維護 README 和進度檔案來解決同樣的問題。但這種自維護文件的品質顯然不如人類預寫的 DESIGN.md。這也解釋了為什麼 buffa 是生產級程式碼,而 C 編譯器的程式碼品質「遠非專家級」。

詳細的逐段解讀見附錄 A:buffa-design-annotated.md

審查者與執行者必須分離

這是三個資訊源中最一致的發現:

buffa/connect-rustrust-code-reviewer.mdmodel: opus, tools: Read, Glob, Grep——只讀權限)做審查,審查者不能修改程式碼。

C 編譯器 用專門的 agent 角色做程式碼品質審查和去重,與編碼 agent 分離。

Harness Design 發現 AI 自我評估時系統性過於寬容,必須用獨立 evaluator。調一個 evaluator 使其挑剔,遠比讓 generator 自我批評容易。

三個來源獨立指向同一個結論:做和評不能是同一個 agent。 這是 GAN 對抗結構在工程實踐中的自然表達。

rust-code-reviewer 的 16 個審查維度也值得關注,API Design 排第一(可用性大於一切),Unsafe 排第八(安全是好設計的結果,不是獨立目標),Security 包含 timing-safezeroize(暴露了處理敏感資料的需求)。

詳細的逐段解讀見附錄 B:rust-code-reviewer-annotated.md

測試品質決定程式碼品質

C 編譯器部落格說得最直接:Claude 會自主地去解決你給它的問題,所以任務驗證器必須近乎完美,否則 Claude 會解決錯誤的問題。

Harness Design 部落格用 Playwright MCP 做端到端驗證,evaluator 像真實使用者一樣導航頁面、截圖、點選按鈕。Sprint 3 單個 sprint 就有 27 條測試標準。

buffa 依賴 Google 的 protobuf conformance test suite 作為「真理之源」。

三者的共同模式是:人類的核心工作從「寫程式碼」變成了「寫測試和設計驗證環境」。 測試不是驗收工具,而是 AI 的導航系統。

但測試要為 AI 而寫,不是為人類而寫:

  • 不列印幾千行無用輸出(上下文汙染)
  • 錯誤資訊用 ERROR 前綴方便 grep
  • 預計算彙總統計避免 AI 手動分析
  • --fast 選項跑隨機取樣(解決 AI 的「時間盲」)
  • 測試名本身是規格說明(explicit_presence_with_zero_value

用基礎設施約束 AI 的行為

所有專案都展示了同一個模式:用結構和工具約束 AI,而不是靠 prompt 說教。

專案
約束機制
解決的問題
buffa
CLAUDE.md 強制提交前跑 reviewer agent
防止未審查的程式碼被提交
buffa
CLAUDE.md 強制 codegen 變更後重新生成型別
防止忘記同步步驟
C 編譯器
CI pipeline 阻止破壞已有程式碼的提交
防止 16 個 agent 互相覆蓋
C 編譯器
檔案鎖 + git 衝突
防止兩個 agent 做同一個任務
Harness Design
評分閾值——低於閾值 sprint 自動失敗
強制品質底線
Harness Design
Sprint contract——動手前談妥完成標準
防止 generator 偏離規格
Rust 編譯器本身
型別檢查——記憶體安全問題編譯不過
AI 程式碼的「第零道審查」

記錄被拒絕的方案

buffaDESIGN.md 中的 "Rejected: Pre-scan capacity reservation for view Vecs" 完整記錄了兩種預掃描方案的基準測試結果(20-97% 效能回退)和失敗原因。docs/investigations/e0477-owned-view-send/ 記錄了完整的調查過程。

這是 AI 編碼中最容易被忽視但最有價值的實踐:防止 AI 退化到已被證偽的方案,這是 AI 編碼中最常見的品質問題之一。AI 看到程式碼中的 Vec 增長開銷,第一反應就是「預分配」。沒有被拒絕方案的記錄,每次新的 AI 會話都可能重新提出這個已經被證偽的「優化」。

上下文管理的三種策略

三個專案 + 兩篇部落格展示了三種不同的上下文管理方式:

靜態文件注入(buffa)。人類預寫 DESIGN.md,Claude Code 每次會話讀取。品質最高,但需要人類前期投入。

AI 自維護運行時文件(C 編譯器)。prompt 中指示 Claude 頻繁更新 README 和進度檔案。適合自主運行場景,但文件品質不如人類寫的。

Context Reset + 結構化 Handoff(Harness Design)。清空上下文啟動新 agent,透過 sprint contract 和評分報告傳遞狀態。Opus 4.5 強需要這個(有「上下文焦慮」),Opus 4.6 基本不需要。

選擇哪種策略取決於任務型別:人機協作用靜態文件,全自主用 AI 自維護,長時執行用 reset + handoff。但 Harness Design 部落格的重要發現是:這些策略的必要性隨模型升級而變化。 每個元件都編碼了「模型不能做什麼」的假設,新模型釋出時應該重新審視。

並行的關鍵在於「任務可分」

C 編譯器部落格提供了最深刻的並行化經驗:

當測試套件有幾百個獨立的失敗測試時,並行簡單。每個 agent 挑一個不同的失敗測試去修。但當 16 個 agent 編譯 Linux 核心時,它們全部卡在同一個 bug 上,互相覆蓋。

解決方案是用已知正確實現創造可並行子任務。用 GCC 隨機編譯大部分核心檔案,只讓 Claude 處理剩餘檔案。這讓每個 agent 修不同檔案的不同 bug。

這是一個通用模式:如果你的任務不可並行,找一個 "oracle" 來分割它。在 Harness Design 中,sprint 結構起到了類似作用,把一個大型應用拆成獨立的功能 sprint。

Agent 專業化

C 編譯器和 Harness Design 都展示了 agent 專業化的價值:

角色
C 編譯器中
Harness Design 中
buffa/connect-rust 中
規劃
Claude 自行分解任務
Planner agent
人類寫 DESIGN.md
編碼
主力編碼 agent
Generator agent
Claude(由 CLAUDE.md 指導)
審查
程式碼品質 agent
Evaluator agent
rust-code-reviewer(Opus,只讀)
去重
專門的去重 agent
文件
專門的文件 agent
人類維護 DESIGN.md
效能
专门的效能優化 agent
人類在 DESIGN.md 中定義效能邊界

審查/評估 agent 應該比編碼 agent 更「貴」buffa 用 Opus 做審查(Sonnet 做編碼),Harness Design 的 evaluator 用 Playwright 做端到端測試。判斷力比生成速度更值錢


五、可複用的方法論框架

文件的五層金字塔

綜上,我們可以提煉出一個 AI 協作文件體系:

層級
檔案
功能
讀者
L1
CLAUDE.md
操作指令。每次會話必讀。
AI agent
L2
DESIGN.md / 產品規格
長期記憶。架構決策和被拒絕方案。
AI agent + 人類架構師
L3
.claude/agents/*.md
專家角色。審查、測試等。
AI sub-agent
L4
程式碼註解
區域性上下文。每個 unsafe 的安全論證。
AI + 人類開發者
L5
docs/investigations/
調查日誌。為什麼不那樣做。
未來的修改者

傳統專案只需要 L4 和部分 L2。L1、L3、L5 是專門為 AI 協作增加的。Harness Design 部落格中的 sprint contract 和評分標準是 L2 的動態版本;C 編譯器中 Claude 自維護的 README 是 L2 的自動化版本。

五個核心原則

原則一:測試品質決定程式碼品質。 AI 會解決你給它的問題,所以驗證器必須近乎完美。測試為 AI 而寫(簡潔輸出、機器可解析、取樣模式解決時間盲)。

原則二:做和評必須分離。 AI 自評系統性過於寬容。獨立 evaluator + 只讀權限 + 高能力模型 = 可靠的品質反饋。

原則三:用基礎設施約束,不靠 prompt 說教。 CI pipeline、檔案鎖、型別檢查器、評分閾值——這些硬約束比「請寫高品質程式碼」有效得多。

原則四:記錄被拒絕的方案。 防止 AI 退化到已證偽方案是 AI 編碼中最獨特的文件需求。

原則五:Harness 隨模型升級而簡化。 每個元件編碼了「模型不能做什麼」的假設。新模型釋出時,剝離不再承重的元件,增加新元件以實現更高能力。

AI 編碼的適用邊界

維度
AI 擅長(buffa、C 編譯器)
人類擅長(connect-rust、tokio/moka fork)
輸入
完整的規格說明
模糊的生態約束
驗證
自動化測試套件
實際部署中的邊界情況
決策
在已知選項中選擇最優
發明新的抽象和 API
錯誤
可被 benchmark/test 捕獲
需要安全稽核/攻擊者思維
上下文
區域性、自包含
跨庫、跨層
並行
可分解為獨立子任務
不可分解的單體任務
層級
應用邏輯、編解碼
運行時內部、並發原語

最後一行是兩個 fork 新增的維度。tokio 的排程器卡頓檢測和 moka 的 TOCTOU 修復都屬於「運行時內部」,這類工作要求對非同步排程器的 work-stealing 演算法、並發資料結構的記憶體序等有深入理解,目前仍是人類工程師的領地。


六、結語

Anthropic 五個開源專案和兩篇工程部落格這七個資訊源,共同指向同一個底層哲學:

AI 編碼的品質上限不取決於模型能力,取決於你圍繞模型搭建的約束、反饋和驗證結構。

buffaDESIGN.md 是靜態的約束(人類預寫的長期記憶),C 編譯器的 CI 和測試 harness 是動態的約束(運行時的品質門禁),Harness Design 的 Generator-Evaluator 對抗是對抗性的約束(GAN 結構的工程化應用)。三種約束方式面向不同場景,但底層邏輯一致。

tokiomoka 的 fork 則揭示了另一個維度:AI 寫的程式碼最終要在真實的基礎設施上運行。buffaconnect-rust 進入生產環境、承受數百萬使用者的並發負載時,暴露的不再是 AI 編碼的問題,而是底層運行時和依賴函式庫的問題,排程器卡頓、並發快取競態。這些問題需要人類工程師在 tokio/moka 這個深度上排查和修復,是當前 AI 編碼能力邊界之外的工作。

Carlini 在 C 編譯器部落格結尾說他既興奮又不安。作為前滲透測試工程師,他說「程式員部署自己從未親自驗證過的軟體,這讓我真的擔心」。這個擔憂和 buffa 的做法形成了有意義的張力,buffa 通過了全部 conformance 測試,被用於生產環境;C 編譯器則明確標註了已知缺陷。區別在於驗證的完整性。 AI 寫的程式碼只有在驗證體系完備時才值得信任。

Anthropic 自己是這個方法論的最佳實踐者。他們比任何人都清楚 Claude 在哪些任務上可靠(buffa 的編解碼),在哪些任務上需要人類架構(connect-rust 的 RPC 設計),在哪些任務上可以全自主但不保證品質(C 編譯器的展示),在哪些任務上 AI 根本不應介入(tokio 排程器內部和 moka 並發原語的正確性修復)。

Harness Design 部落格的最後一句話值得作為全文的收尾:

「有趣的 harness 組合空間不會隨著模型進步而縮小。它會移動。AI 工程師的有趣工作是不斷找到下一個新組合。」


附錄

附錄 Abuffa-design-annotated.md — buffa DESIGN.md 的逐段中英文對照解讀 Gist[8]

附錄 Brust-code-reviewer-annotated.mdconnect-rust rust-code-reviewer.md 的逐段中英文對照解讀 Gist[9]

參考資料
[1]

connect-rust: https://github.com/anthropics/connect-rust

[2]

Building a C compiler with a team of parallel Claudes: https://www.anthropic.com/engineering/building-c-compiler

[3]

Harness design for long-running application development: https://www.anthropic.com/engineering/harness-design-long-running-apps

[4]

anthropics/tokio: https://github.com/anthropics/tokio

[5]

anthropics/moka: https://github.com/anthropics/moka

[6]

ConnectRPC: https://connectrpc.com/docs/protocol/

[7]

RFC 007: https://github.com/connectrpc/connectrpc.com/pull/334

[8]

buffa-design-annotated.md — buffa DESIGN.md 的逐段中英文對照解讀 Gist: https://gist.github.com/ZhangHanDong/f4ac670f2fdd939bc4355dad93df92b0

[9]

rust-code-reviewer-annotated.mdconnect-rustrust-code-reviewer.md 的逐段中英文對照解讀 Gist: https://gist.github.com/ZhangHanDong/ebc9577991d0a5ce94f1d91c5d64fe40


分享網址
AINews·AI 新聞聚合平台
© 2026 AINews. All rights reserved.