AI Agent 複雜度棘輪效應:為什麼 90% 的測試覆蓋率至關重要

@garrytan
英語2 個月前 · 2026年5月12日
237K
791
96
47
1.6K

TL;DR

Garry Tan 解釋了複雜度棘輪效應,即 AI Agent 如何透過自動化測試與文件編寫來確保軟體品質持續提升,讓獨立開發者也能輕鬆管理龐大的程式碼庫。

我過去一年都在用 AI 寫程式。不是單純下提示詞而已——而是真的建構軟體。我做了兩個開源專案:GStack,它可以讓 AI 編碼 Agent 更強大;還有 GBrain,它能將你讀過和寫過的所有內容,變成一個可供 AI 搜尋的知識庫。這兩個專案加起來,大約有 97 萬行程式碼和 665 個測試檔案。幾乎全部都是由 Claude Code 和 Codex 在我的指導下寫出來的(大多數時候同時開 15 個 Conductor 會話)。

上週,我 在 72 小時內合併了 14 個 Pull Request,新增了近 29,000 行程式碼。而且每個版本的測試都比上一個版本更完善。

這在過去被認為是不可能的。速度和品質通常被視為 trade-off。要嘛快速出貨,然後到處出包;要嘛慢慢來,確保品質。你只能選一個。

但現在你不用再做出取捨了。關鍵在於達到 90% 的測試覆蓋率——而 AI Agent 讓這件事變得輕而易舉。五十年來,那種程度的驗證需要付出極高的人力成本才能維持。現在,Agent 會和程式碼一起撰寫測試。於是,我稱之為「複雜度棘輪」(complexity ratchet)的現象出現了:系統只會變得更好,不會更差。

(這是關於用 AI 建構軟體的系列文章第七篇:1 2 3 4 5 6

過去的軟體很脆弱

過去五十年,整個軟體工程學科都圍繞著一個核心概念:防止錯誤,因為錯誤是災難性的。

你必須在第一次就把程式碼寫對。遺漏一個邊界情況,就可能讓生產環境崩潰。部署一個有問題的資料庫遷移,就可能遺失客戶資料。寫了一個微妙的函式,而當唯一懂它的同事離職後,就再也沒人知道它為什麼能運作。整個系統依賴於人類的細心,但人類並不細心。所以我們建立了複雜的流程——程式碼審查、測試環境、QA 團隊、發佈列車——全都是為了在使用者發現問題之前抓住它們。

這在某種程度上是有效的。但速度很慢。這也意味著任何軟體系統的複雜度都有一個難以超越的上限:一個團隊能夠同時記在腦中的事物數量。

現在的軟體很有彈性

我不是說它變得隨便。而是指它擁有了一種前所未有的韌性。

我說「模型已經到位了」,意思是 AI 編碼 Agent——Claude、GPT、Codex,以及圍繞它們成長起來的生態系——現在能夠讀懂程式碼、理解上下文、診斷錯誤,並撰寫修復方案。不是完美無缺,但已經足夠好到改變軟體的錯誤處理模型。

資料庫遷移出問題?Agent 會讀取錯誤訊息,理解橫跨 45 個版本的資料庫 schema 歷史,寫出修復方案,並撰寫測試。檔案同步在處理數百萬個符號連結時卡住?Agent 會診斷出是解析器超時,將其限制在 30 秒內,並附上測試一起提交修復。提取管線有歸因錯誤?跨模型評估會捕捉到它,然後提示詞會被迭代更新,並在資料庫層級加入強制執行機制。

對於大多數程式碼層級的錯誤——邏輯錯誤、解析失敗、邊界問題——Agent 現在可以在下一個回合中診斷並修復它們。這是全新的能力。那些仍然具有災難性的錯誤,是那些會破壞狀態的錯誤:對生產資料執行錯誤的資料庫遷移、在被發現前就被利用的安全漏洞、無法挽回的隱私外洩。棘輪機制在這裡也有幫助(好的測試能在上線前捕捉到大部分這類問題),但真正的轉變在於,程式碼庫中絕大多數的錯誤都是可修復的類型。

這對軟體建構方式來說,是一個相位的轉變。但前提是你必須擁有這個棘輪機制。

Agent 複雜度棘輪

棘輪是一種允許單一方向運動的機制。棘輪扳手只能向前轉動螺栓,並防止它向後滑脫。這就是個比喻。

在由 Agent 編碼的軟體中,每次與 AI Agent 的編碼會話都會為程式碼庫增加三樣東西:

  1. 測試:這些測試定義了「正確」的標準——它們是自動化檢查,每當有人修改程式碼時就會執行,如果修改破壞了某些東西,就會大聲地失敗。
  2. 文件:記錄了決策背後的原因——不只是程式碼做了什麼,還有其背後的理由和取捨。
  3. 評估結果:設定了品質門檻——針對輸出品質的結構化評估,附有分數,讓你知道下一個版本是變好還是變差。

下次當 Agent 再次處理這個程式碼庫時,它會把所有這三類資訊載入到它的上下文視窗(AI 能看見並進行推理的文字)中。它無法退步到低於測試套件的品質標準——測試會失敗。它不能忽略文件——因為文件就在上下文中。它無法提供低於評估基準線的品質——分數都被記錄下來了。

品質下限隨著每一次迭代而提升。只能前進,不能後退。這就是棘輪。

實際運作起來是什麼樣子

我來具體說明一下。GBrain 是我正在建構的一個知識系統——它可以透過儲存、索引和搜尋一個人的筆記、會議、對話和研究資料,為 AI Agent 提供長期記憶。想像它是一個你的 AI 助手能夠實際讀取的「第二個大腦」。

它的一個功能是「知識論提取」:它會閱讀數千頁的內容,並提取出誰相信什麼,以及他們的信心程度是如何隨時間變化的。「Garry 認為比特幣會達到 30 萬美元(信心值:0.45)。」「Jared 認為這家新創公司有很強的留存率(信心值:0.80)。」類似這樣,但規模是橫跨 28,000 頁。

第一次提取,就找出了 100,720 個陳述。我用一個跨模型評估來評分其品質——我讓 GPT-5.5 和 Claude 各自獨立地為輸出打分。總體分數:6.8 / 10。

最大的問題是什麼?我稱之為「持有者混淆」。以「AI 將在 2027 年取代 80% 的軟體工程師」這個陳述為例。這個信念是誰的?是寫出這句話的人嗎?是他們引用的某個人嗎?還是系統的分析引擎根據播客文稿推斷出來的?第一版在 35% 的情況下會搞錯這個區別。這很重要——如果你在建立一個追蹤人們信念的系統,你需要知道「誰」相信它。

所以,我們記錄了評估結果。確定了六個特定的失敗模式。第二版的提示詞一一解決了這六個問題。權重四捨五入(信心值分數)的規則被強制在資料庫層級執行——不再允許像 0.74 這種虛假的精確度,而 0.75 才是誠實的答案。17 個測試鎖定了這個合約。

現在,任何未來版本的提取功能,都無法在未能通過這 17 個測試的情況下發佈。沒人需要記住為什麼權重四捨五入很重要,或者什麼是持有者混淆。測試會記得。

品質下限就此永久性地提升了。這就是棘輪轉動了一次。

為什麼大多數「直覺編碼」的專案會失敗

"Vibecoding" 是 Andrej Karpathy 對用 AI 寫程式的一種說法,指的是你用自然語言描述你想要的東西,然後讓模型生成程式碼。這方法很強大,也是我寫程式的方式。但從我在 YC 申請案和開源 repo 中看到的狀況,大多數跳過測試的直覺編碼專案,一旦達到中等複雜度——幾千行程式碼、幾個互相影響的功能——就開始土崩瓦解。

它們跳過了棘輪機制。沒有測試、沒有文件、沒有評估。Agent 增加了複雜度,但沒有任何東西可以防止倒退。每一個新功能都有可能破壞舊功能,而如果沒有測試,你只能在使用者回報時才會發現。到了 0.5 版本,程式碼庫就像一間鬼屋,每個改動都會破壞一些意想不到的東西。然後開發者會寫一篇部落格文章,說 AI 寫程式行不通。

AI 寫程式行得通。他們只是沒有建立棘輪機制。

你可能會說,會寫測試的那種人,一開始也會寫出好的架構。有道理。但棘輪機制的重點不在於「人」——而在於「下一次會發生什麼事」。當一個新的貢獻者發起 PR 時,或者當模型版本改變時,或者當你凌晨 2 點精神不濟地寫程式時,測試會抓住回歸問題,無論它們是誰寫的。即使人類不在最佳狀態,棘輪也能運作。這就是重點。

沒有測試,改進就是一個充滿雜訊的過程——Agent 試圖讓事情變得更好,但沒有回歸訊號,好的改變和壞的改變同樣難以察覺。有了密集的測試套件,你就在受測的表面區域上得到了一個棘輪:對於你已經編碼成測試的行為,品質只會上升。這涵蓋了系統的大部分,但不是全部。但這已經足夠以高速維持前進的動力了。

測試就是機構記憶

在傳統軟體公司裡,機構記憶存在於人類身上。知道為什麼要有那個快取層的資深工程師。記得那次差點毀掉資料庫的資料庫遷移的架構師。能解釋帳務系統中那個奇怪邊界案例的技術主管。

人類會離開。他們會退休、被挖角、或 burnout。當他們離開時,知識也跟著消失。每一家軟體公司都有過這樣的經驗:打開一個關鍵檔案,發現一行註解寫著 // 不要改這個——去問 Dave,而 Dave 三年前就離職了。

Agent 的上下文視窗不會離職。它不會被挖角。它不會忘記。當測試套件編碼了「權重四捨五入必須以 0.05 為增量」,而文件解釋了「因為跨模型評估顯示虛假的精確度會降低對信心值分數的信任」時,這個知識就是持久的。任何 Agent、任何模型、任何時間,都可以載入那個上下文並理解這個限制條件。

測試是一種能夠在員工離職後存留下來的機構記憶。對於一個單人專案來說,它們甚至更為關鍵——因為它們是你唯一的機構記憶。

一切可 harness 的東西都是可測試的

棘輪機制不只適用於傳統的程式碼。它適用於任何電腦能夠觀察到的東西。

想想一個現代系統的各個層次。作業系統提供給你行程樹、檔案系統狀態、網路 socket、cron 排程。終端機提供給你每一次按鍵、每一行輸出、每一次互動提示。瀏覽器提供給你渲染後的頁面、按鈕狀態、導航事件。API 提供給你結構化的回應,你可以解析並驗證它們。而 AI Agent 提供給你可觀察的行為——它們說了什麼、呼叫了什麼工具、做事的順序、是否在行動前先詢問。

所有這些都是可 harness 的。如果你能 harness 它,你就能觀察它。如果你能觀察它,你就能對它進行斷言。如果你能斷言,你就能對它使用棘輪機制。

這個範圍比傳統的單元測試大得多。讓我展示給你看。

GStack 是我開源的編碼 Agent 框架——有 93,000 個 GitHub 星星、701,000 行程式碼、46 個技能。它的一個核心功能是互動式計劃審查:你讓它審查你的架構,它會逐節審查計劃,提出問題、探討邊界案例、挑戰你的假設。就像有一個真正會讀程式碼的工程經理。

問題在於:Claude Code 有時會跳過整個互動部分。它會讀取計劃檔案,一次性傾倒所有發現,然後結束——過程中完全沒有問使用者任何問題。這個審查的全部價值就在於來回對話。跳過它完全違背了目的。

這種情況要怎麼測試?你無法用「AI 有沒有進行對話」來寫單元測試。沒有傳統的測試框架涵蓋這個。

所以我用了 Bun 的 TTY 功能來 建立一個測試 harness(PR #1354)。這個 harness 會在一個偽終端(pseudo-terminal)中實際啟動 Claude Code,餵給它一個特定的 repo 情境,觸發審查技能,並即時監控終端機的輸出。測試會觀察 Agent 在結束前是否發出了互動式提問。如果它只是傾倒發現並直接退出,沒有任何提問,測試就會失敗。

這不是在測試程式碼。這是在測試一個 AI Agent 是否遵循了行為合約。在 TTY 層級。透過實際觀察它的運作。

對應的棘輪機制有三層:

  1. 技能指令中的「STOP」閘門——明確的規則,規定「你在進入下一個章節之前,『必須』詢問使用者」,並附有反理性化條款,指名道姓地指出特定的失敗模式,讓模型無法透過自我說服來跳過。
  2. 反捷徑條款——「計劃檔案是互動式審查的『輸出』,而非其替代品。」這一句話堵住了模型一直試圖利用的漏洞。
  3. 閘門層級下限測試——即那個 TTY harness 測試,它在受控情境下啟動 Claude Code,如果 Agent 沒有提出至少一個互動式問題,測試就會失敗。

現在,當 Anthropic 推出新版本模型,或者當我修改某個技能的提示詞時,測試套件會捕捉到互動合約的任何回歸。Agent 無法默默地停止提問。測試會監控終端機並進行檢查。

或者看看 PR #880,它提供了一個新的 OpenClaw 外掛。測試不僅僅檢查程式碼是否能編譯。它會從原始碼建構這個外掛,在一個隔離的設定檔中啟動一個真正的 OpenClaw 實例,透過 CLI 安裝外掛,執行 plugins inspect 來驗證執行時期是否成功載入,設定 config 欄位,驗證 config,然後執行 plugins doctor 來確認沒有任何診斷問題。這是一個橫跨兩個獨立程式的完整端到端測試。359 行的測試程式碼。人類幾乎不會手動撰寫這種測試,因為設定過程太繁瑣了。Claude 大約五分鐘就寫好了。這就是努力壁壘在即時消失的證據。

這個原則可以推廣。你可以在作業系統層級進行測試:資料庫遷移是否建立了正確的資料表、cron 工作是否有觸發、行程是否還活著?在瀏覽器層級:頁面是否有正確渲染、Agent 是否正確填寫了表單?在 API 層級:模型是否回傳了結構正確的 JSON?在行為層級:Agent 是否遵循了協定、在刪除前是否有詢問、被告知停止時是否照做?

整個技術堆疊都是可測試的。棘輪機制適用於所有這一切。大多數人還沒意識到這點,因為他們仍然認為測試覆蓋率只是在問「我的函式有沒有回傳正確的數字」。真正的測試範圍,是電腦能看到的一切。

關於 90% 這個數字

那麼,達到 90% 的測試覆蓋率到底能帶來什麼?

Capers Jones 研究了超過 10,000 個軟體專案,並測量了缺陷移除效率(DRE)——即在使用者發現缺陷之前被捉到的百分比。他在 Applied Software Measurement 一書中的資料顯示了一條非線性曲線:低於 70% 的覆蓋率時,DRE 大約在 65-75% 之間。當覆蓋率達到 85-95% 時,DRE 會躍升至 92-97%。這種關係不是線性的。在 85% 左右有一個曲線的轉折點,缺陷逃逸率會急遽下降。

航空電子產業在幾十年前就發現了這一點。DO-178C 是 FAA 對飛行關鍵軟體制定的標準,對於 Level A 系統(也就是說,一個錯誤可能導致飛機失事的系統)它要求達到「修改條件/決定覆蓋率」(Modified Condition/Decision Coverage, MC/DC)。分支覆蓋率單獨使用時會漏掉 10-20% 的錯誤。而 MC/DC 比行覆蓋率更嚴格,可以達到 >99% 的 DRE。他們規定這個不是因為官僚喜歡文書作業。他們規定它是因為資料顯示,低於某些覆蓋率門檻時,重大缺陷會以「與不殺人」這個目標不相容的比率逃逸。

這與可靠度工程是平行的。工廠使用一種叫做 Six Sigma 的系統來衡量品質。概念是:計算每生產一百萬個單位會產生多少缺陷,然後將其表示為「Sigma 等級」——Sigma 越高,缺陷越少。一個 3-Sigma 的流程大約會產生 67,000 個缺陷/百萬(相當糟)。一個 4-Sigma 的流程大約會產生 6,200 個(好了十倍)。一個 5-Sigma 的流程則只產生 233 個(又好了 27 倍)。從 4 Sigma 跳到 5 Sigma 不是漸進式的改進。這是一個相位的轉變。

測試覆蓋率遵循同樣的曲線。從 70% 的覆蓋率進步到 90%,不是好 30%。而是缺陷逃逸數減少一個數量級。在 70% 的覆蓋率下,漏網的缺陷藏在 30% 未測試的程式碼中。在 90% 時,藏身之處縮小到 10%,而且大多數危險的路徑都被牢牢鎖定。

現在,我必須誠實地說,研究也顯示了其他結果。Mockus, Nagappan, and Dinh-Trong 在研究 Windows Vista 時發現,雖然較高的覆蓋率與較少的發佈後缺陷相關,但要達到 90% 以上的努力會急遽增加。最後那 20% 的覆蓋率所需的工作量,比前面 70% 要多得多。這個現象已經存在了幾十年。這就是為什麼大多數團隊在達到 70-80% 的覆蓋率後就會覺得夠好了,然後停下來。

但有些事情改變了:AI 編碼 Agent 不會感到「費力」

它們不會因為要寫第十四個邊界案例的測試而感到無聊。它們不會在週五下午五點偷工減料。它們不會看著一個棘手的整合測試然後想:「我晚點再回來處理」。那個讓人類團隊在 70% 覆蓋率前止步的努力曲線,對 Agent 並不適用。你可以要求 Claude 為一個模組中的每個邊界案例撰寫測試,它會樂意地、徹底地在凌晨 2 點完成,而且毫無怨言。那個殘酷的最後 20%——正是讓 90% 覆蓋率對人類團隊來說不切實際的部分——正是 AI Agent 最擅長的工作。

這才是真正的關鍵。重點不在於 AI 讓你寫程式更快。很多人都注意到了這點。重點在於 AI 讓你「驗證」的程度,達到過去因成本太高而無法持續的水平。那個資料顯示具有神奇效果的 90% 門檻?過去需要付出極高的「人類意志力」才能達到。現在它幾乎是免費的了。

這就是關鍵的區別。棘輪機制不是把行覆蓋率當作一個虛榮指標。它是關於那些編碼了行為合約的測試——持有者混淆測試、權重四捨五入測試、互動式審查閘門測試。每個測試都鎖定了一個特定的學習經驗。覆蓋率只是一個代理指標,告訴你系統有多少行為是受到合約約束的。在 90% 的覆蓋率下,幾乎每個行為變更都會觸發一個測試訊號。Agent 要嘛通過測試(可以安全發佈),要嘛打破測試(立即被發現)。

剩下的 10% 是整合點、基礎設施管線,以及一些真正難以測試的邊界情況。沒關係。那 90% 才是將混亂轉變為棘輪的關鍵。

達到 90% 的覆蓋率過去是一項英雄式的壯舉。現在它只是一個平凡的星期二。這就是遊戲規則的改變。

概念驗證

這兩個專案一開始都是我一個人做的。現在不再是一個人的專案了。

GStack 現在有 37 位貢獻者。v1.30 版在一個版本中整合了 21 個來自社群的 PR。GBrain 則有 25 位貢獻者。v0.31.1.1 版在一次 PR 中整合了 22 個來自社群的修復——涵蓋了身份驗證流程、schema 啟動、同步、隱私等方面。

棘輪機制讓這一切變得安全。每個來自外部的 PR 都必須通過現有的測試套件。新的貢獻者不需要完全理解整個系統。他們只需要讓測試通過。

上週的 GBrain 版本說明了這一切:

  • v0.31.0:新增了一個用於即時記憶的事實表,以及一個「夢境整合」階段,將短期記憶提升為長期知識。
  • v0.31.1:修復了 25 個 CLI 指令,這些指令默默地將請求路由到一個空的本地資料庫,而不是使用者的實際大腦。
  • v0.31.1.1:一次 PR 中整合了 22 個社群回報的修復。
  • v0.31.2:修復了在擁有大量符號連結的大型 repo 上會無限等待的程式碼同步問題,方法是增加一個 30 秒的超時機制。

每個版本發佈時,測試數量都比上一個版本更多。Agent 在撰寫程式碼的同時也撰寫測試。覆蓋率不會下降,因為維護它所需要付出的努力,已經不再是人類的負擔。

新的複雜度天花板

軟體的複雜度天花板剛剛被大幅提高了。

過去,它受限於一個團隊能將整個系統記在腦中的能力。現在,它受限於一個人加上那些能將整個程式碼庫、schema 歷史、測試套件和文件載入到上下文中的 Agent。

這是一個大得多的數字。而且隨著上下文視窗越來越大,模型在推論程式碼方面的能力越來越強,這個數字還在增長。

任何不採用這個模式——Agent 加上品味,加上一個只會上升的測試套件——的軟體公司,都已經比一個擁有這些的開發者出貨更慢、品質更差。

工具已經有了。程式碼是開源的。測試就是棘輪。90% 的覆蓋率,每個 PR 都要達到,沒有例外。

五十年來,90% 的測試覆蓋率是航空電子和醫療設備的奢侈品——只有那些有預算用人力去堆的團隊才負擔得起。AI Agent 摧毀了那面努力壁壘。讓軟體變得可靠的覆蓋率門檻,不再是昂貴的了。它只是一個設定選項。問題不在於你能不能負擔 90% 的覆蓋率。問題在於,你能負擔不起嗎?

棘輪機制、技能,以及整個知識系統都是開源的,並且在 GitHub 上免費提供。開始動手建構吧。

我的 MIT 授權開源專案:

  • GStack — 讓 Claude Code 變得更強。93K 星星。免費。
  • GBrain — 你的 AI Agent 第二個大腦。14K 星星。免費。

AI 解說系列文章:

  1. Fat Skills, Fat Code, Thin Harness — 架構
  2. Resolvers — 智慧的路由表
  3. The LOC Controversy — 60 萬行程式碼實際產出了什麼
  4. Naked Models Are Stupider — 模型是引擎,不是車子
  5. The Skillify Manifesto — 每個工作流程都變成一個可測試的技能
  6. Meta-Meta-Prompting — 複合技能產生湧現能力
  7. Agent 複雜度棘輪 — 你正在閱讀的這篇

https://x.com/garrytan/status/2054055071017538028

https://x.com/garrytan/status/2042925773300908103

https://x.com/garrytan/status/2044479509874020852

https://x.com/garrytan/status/2045404377226285538

https://x.com/garrytan/status/2045798603059548364

https://x.com/garrytan/status/2046876981711769720

https://x.com/garrytan/status/2053127519872614419

https://x.com/karpathy/status/1886192184808149383

一鍵儲存

使用 YouMind AI 深度閱讀爆款文章

保存原文、追問細節、總結觀點,並在一個 AI 工作空間裡把爆款文章沉澱成可複用筆記。

了解 YouMind
寫給創作者

把你的 Markdown 變成乾淨的 𝕏 文章

圖片上傳、表格、程式碼區塊,往 𝕏 上手動重排太痛苦。YouMind 把整篇 Markdown 一鍵轉成乾淨、可直接發佈的 𝕏 文章草稿。

試試 Markdown 轉 𝕏

更多可拆解樣本

近期爆款文章

探索更多爆款文章