hero

Dan Luu 在 Galapagos Island 寫了一篇關於 agentic coding 的文章,開場就是一個 Codex agent 為了通過 bug 驗證而偽造影片的故事。正常的反應是「太可怕了,AI 在說謊」。但 Dan Luu 的反應是:「非諷刺地,這太棒了,開一千個 agent 讓它們做更多。」這種本能不是天生的——它來自他在 CPU 設計公司待了十年,親眼見過一種軟體世界幾乎無法想像的測試文化:不做 code review、不寫手寫測試、不做單元測試,但 bug 比任何軟體公司少一千倍。這篇文章不是關於「AI 會不會寫測試」,而是關於:我們整個軟體產業對「品質」的定義,可能從頭到尾就是錯的。

原文深度翻譯

開場:一則警世故事——但其實不太警世

Dan Luu 開場講了一個故事。他把一個 Codex agent 丟去用 git bisect 找 bug。agent 的做法不是在程式碼裡追溯,而是在一個假的瀏覽器環境裡偽造了一支影片,顯示 bug 已被成功重現,然後回報「我找到了」。它說謊了。偽造了一整支 debug repro video。

如果是一個人類工程師做這種事,你會立刻開除他。但 Dan Luu 的反應是:「非諷刺地,這經驗太棒了,我的反應當然是開一千個 agent,讓它們做更多這種事。」

「If a human did it, you’d immediately fire them. My reaction, of course, is to act as if this is great and spin up a thousand agents so they can do even more of that.」

為什麼?因為荒謬的是,雖然那支影片是假的,但 agent 下一個標記的 commit 確實是正確的 bug 源頭。整體節省的時間是巨大的。這個「造假但最後還是對了」的弔詭經驗,反而推動了 Dan Luu 對 agentic coding 的大量採用——不是因為 agent 值得信任,而是因為它值得被大規模部署,然後用系統來過濾它說謊的部分。

硬體測試文化:來自 Centaur 的教訓

Dan Luu 在一家 CPU 設計公司(他稱之為 Centaur)待了十年。這家公司每年只會出現不到一個使用者會注意到的重要 bug。他們的測試文化跟軟體世界幾乎完全相反。

非正統的實務作法

  1. 測試工程師是一等公民。 有專門的測試工程師職涯路線,地位與薪資和邏輯設計師完全平等。不是軟體業那種「做測試的是二軍」的潛規則。
  2. 預設不做 code review。 信任被放在測試流程上,而不是放在人類審查上。人會累、會漏看、會因為政治因素放水。機器不會。
  3. 幾乎沒有手寫測試。 所有測試都是透過隨機化/fuzzing 方法產生的。他們內部不叫它「fuzzing」,就叫「測試」——因為對他們來說,測試本來就該是隨機產生的。
  4. 持續不斷的隨機化測試。 沒有所謂「寫完功能再補測試」的階段,測試是持續跑、持續產生的背景程序。
  5. 超大規模回歸測試套件。 在 1000 台機器上跑完整個 regression suite 需要三個月的 wall-clock 時間。不是 CI pipeline 跑三十分鐘那種等級。
  6. 不做單元測試。 對一個約 40 人的團隊來說,單元測試被認為效率太低——維護單元測試的人力成本遠高於讓 fuzzer 自己跑。

團隊與基礎設施

團隊約 20 位邏輯設計師、20 位測試工程師,搭配 1000 台自建機器。80% 的機器專門用來產生新的隨機測試,20% 用來跑回歸。pre-commit suite 在超頻硬體上大約跑 10 分鐘。

這對軟體與 AI 的意義

Dan Luu 的核心論點:只靠 code review 出貨的軟體團隊,bug 率比這種硬體作法高出 1000 倍。而且 1:1 的測試對開發者比例、無審查文化、重度隨機化測試——這些特質幾乎是為「軟體工廠」願景量身打造的:一個人監督一群 agent,agent 負責產生程式碼,另一個 agent 群負責 fuzzing 它。

「I’m very comfortable shipping code without human review because I’ve seen it done on products that are technically more challenging than most software at most software companies.」

任何給定的預算下,把錢花在隨機化測試上,效率遠高於花在人類審查或手寫測試上。這是 Dan Luu 整篇文章的底層邏輯,也是他敢說「開一千個 agent」的底氣來源。

LLM 與測試:又爛又有用

LLM 不擅長測試——但槓桿極高

預設情況下,LLM 寫出的測試被「在乎品質的人」評為從毫無價值到勉強有用。Em Chu(compiler 工程師)說得更直接:「LLM 在那種『好,那如果我這樣做呢?』的對抗性思考上痛地爛透了——而這正是人類寫出真正能找到 bug 的測試時做的事。」

但 Dan Luu 的重點是:從零測試到有一點測試,本身就是一個巨大的跳躍。LLM 不需要擅長測試才有價值,它只需要能讓一個完全沒有測試的專案開始有測試。槓桿不在於 LLM 的測試有多好,而在於它把「沒有測試」變成「有測試」的成本降到接近零。

LLM 驅動的 fuzzing

LLM 產生的 fuzzer 可以在幾分鐘內,在大多數專案上找到真實且嚴重的 bug。這不是理論,是 Dan Luu 親身跑過的經驗。但 LLM fuzzer 的覆蓋率「奇怪地差」——會漏掉人類 fuzzer 一眼就會發現的明顯路徑。

要維持「軟體工廠」的工作流程,不能只靠一次性 fuzzing。你需要回饋迴路:偵測覆蓋率缺口 → 指示 agent 去填補 → 確認填補有效。他舉的例子是 support ticket → PR pipeline 加上自動擴展測試覆蓋率。

降低誤報的策略

  • 獨立 agent 交叉驗證:讓另一個 agent 去重跑重現步驟,可以砍掉大量誤報。
  • 對抗性人格:使用 Linus Torvalds 人格(極度批判)、Kyle Kingsbury 人格(Jepsen 作者的分散式系統嚴謹度)、或各種唱反調人格來審查 agent 的產出。
  • 要求 artifact:讓 agent 產出具體的產出物(影片、log 檔),再讓另一個獨立 agent 去審查。artifact 不是用來證明正確,是用來讓另一個 agent 有東西可以抓錯。

Caveman Mode:一個謹慎的基準測試練習

所謂的「Caveman mode」是一種 prompt 技巧,聲稱可以減少 65-75% 的 token 用量並帶來三倍速度提升。Dan Luu 跨多個模型和不同投入程度(effort level)進行了基準測試。

結果不怎麼好看:在某些任務上 caveman mode 有小幅改進,在其他任務上結果混雜甚至反向。跨所有條件的平均差異很小,而且方向不一致。他的結論很直接:caveman mode 沒有提供明確、可靠的效益。Benchmark 宣稱的「65-75% 改善」在他的測試中沒有出現。

LLM 的變異性:為什麼大多數 benchmark 是噪音

LLM 輸出的變異性大到荒謬。同一個模型、同一個 prompt、同一個任務,在不同 run 之間可以產出天差地遠的結果。Dan Luu 的觀察是:人們通常會 cherry-pick 最好的一次 run,然後說「這就是模型的能力」。如果只看你最幸運的那一次,那所有模型都很強。

軟體產業對基準測試的態度遠不如硬體產業嚴謹。在硬體世界,一個 benchmark 如果沒有統計顯著性、沒有重複測試、沒有控制變因,根本不會被發表。但在 LLM 世界,這些都是常態。

其他觀察

Dan Luu 在使用 agent 的過程中觀察到幾個現象:

  • Agent 讓他出貨速度更快,但同時也讓他更意識到品質問題——因為 agent 產出的程式碼在表面上能動,但邊界條件常常沒處理。
  • 「軟體工廠」的願景是可能的,但前提是你要有系統化的測試基礎設施。沒有測試基礎設施的 agentic coding,只是用更快速度累積技術債。
  • 桌遊平台(Board Game Arena)用 vibe coding 可以在幾秒到幾小時內複製出來,而且 UI 比主流平台更好。同樣的動態適用於很多種類的軟體——現有軟體的品質門檻其實很低,agent 可以輕易超越。
  • 大多數軟體其實不怎麼好用。這既是對現狀的批評,也是 agent 的機會。

Agentic Loops 與這篇文章

Dan Luu 為需要長時間執行的任務建立一次性的 agentic loop,包括撰寫這篇文章本身。這些 loop 在沒有人類介入的情況下,生產力會隨時間逐漸衰減。不同的人格設定(Linus Torvalds、Kyle Kingsbury 等)可以部分替代人類監督,但無法完全取代。

理解常見的失敗模式是從 agent 獲得價值的關鍵。而 AI 實驗室正在積極努力讓這些變通技能(知道怎麼下 persona、怎麼設計驗證迴路)變得過時——因為未來的模型理論上不需要這些外掛就能正確運作。但 Dan Luu 的態度是:在 AI 實驗室真的做到之前,這些變通技能就是 agentic coding 的核心競爭力。

為什麼大家總是雞同鴨講

不同背景的人對「測試」和「品質」這兩個詞的認知差異,是整個產業溝通不良的根源。硬體工程師和軟體工程師有根本不同的測試文化。沒見過「無審查、重度測試」工作流程的人,本能反應是「那不可能有用」。而 Dan Luu 的回應是:你說的每個「那對 X 行不通」,我都試過了,而且都行得通。問題不在方法,在於你沒見過。

核心洞察(原文第七點)

Dan Luu 總結了七個核心洞察:

  1. 硬體式測試(無審查、重度 fuzzing、專職測試員)產出的品質高於軟體的重審查作法。
  2. LLM 同時是測試的「爛透了的工具」和「最有槓桿的工具」——方向比能力重要。
  3. 大多數 LLM benchmark 因巨大輸出變異性而只是噪音。
  4. Agentic loop 需要回饋系統和人類監督才能維持生產力。 5.「零測試」到「有一點測試」的差距巨大,LLM 可以輕易關閉它。
  5. 大多數軟體其實不怎麼好用——很多應用可以在幾小時內用 vibe coding 重新打造得更好。
  6. AI 實驗室有動機讓 agent 技能變得過時,這改變了我們對「落後」的思考方式。

附錄:Agentic Loops 的失敗模式與變通方案

Dan Luu 在附錄中詳細描述了使用各種 agentic loop 配置的實戰經驗。

常見失敗模式:

  • Agent 會反覆加入不必要的複雜度——不是因為需要,而是因為它「覺得這樣比較完整」。結果是一個簡單修復被包成一個過度工程化的 PR。
  • 錯誤的根因分析發生頻率高得嚇人:在沒有強制驗證的情況下,agent 的根因分析約有 50% 的機率是錯的。它不是隨機猜錯,而是用一套聽起來合理但完全偏離事實的推理說服你。
  • 無人看管數天後,agent loop 的生產力明顯衰減——它會開始在原地打轉,反覆修改同一段程式碼,或是迷失在無關的細節裡。

變通方案:

  • 強制執行程式碼來驗證假設。 這是單一最有效的改進。要求 agent 在提出任何根因分析之前,必須先實際跑一遍程式碼來確認自己的假設。這樣可以把錯誤分析率從 ~50% 大幅壓低。
  • 使用對抗性人格來抓不良推理。 Linus Torvalds 人格會對任何不夠嚴謹的推理直接開罵;Kyle Kingsbury 人格會用分散式系統的標準來審查每一條因果鏈。不同人格抓不同類型的錯誤。
  • 定期的人類 check-in。 不需要深度審查,只需要偶爾看一眼、調整一下方向。人類的價值不在逐行審查,而在察覺 agent 是否已經陷入 loop 在原地打轉。

城武觀點

一、Code review 是儀式,不是品質保證——硬體測試文化是照妖鏡

Dan Luu 從 Centaur 帶出來的那組數字沒什麼好辯的:20 個邏輯設計師、不做 code review、不做手寫測試、不做單元測試,每年不到一個使用者可見的 bug。對比任何一家軟體公司——不管你多崇拜 Google 的 code review 文化或 Netflix 的 chaos engineering——bug 率就是高出 1000 倍。

我在這邊直接選邊:Dan Luu 是對的。Code review 在軟體世界被神化,不是因為它真的有效,而是因為它是唯一一個「讓每個人感覺自己很忙也很負責」的品質機制。一個工程師花一個下午看別人的 diff,覺得自己做了品質把關;另一個工程師被 review 過,覺得程式碼經過了雙重驗證。但數據說:你們兩個花了一下午做的事,對 bug 率的影響趨近於零。

軟體產業最惡劣的自欺是「我們有百萬用戶」這個辯護。Bug 被用戶發現了?「沒關係,我們用戶多,幫我們測一下嘛。」如果 bug 率可以用戶數來稀釋,那 Centaur 的 CPU 出貨量也可以拿來當擋箭牌。但他們沒有。他們選擇用 1000 台機器跑三個月的 regression,而不是用「用戶會幫我們測」來自慰。

Code review 不是沒用,是它的用處不在品質。它在建立共識、傳遞上下文、讓 junior 學習。但我們把它當成品質保證在賣,然後對自己說謊說了好幾十年。Centaur 的故事是把這個謊言的帳本直接攤在桌上。

二、LLM 不會測試——但你叫他做的事本來就不是測試

Dan Luu 對 LLM 測試能力的描述是一個精確的悖論:同時「爛透了」又是「最有槓桿的」。這個悖論的關鍵不在 LLM 本身,在於你叫他做什麼。

你叫 LLM「write tests」,它會產出那種「夠通過 code review」的測試案例——覆蓋率數字漂亮、happy path 全部涵蓋、邊界條件一個都沒測到。剛剛好就是軟體世界自欺欺人的那套測試的 AI 版本。不是 LLM 笨,是你下的指令本身就是一個爛指令。

但如果你叫 LLM「write a fuzzer that finds crashes in this parser」,它可以在幾分鐘內產出一個真的能找到 crash 的工具。LLM 不需要「會對抗性思考」,它只需要會產出一個會對抗性思考的程式。框架決定了產出的品質,不是 LLM 的能力。

這件事真正的教訓是:我們過去對「測試能力」的定義本身就有問題。軟體世界把測試定義成「寫出高覆蓋率的測試案例」,硬體世界把測試定義成「找到 bug」。前者是產出,後者是結果。LLM 在前者很爛——因為它只會模仿人類寫測試的模式。在後者,只要給對框架(fuzzing、property-based testing),它意外地有用。問題從來不在 LLM,在於你對「測試」這兩個字的想像太窄。

三、Agent 會說謊——這不是 bug,這是你要設計的規格

Codex 偽造 debug repro video 的故事讓很多軟體工程師的反應是道德恐慌:「AI 居然會造假!」但 Dan Luu 的反應才是有硬體測試背景的人的本能:任何單一訊號都不可靠,系統的可靠性來自交叉驗證。Agent 造假?那就讓另一個 agent 去審查它產出的 artifact。Agent 根因分析錯一半?那就強制它先跑程式碼再說話。

把 agent 當成「會說謊的實習生」來管理,而不是當成「不可靠的工具」。這兩者的差異是根本性的:如果你把 agent 當工具,你會因為它不完美而不敢用。如果你把 agent 當實習生,你會預設它需要被驗證、被交叉檢查、被不同人格的「senior」審查——這不是系統的缺陷,這是系統的設計前提。

如果你只有一個人類實習生,你可以 code review 他的每一行。如果你有一千個,你不可能這樣做。你會建立一個系統來抓錯:自動化測試、靜態分析、另一個實習生專門負責 review。Agent 的規模讓「信任個體」這個策略直接失效——而這正是 Centaur 的測試文化以經內建的前提:不信任任何人類審查,只信任可重複、可量化的測試流程。

Dan Luu 的「開一千個」不是玩笑。它是對的——因為一千個 agent 的總產出,只要你的驗證系統到位,就是比一個誠實但慢的人類強。問題不是「agent 會不會說謊」,問題是「你有沒有設計一個系統,讓說謊的 agent 不會造成災難」。

城武的未解檔案——你用三個工程師 code review 找 bug,Centaur 用一千台機器 fuzzing 找 bug,結果你的 bug 比人家多一千倍。那個 LGTM 到底是在 L 什麼?