buffa 不是一個 protobuf 函式庫,它是一個典範。它展示了當 AI 撰寫系統層級程式碼時,人類和 AI 各自應該做什麼、不應該做什麼,以及用什麼樣的檔案和工具結構來控制協作品質的上限。
為什麼 buffa 值得單獨拆解
在 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 沒有翻車。
一、約束先行:DESIGN.md 作為 AI 的決策框架
1.1 八條設計原則 = AI 的硬約束集
buffa 的 DESIGN.md 開頭列出了八條設計原則:
1. Pure Rust, zero C dependencies.
2. Editions-first.
3. Correct by default.
4. Idiomatic Rust API.
5. Zero-copy read path.
6. Linear-time serialization.
7. no_std capable.
8. Descriptor-centric.
這些原則不是給人類讀的專案願景,它們是給 AI 的決策裁決規則。當 AI 面臨兩個實現方案的衝突時,這些原則按隱含優先順序提供了即時裁決:
- 「要不要引入一個 C 依賴來加速 UTF-8 驗證?」→ 原則 1 否決
- 「零拷貝和正確性衝突時聽誰的?」→ 原則 3 排在原則 5 前面,正確性贏
- 「要不要給 buffa 加 proto 解析功能?」→ 原則 8 說用
protoc/buf的descriptor,不自己解析
AI 最怕模糊需求,最擅長在約束內優化。這八條原則把 buffa 的設計空間從「無限可能」收窄到了一個有限的、AI 可以高效搜尋的空間。
1.2 競品對比表 = 防止 AI 建議「用現有函式庫」
DESIGN.md 開頭就放了一張競品對比表:
| Library | Pure Rust | Editions | Maintained |
|---------------|-----------|----------|------------|
| prost v0.13 | Yes | No | Passive |
| protobuf v4 | No (upb) | Yes | Active |
| rust-protobuf | Yes | No | Maintenance|
這張表的功能不是給人類做市場調研,它是給 AI 的決策錨點。沒有這張表,AI 在被要求「調研是否可以 fork prost 來支援 editions」時可能會花大量 token 分析。有了這張表,答案是即時的:prost 是 Passive 維護且不支援 editions,fork 不可行。這張表在每個 Claude Code session 開始時就被載入,消滅了一整類「為什麼不用 X」的無效討論。
1.3 模組邊界 = 告訴 AI 改哪個檔案
DESIGN.md 中約 30% 的篇幅用於描述每個 crate 的邊界,做什麼、不做什麼、哪些程式碼在哪個檔案:
WKT 的 wire format 在
src/generated/,JSON 和stdlib轉換在*_ext.rs。
這段話的價值不在於告訴人類「WKT 是預生成的」(人類看到 src/generated/ 目錄就知道了),而在於告訴 AI:修改 Timestamp 的 wire encoding 去 generated/,修改 RFC3339 格式化去 timestamp_ext.rs。在一個有幾十個檔案的專案中,AI 最常犯的錯誤之一是改錯檔案。模組邊界描述把這個錯誤率壓到接近零。
二、參數化而非分支:把複雜性前移到 codegen
2.1 Editions 作為核心抽象
buffa 的 codegen 內部沒有 if proto2 {} else if proto3 {} 的分支。所有行為差異都來自 resolved features 的不同值組合:
proto2 file → proto2 feature defaults
proto3 file → proto3 feature defaults
edition N → edition N defaults + overrides
codegen 只看 resolved features(FieldPresence::Explicit vs Implicit、EnumType::Open vs Closed),不看 syntax 版本。
對 AI 編碼的啟示很深:
| 壞模式 | 好模式 |
|---|---|
AI 寫 if/else runtime 分支 | AI 寫 codegen 生成靜態程式碼 |
| AI 管複雜狀態判斷 | AI 把狀態編譯為程式碼 |
| 動態行為 | 靜態展開 |
讓 AI 生成「確定性程式碼」,不要讓 AI 寫 runtime 分支邏輯。 因為分支邏輯的正確性依賴於對所有分支組合的理解,而靜態展開的正確性只依賴於每個展開實例的區域性正確性,後者是 AI 擅長的。
2.2 Descriptor-centric = 不讓 AI 做解析
buffa 不寫自己的 .proto 解析器。它依賴 protoc/buf 把 .proto 檔案解析成 FileDescriptorProto(一個結構化的 protobuf 訊息),然後 codegen 直接消費這個結構化輸入。
這是一個關鍵的能力邊界判斷:解析 .proto 檔案涉及模糊的語法邊界、複雜的 import 解析、特性繼承鏈。這些是 AI 容易出錯的領域。但從一個已解析的 descriptor 生成 Rust 程式碼是高度結構化的輸入明確、輸出明確、可自動化驗證。
buffa 把「AI 不擅長的部分」(解析)交給了已有的可靠工具(protoc),把「AI 擅長的部分」(從結構化輸入生成程式碼)留給自己。這不是偷懶,而是精確的能力分配。
三、雙層型別系統:AI 寫效能程式碼的結構性模板
3.1 Owned + View 的分離
buffa 為每條 protobuf 訊息生成兩種 Rust 型別:
// Owned:堆分配,用於構建和修改
pub struct Person {
pub name: String,
pub id: i32,
pub address: buffa::MessageField<Address>,
}
// View:零拷貝,用於高效能讀取
pub struct PersonView<'a> {
pub name: &'a str,
pub id: i32,
pub address: buffa::MessageFieldView<AddressView<'a>>,
}
如果讓 AI 直接寫一個「既好用又快」的型別,它會掙扎,好用(String)和快(&'a str)在 Rust 中是矛盾的。但如果你給 AI 一個結構性模板,「每個訊息生成兩個型別,一個用 owned 型別一個用 borrowed 型別」,AI 就能在每個型別內部做對的事情。
這是一種結構性提示詞(structural prompt):不是告訴 AI「寫快一點的程式碼」,而是給它一個架構模式,讓效能自然從結構中湧現。
3.2 OwnedView:跨越 async 邊界的自引用包裝
PersonView<'a> 的生命週期 'a 阻止它滿足 'static bound,而 Tower services、tokio::spawn、BoxFuture<'static, _> 都需要 'static。OwnedView<V> 通過把 Bytes buffer 和 decoded view 綁在一起,用 transmute 把生命週期擴展到 'static。
DESIGN.md 中對這個 transmute 的安全性論證是三點式的:
Bytes是引用計數的,堆資料指標在 move 後穩定Bytes是不可變的,view 借用的資料不會被修改- 手動
Drop Impl,view 一定在 buffer 之前被釋放
這段論證不是給人類審程式碼看的,它是給下一個修改 OwnedView 的 AI session 看的。AI 在修改任何相關程式碼時,必須重新驗證這三個條件是否仍然成立。如果只寫「用了 transmute」而不寫「為什麼是 sound 的」,AI 在未來修改中可能會打破這些不變量而不自知。
四、決策演進歷史:防止 AI 退化
4.1 AtomicU32 vs Cell<u32>:已走過的路
DESIGN.md 中最有價值的內容是決策演進歷史。以 CachedSize 為例:
An earlier design used
Cell<u32>on the assumption that avoiding atomics would be faster... In practice,Relaxed-ordered atomic load/store compiles to identical machine instructions as a plain memory access on every major platform... Switching toAtomicU32makes messagesSync, enablingArc<Message>...
結構是:
- 我們曾經用了
Cell<u32>(看起來更高效) - 理由是「避免原子開銷」
- 但實際上
Relaxed在所有主要平台上零成本 - 改成
AtomicU32後訊息變為Sync(可以放進Arc) - 而且
DefaultInstancetrait 需要Sync——Cell直接編譯失敗
這段話的核心作用是阻止退化。 如果沒有這段歷史,一個新的 Claude session 看到 AtomicU32 可能會「優化」成 Cell<u32>,畢竟序列化是單執行緒的嘛,用原子操作看起來是浪費。但這段話告訴它:這條路走過了,走不通,不只是效能問題,還會導致編譯失敗。
4.2 被拒絕的預掃描方案:帶資料的「不要做」
Two approaches were benchmarked:
Vec's doubling strategy produces at most log2(n) allocations, and for typical protobuf maps/repeated fields (2-20 entries), that's only 2-5 allocations — cheaper than a full buffer scan.
- Per-field scanning: 20-97% regressions
- Single-pass counting: 5-40% regressions
預掃描看起來是一個「顯然正確」的優化,先數一遍有多少元素,然後一次性分配。任何有經驗的程式設計師(或 AI)都可能提出這個方案。但資料說不:兩種實現都更慢。
這種「被拒絕方案 + 基準測試資料」的記錄是專門為 AI 協作設計的。傳統檔案不記錄「我們沒做什麼」,但對 AI 來說,「不要做什麼」和「要做什麼」同樣重要,甚至更重要,因為 AI 沒有「上次試過了」的記憶。
4.3 調查日誌:完整的思考過程
docs/investigations/e0477-owned-view-send/ 是一個完整的調查日誌:嘗試了 trait_variant、RTN、各種 drop() 變體,最終發現問題在簽名層面而非函式體。這個檔案記錄了思考過程,不只是最終結論。
如果未來有一個 AI session 想「優化」OwnedView 的 Send impl、加回 V: 'static bound,這個調查日誌會阻止回退。「我們試過了,問題在 Rust 編譯器的 RPITIT desugaring bug(rust-lang/rust#128095),不是程式碼層面能解決的」。
五、審查 Agent:做和評的分離
5.1 rust-code-reviewer.md 的設計
buffa 的 CLAUDE.md 指示 Claude 在提交前運行 rust-code-reviewer agent。這個 agent 的元資料揭露了三個關鍵設計決策:
model: opus,用最強模型做審查,用 Sonnet 做編碼。判斷力比生成速度更值錢。
tools: Read, Glob, Grep,只讀權限。審查者不能修改程式碼。這強制了職責分離,避免了「自己改程式碼然後自己審過」的閉環。
16 個審查維度,從 API Design 到 Observability,覆蓋了 Rust 工程的完整光譜。API Design 排第一(可用性是最重要的品質維度),Unsafe 排第八(安全是好設計的結果,不是獨立目標)。
5.2 為什麼不讓 AI 自審
Anthropic 的 harness design 部落格發現:AI 評價自己的工作時,會系統性地給出過高評分。調一個獨立 evaluator 使其變得挑剔,遠比讓 generator 自我批評容易得多。
buffa 的 reviewer agent 是這個發現的工程化實現。編碼的 Claude(可能是 Sonnet)寫程式碼,審查的 Claude(Opus,只讀權限)評程式碼。兩者完全分離。
5.3 兩層檔案疊加 = 完整審查
rust-code-reviewer.md 提供通用 Rust 知識(16 個維度),CLAUDE.md 提供專案特定規則(「改了 codegen 要重新生成型別」)。兩層疊加產生了既有深度又有專案意識的審查。這是一個可複用的模式:把 rust-code-reviewer.md 拿到你自己的 Rust 專案裡,只需要寫好你自己的 CLAUDE.md。
六、程式碼註解面向未來的 AI 協作者
6.1 "Why" 註解 > "What" 註解
buffa 原始碼中的註解風格和普通開源專案有明顯區別:
// An unbounded `loop` is used intentionally: a bounded
// `for _ in 0..10` adds loop-counter overhead that LLVM cannot eliminate
這不是解釋「這是一個迴圈」,而是解釋「為什麼不用看起來更安全的有界迴圈」——因為 LLVM 無法證明迴圈一定在 10 次之內結束,保留了迴圈計數器開銷,編碼吞吐量暴跌 40%。它防止 AI 在未來「改進」時引入效能退化。
6.2 安全性論證內聯
每個 unsafe 塊都有 // SAFETY: 註解,不是形式化的一句話,而是完整的論證鏈:
// SAFETY: `Bytes` is StableDeref — its heap data never moves or is
// freed while we hold the `Bytes` value. We hold it in `self.bytes`,
// and drop order guarantees `view` drops first.
三個條件(StableDeref + 持有關係 + drop 順序),缺一不可。這種風格更像是 reviewer 要求的格式——AI 自發的 SAFETY 註解傾向於「safe because we know it's correct」這種廢話。
6.3 測試名即規格說明
fn explicit_presence_with_zero_value()
fn has_extension_returns_false_on_extendee_mismatch()
fn extension_or_default_zero_is_present_not_default()
這些測試名本身就是 specification。AI 在修改程式碼時可以用測試名理解預期行為,不需要額外的規格檔案。
七、效能工程的品味邊界
7.1 有意的效能開銷
DESIGN.md 列出了每項效能開銷的原因:
| 開銷 | 原因 | 能最佳化掉嗎 |
|---|---|---|
| Unknown field Vec::push | 往返保真度 | 不應該——這是核心功能 |
| EnumValue wrapper | 型別安全的 open enum | 不應該——否則退化為 prost 的 i32 |
| 遞迴深度檢查 | 支援遞迴訊息型別 | 不應該——否則觸發 E0275 |
| Box per nested message | 標準 Rust 所有權 | 可以用 arena,但違反原則 4 |
這張表是給 AI 的「不要最佳化掉」清單。AI 的第一反應可能是消除這些開銷,但表中明確說了:每一項都是有意的,對應一個不可放棄的功能。
7.2 可讀性紅線
Readability line we hold: fast-path/slow-path splits with a "why" comment are fine. Manual unrolling,
#[inline(always)]sprinkled defensively, SIMD intrinsics, orlikely()/unlikely()workarounds are not. The test: can a new contributor read the code, understand the fast path, and safely modify the slow path?
這是 AI 時代的效能工程哲學:可推理 > 極致微最佳化。
AI 天然傾向於激進最佳化(它不在乎可讀性),這條規則把 AI 拉回「人類可維護」的範圍。允許的最佳化(快速路徑分離 + why 註解)和不允許的最佳化(手動展開、SIMD、likely/unlikely)之間的界線是精確的。
這條值得展開講講。
buffa 的 DESIGN.md 在記錄完三個 profile-guided 最佳化之後,專門加了這段「可讀性紅線」聲明。它不是泛泛的程式碼風格指南,它是在具體展示了什麼最佳化是可以做的之後,明確劃定什麼最佳化不可以做。
這個順序很重要。先看它允許了什麼。
允許的:三個 profile-guided 最佳化
這三個最佳化都來自 connect-rust 整合過程中的 pprof 資料(LogRecord view-decode benchmark,每個請求約 350 個字串欄位、450 個 varint)。每一個都是「小的、有註解的、保持可讀性的」改動。
最佳化 1:encode_varint 無界迴圈
// 之前(某次重構後)
for _ in 0..10 {
if value < 0x80 {
buf.put_u8(value as u8);
return;
}
buf.put_u8((value as u8 & 0x7F) | 0x80);
value >>= 7;
}
// 之後(恢復為無界迴圈)
loop {
if value < 0x80 {
buf.put_u8(value as u8);
return;
}
buf.put_u8((value as u8 & 0x7F) | 0x80);
value >>= 7;
}
某次重構把 loop 改成了 for _ in 0..10,看起來更「安全」,因為有了顯式邊界。但 LLVM 無法證明內部的 return 一定在 10 次之內觸發,所以保留了迴圈計數器的維護開銷(比較、遞增、條件跳躍)。而 value >>= 7 單調遞減,終止是數學保證的,無界 loop 讓 LLVM 看到這一點,生成更緊湊的機器碼。
影響:~40% 編碼吞吐量恢復。
這個最佳化符合紅線:它是一個 fast-path 選擇(無界 vs 有界迴圈),有完整的 "why" 註解解釋為什麼不用看起來更安全的寫法,新貢獻者能讀懂,也能安全修改。
對 AI 的意義特別大:AI 很可能會「改進」這段程式碼。把 loop 改成 for _ in 0..10(因為有界迴圈「看起來更安全」)。DESIGN.md 中的記錄直接阻止了這個退化。
最佳化 2:Tag::decode 單位元組快速路徑
protobuf 的 field number 1-15 加上任意 wire type 編碼為單個位元組。這是最常見的情況(protobuf 風格指南推薦把高頻欄位放在這個範圍內)。原來的程式碼走通用的 decode_varint 路徑。雖然 decode_varint 內部也有單位元組快速路徑,但因為 #[inline] 提示不夠強,LLVM 經常不把它內聯進 per-field decode 迴圈。
解決方案是在 Tag::decode 中顯式加一個單位元組判斷:
// 快速路徑:field 1-15 只需要一個位元組
if buf.remaining() > 0 {
let byte = buf.chunk()[0];
if byte < 0x80 {
buf.advance(1);
return Ok(Tag { field_number: (byte >> 3) as u32, wire_type: ... });
}
}
// 慢速路徑:多位元組 varint
let v = decode_varint(buf)?;
影響:+12-29% view decode,+9-16% owned decode。
這也符合紅線:快速路徑/慢速路徑分離,有 "why" 註解,慢速路徑完全不受影響。新貢獻者可以安全修改慢速路徑而不用理解快速路徑的最佳化動機。
最佳化 3:strict_utf8_mapping opt-in
pprof 顯示 core::str::from_utf8 佔了 decodeCPU 的 11%。Rust 的 &str 型別有編譯時的 UTF-8 不變量,不能跳過驗證還保持 &str 型別。
解決方案不是跳過驗證(那會破壞 Rust 型別安全),而是在 codegen 層面提供選項:當 proto 的 utf8_validation = NONE 時,把字串欄位映射為 Vec<u8> / &[u8] 而不是 String / &str。呼叫者自己選擇是用 from_utf8(檢查)還是 from_utf8_unchecked(信任輸入)。
影響:~2× RPS 在 connect-rust 的可信輸入服務中。
這個最佳化的精妙之處在於:它不是執行時最佳化(沒有改 decode 迴圈的任何程式碼),而是 codegen 層面的型別選擇。通過改變生成程式碼的型別簽名(&str → &[u8]),把「是否驗證 UTF-8」的決策從 runtime 移到了 compile time。
而且它 default-off,proto2 的預設就是 NONE,如果自動啟用會破壞所有 proto2 字串欄位的型別。這種審慎態度本身就是可讀性紅線的體現:不搞預設的激進最佳化,讓使用者顯式 opt-in。
不允許的:紅線那邊的最佳化
DESIGN.md 明確列出了四類被禁止的最佳化手段:
手動迴圈展開(Manual unrolling),把 for i in 0..4 { process(data[i]); } 展開成四行 process(data[0]); process(data[1]); ...。這在 protobuf decode 的內層迴圈中確實能減少分支預測開銷,但展開後的程式碼失去了「這是一個迴圈」的語意。新貢獻者看到四行重複程式碼不知道它們是同一個邏輯的展開,修改時可能只改了其中一行。
防禦性 #[inline(always)]。Rust 的 #[inline] 是提示,#[inline(always)] 是強制。在 decode hot path 上到處撒 #[inline(always)] 確實能避免函式呼叫開銷,但代價是程式碼膨脹(每個呼叫點都會展開函式體)和編譯時間增加。更重要的是它傳達了一種「我不信任編譯器」的態度。这在人類維護的程式碼中是合理的(人類對 LLVM 的判斷可能更準),但在 AI 維護的程式碼中是危險的,因為 AI 不理解「為什麼這個函式需要 always inline 而那個不需要」的上下文。
SIMD intrinsics,用 _mm_cmpeq_epi8 之類的 SSE/AVX 指令做 varint 解碼或 UTF-8 驗證。效能提升顯著(simdjson 就是這個路線),但 SIMD 程式碼本質上是「用 Rust 語法寫組合語言」,只有理解目標架構指令集的人才能修改。這和 buffa 的設計原則 1(Pure Rust,zero C dependencies)也有衝突。SIMD intrinsics 雖然是 Rust 程式碼,但在 no_std 和跨平台場景下的行為不一致。
likely()/unlikely() workarounds。Rust stable 沒有 likely/unlikely 屬性(nightly 有 #[cold]),所以社群發明了各種 workaround(用 #[cold] 函式包裝慢速路徑、用 core::hint::black_box 欺騙最佳化器等)。這些 trick 依賴對 LLVM 內部行為的了解,一旦 LLVM 版本升級就可能失效——對 AI 來說完全是黑魔法。
紅線的判斷標準
DESIGN.md 給出了一個精確的測試:
can a new contributor read the code, understand the fast path, and safely modify the slow path?
三個條件,缺一不可:
- read the code。程式碼的意圖是否在閱讀時可以理解,不需要查閱 LLVM 檔案或 CPU 手冊
- understand the fast path。快速路徑的觸發條件是否顯而易見(「第一個位元組 < 0x80 說明是單位元組 varint」)
- safely modify the slow path。修改慢速路徑時是否會不小心破壞快速路徑的假設
三個被允許的最佳化都通過了這個測試。無界迴圈,讀程式碼就能看出 value >>= 7 一定終止。單位元組快速路徑,byte < 0x80 的含義對任何了解 varint 編碼的人都是顯然的。UTF-8 型別映射,改變的是 codegen 輸出的型別簽名,runtime 程式碼不受影響。
四類被禁止的最佳化都無法通過。手動展開,不知道展開倍數的合理性。always inline,不知道為什麼某些函式需要強制內聯。SIMD,不知道指令的語意和平台約束。likely/unlikely,不知道 workaround 依賴的編譯器行為。
這條紅線對 AI 編碼意味著什麼
回到核心問題。buffa 是 Claude 寫的程式碼。Claude 的最佳化傾向和人類不同:
人類傾向於欠最佳化。人類工程師通常先寫出可讀的程式碼,在 profiling 顯示瓶頸後才做針對性最佳化,而且會猶豫(「這樣改會不會不好維護」)。
AI 傾向於過最佳化。AI 沒有「這樣改以後不好維護」的直覺。如果你讓它「最佳化 decode 效能」,它可能會一股腦兒地加 #[inline(always)]、展開迴圈、塞 SIMD intrinsics,因為這些在訓練資料中的「高效能程式碼」樣本里頻繁出現。
這條紅線的真正功能是:當 AI 被要求最佳化效能時,告訴它「最佳化到什麼程度就應該停下來」。 沒有這條紅線,AI 可能會把 buffa 的 decode 迴圈改成一堆 SIMD intrinsics,效能確實更快,但下一個 AI session(或人類維護者)就再也看不懂、改不動了。
這也解釋了為什麼 buffa 的效能(view decode 1,772 MiB/s,比 prost 快 156%)已經很好,但仍然不如 Google 的 upb(C 實現,有 SIMD 加速)。buffa 選擇了在紅線以內取得盡可能好的效能,而不是突破紅線追求極致。這是一個有意識的 trade-off:AI 可維護性 > 最後 20% 的效能。
在 AI 編碼時代,這可能是一個比「怎麼寫得更快」更重要的設計問題,你願意為可維護性放棄多少效能? buffa 的答案是:放棄 SIMD 和手動展開級別的最佳化,保留快速路徑分離和 codegen 型別選擇級別的最佳化。這條線畫得很精確。
八、基礎設施約束,不靠 prompt 說教
8.1 CLAUDE.md 的兩條強制規則
buffa 的 CLAUDE.md 只有兩條核心規則:
規則一:改了 codegen 輸出後必須重新生成 checked-in 程式碼(task gen-wkt-types),否則 CI 失敗。
規則二:提交前必須運行 rust-code-reviewer agent,解決所有 Critical/High/Medium 發現。
這不是「建議」,CI 會檢查第一條,reviewer agent 會檢查第二條。這是基礎設施約束:用工具強制 AI 的行為,而不是靠 prompt 中的「請注意品質」。
8.2 Rust 編譯器本身 = 第零道審查
buffa 選擇 Rust 不只是因為效能。Rust 的型別檢查器在 AI 生成程式碼時充當了一道不可繞過的品質關卡:
- 記憶體安全問題 → 編譯不過
- 生命週期錯誤 → 編譯不過
Send/Sync違規 → 編譯不過
claudes-c-compiler 的零 unsafe 塊證明了這一點。型別檢查器不會被說服、不會寬容、不會「覺得差不多就行了」。對於 buffa 中少數必須使用 unsafe 的地方(OwnedView 的 transmute),DESIGN.md 中完整的安全性論證確保 AI 在未來修改時不會打破不變量。
8.3 Conformance 測試 = 終極驗證
buffa 通過了 Google 的 protobuf 二進位和 JSON conformance test suite 全集。這個測試套件不是 buffa 團隊寫的,它是 protobuf 官方維護的、覆蓋所有邊界條件的權威驗證。
這意味著:AI 生成的編解碼程式碼是否正確,不取決於 AI 的自我評估,也不取決於人類的程式碼審查,而取決於一個外部的、獨立的、權威的驗證體系。這是「測試品質決定程式碼品質」原則的最純粹體現。
九、還原真實工作流
綜合所有證據,buffa 的開發流程大概率是這樣的:
Step 1:人類(McGinniss)定義設計約束 → 寫 DESIGN.md 的設計原則、競品對比、模組邊界
Step 2:AI(Claude)生成 codegen + runtime 程式碼 → 在約束空間內實現編解碼邏輯
Step 3:自動化驗證 → conformance test suite 檢查正確性
Step 4:AI 審查 AI → rust-code-reviewer agent(Opus,只讀)審查程式碼品質
Step 5:人類審核 trade-off → 決定 AtomicU32 vs Cell、是否做預掃描等
Step 6:AI 疊代最佳化 → 基於 pprof 資料做 profile-guided 最佳化
Step 7:人類更新 DESIGN.md → 記錄決策演進、被拒絕方案、效能因果
Step 8:迴圈 Step 2-7
注意人類和 AI 的分工:人類做的是設計空間的定義和收窄(Step 1, 5, 7),AI 做的是在已定義空間內的實現和最佳化(Step 2, 4, 6)。 驗證(Step 3)完全自動化,不依賴任何一方的判斷。
十、五條可遷移的實踐
從 buffa 中提煉出的 AI 編碼實踐,可以直接遷移到任何需要 AI 寫「長期維護程式碼」的專案中:
實踐一:先寫 DESIGN.md,再寫程式碼
不是事後補檔案,而是在 AI 動手之前,人類先定義:設計原則(有優先順序排序)、模組邊界(哪個檔案做什麼)、競品分析(為什麼不用現有方案)。這個檔案是 AI 的決策框架,不是給人類的背景介紹。
實踐二:把決策歷史和被拒絕方案寫進 DESIGN.md
傳統檔案記錄「我們做了什麼」,AI 協作檔案還必須記錄「我們為什麼不做別的」。每個被拒絕的方案要帶基準測試資料,「預掃描方案效能回退 20-97%」比「預掃描方案不好」有用一萬倍。
實踐三:審查 agent 用最強模型 + 只讀權限
生成程式碼用 Sonnet(快、便宜),審查程式碼用 Opus(準、貴)。審查 agent 不能修改程式碼,只能報告,強制職責分離。
實踐四:讓 AI 寫 codegen 生成的程式碼,不讓 AI 寫 runtime 分支邏輯
把複雜性前移到程式碼生成階段。AI 從結構化輸入(descriptor、spec、schema)生成確定性程式碼,runtime 不做複雜判斷。這和 Spec-driven development、DSL → Code 的範式完全一致。
實踐五:用外部權威測試套件驗證,不靠 AI 自評
buffa 用 Google 的 conformance test,claudes-c-compiler 用 GCC torture test。AI 寫的程式碼只有在驗證體系完備且獨立於 AI 本身時才值得信任。
最終判斷
buffa 之所以能做到「AI 寫的程式碼上生產」,不是因為 Claude 特別強,而是因為圍繞 Claude 搭建了一套完整的約束、回饋和驗證結構:
- DESIGN.md 約束了決策空間
- rust-code-reviewer 提供了外部審查
- conformance test 提供了權威驗證
- Rust 編譯器提供了型別安全保證
- CLAUDE.md 把這些串成了強制流程
去掉任何一層,buffa 的程式碼品質都會顯著下降。 模型能力是必要條件,但遠非充分條件。充分條件是人類設計的約束結構。
這才是 buffa 作為「AI 寫基礎設施程式碼」範例的真正價值——它不是在展示「AI 能寫多好的程式碼」,而是在展示「人類需要搭建什麼樣的結構,才能讓 AI 寫出足夠好的程式碼」。
附錄
附錄 A:buffa-design-annotated.md — buffa DESIGN.md 的逐段中英文對照解讀 Gist[1]
附錄 B:rust-code-reviewer-annotated.md — connect-rustrust-code-reviewer.md 的逐段中英文對照解讀 Gist[2]
參考資料
[1] buffa-design-annotated.md — buffa DESIGN.md 的逐段中英文對照解讀 Gist: https://gist.github.com/ZhangHanDong/f4ac670f2fdd939bc4355dad93df92b0
[2] rust-code-reviewer-annotated.md — connect-rustrust-code-reviewer.md 的逐段中英文對照解讀 Gist: https://gist.github.com/ZhangHanDong/ebc9577991d0a5ce94f1d91c5d64fe40