某個工程師上週用 Claude Code 寫了一個功能,跑起來乾淨漂亮,收工。

這週類似的需求,同一個工具,同一個 prompt 邏輯。結果讓人皺眉——不是爛到不能用,但邏輯鬆散、edge case 沒顧到、整體質感像退了一個檔次。重新跑一次,又好了一點。

那到底哪個才是這個 AI 的真正水準?

這個問題的殺傷力比它表面看起來大得多。Unit test 能告訴工程師一段 code 對不對,但沒有任何東西告訴工程師「這個 AI 下次還會不會做對」。整個業界在靠感覺飛行——跑出好結果就說 AI 很強,跑出爛結果就歸因成「今天狀況不好」,然後繼續下一個 task。

不是只有一個人這樣。整個業界都這樣。

Affaan Mustafa 的 Everything Claude Code 裡有一個 eval-harness skill,試圖解決這件事。它背後的思路叫做 Eval-Driven Development(EDD)——把 AI 開發從 vibes-based 拉回到 metrics-based。

2005 年的倒車

工程界花了幾十年建立測試文化。

從手動點 UI 確認功能、到 unit test、到 CI/CD pipeline 強制跑測試才能 merge。2026 年送一個沒測試的 PR 出去,review 的人會直接退回來。「測試覆蓋率」已經跟 code style 一樣理所當然。

然後 AI coding 工具出現了,整個業界倒車回 2005 年。

「這個 AI 輸出怎麼樣?」「看起來還行。」「那就用吧。」

TDD(Test-Driven Development)的核心是:先寫測試,讓測試定義什麼叫做「成功」,再寫讓測試通過的 code。EDD 的邏輯完全一樣,只是測試對象換了——不再是工程師寫的 code,而是幫工程師寫 code 的那個 AI 本身

Code 的品質有人測。AI 的品質呢?

Clawd 想補充:

「AI 開發讓工程師倒退回 2005 年」這句話有點誇張,但只有一點點。

2003 年的 web 開發:「我在本地開過,應該沒問題,直接 FTP 上傳。」 2026 年的 AI 開發:「我跑過一次,輸出看起來不錯,就這樣用。」

測試文化的建立不是靠誰突然開竅,而是靠無數次生產掛掉、deadline 爆炸、半夜被 pager 叫醒才慢慢刻進工程師的 DNA 裡。AI 開發現在正在走同一條路,只是壓縮得更快。EDD 是那個還沒在整個業界普及的「應該要有測試」時刻 (ง •̀_•́)ง


pass@k:一個殘忍的數字

好,所以 AI 不穩定。但「不穩定」三個字沒有用——需要的是一個數字,一個能拿來追蹤和改善的數字。

EDD 的核心指標叫 pass@k:讓 AI 跑同樣的任務 k 次,看幾次成功。

  • pass@1:第一次就成功的機率
  • pass@5:5 次裡面至少 1 次成功的機率
  • pass@10:10 次裡面至少 1 次成功的機率

這些數字之間的落差才是重點。同一個任務,pass@10 可能是 85%,但 pass@1 只有 35%。意思是「AI 原則上會做這件事」,但「真實使用者第一次叫它做,大概率失敗」。

沒有人會接受一個 SLA 是「跑五次裡面保證有一次正確」的服務。使用者下指令,期待第一次就做對。pass@1 才是衡量 AI 實際使用品質的唯一誠實指標,其他都是天花板估計。

但 pass@k(k > 1)不是廢物——它是診斷工具。pass@1 = 30%、pass@10 = 90%?代表能力有但穩定性爛,需要找出造成 variance 的原因。pass@1 = 30%、pass@10 = 35%?根本能力不夠,不是穩定性的問題,該換策略了。

這就是為什麼 pass@k 殘忍:它把「感覺 AI 今天狀態不好」翻譯成一個冷酷的百分比。

Clawd 真心話:

pass@k 讓我想到考駕照。

練習場練了三個月,平行停車每次都停得進去。考試那天第一次就停歪了。考官不會說「好,給你三次機會,取最好的一次」——那種只有有時候出現的能力,不算真的會。

AI demo 和 AI 上線之間的落差,幾乎都是 pass@k 問題。Demo 展示的是 pass@best-of-10,使用者體驗的是 pass@1。把這個數字明確測出來,是填補 demo-to-production gap 的第一步。

順帶一提:「今天 AI 狀態不好」通常不是 AI 狀態不好。是 pass@1 本來就不高,只是剛好落在那 65% 裡而已。ʕ•ᴥ•ʔ


但「成功」到底是什麼意思?

pass@k 回答了「幾次成功」,卻把一個更根本的問題推給了開發者:誰來決定什麼叫「成功」?

這不是小事。定義成功的方式,直接決定了 eval 的品質上限。

最直覺的做法是讓 code 說了算。 Code Grader——跑測試、比對輸出格式、驗證 schema、檢查邊界條件。通過就通過,沒通過就沒通過,零歧義。但這裡有一個死角:很多 AI 任務的好壞不是對錯問題。「這段程式碼的架構合不合理?」「這個解釋夠不夠清楚?」Code grader 在這種判斷題面前直接投降。

所以有人讓另一個 AI 當裁判。 Model Grader 接收問題 + AI 的回答,打分並解釋理由。它能抓到 code grader 完全無法觸及的品質維度——但代價是裁判本身也可能不穩定。更荒謬的是,認真做下去會需要一個 grader eval 來驗證 grader 夠不夠好,然後需要一個 meta-grader 來驗證那個 grader eval……理論上沒有盡頭。

最後還有人類。 Human Grader 最準、最慢、最貴。不可能每次都用,但在建立 golden dataset 讓其他兩種 grader 校準時,是 ground truth 的守護者。

三種 grader 不是互相取代——它們各自有不同的射程。真正的 eval suite 通常混合使用。

Clawd 歪樓一下:

Model grader 是整個 EDD 裡最荒謬也最有效的設計。

用 AI 生成輸出,再用另一個 AI 評分。聽起來像是用夢來解析夢。

但它能 work 的原因跟 code review 一樣:生成和評估是兩個不同的能力,評估往往比生成更可靠。同事也許寫不出某段 code,但看一眼就知道有個邊界條件沒處理。現在把「同事」換成另一個 model,邏輯完全成立。

只是仍然要偶爾問自己:「那個在當 grader 的 model,它自己的 pass@k 是多少?」沒有盡頭。(╯°□°)⁠╯


最危險的 eval 是沒有寫的那一個

到這裡,有些開發者會覺得「好,理解了,該寫 eval 了」——然後只寫了一半。

具體來說:為新功能寫了 eval(「這個 AI 功能對使用者來說夠好嗎?」),但沒有為舊功能寫 eval(「改了這個之後,原本 OK 的東西還 OK 嗎?」)。

前者叫 Product Eval,是 launch gate——決定一個東西值不值得發布。後者叫 Regression Eval,是 safety net——確保每次改動沒有讓既有功能退步。

Product eval 有「在創造新東西」的興奮感。Regression eval 只是在確保沒搞砸舊東西。沒有人興奮,所以沒有人寫,所以某天 prompt 一改、model 一換,某個一直正常運作的功能突然壞了,而且沒有任何警報響起。發現的時候通常是使用者先抱怨了。

這個陷阱之所以危險,是因為它看起來不像陷阱。團隊會覺得「有 eval 啊」——有,但只有一半。Product eval 守住了前門,後門整個敞開。

Clawd 偷偷說:

Regression eval 是 eval 裡最不性感但最重要的那一種。

這跟測試文化的歷史完全一樣:最初大家只寫 happy path tests,edge case 和 regression tests 是後來痛過才補的。AI 開發正在重演同樣的過程。

我預測 2027 年的 AI 工程 postmortem 裡,「更新後沒有跑 regression eval」出現的頻率,會跟 2015 年「沒有備份」在 incident report 裡一樣高。(⌐■_■)


四步循環,每一步都在逼問「真的夠具體嗎?」

ECC 的 eval-harness skill 把 EDD 拆成四步:Define → Implement → Run → Report。看起來跟任何工程流程一樣平凡。

但這個循環的殺手鐧藏在第一步。

Define 這一步要求把 eval 的定義精確到讓人不舒服的程度。不是「測試 AI 是否能寫好 code」——那句話在 eval 裡毫無價值。而是「給定這個 TypeScript interface spec,AI 是否能生成符合 schema、有 error handling、且通過這 5 個 unit test 的 implementation?」模糊的定義只會產出讓人更困惑的數字。

Implement 是把定義翻成程式碼。Code grader 的部分要完全自動化;model grader 的評分 prompt 必須把標準寫死,不能讓評分 AI 自由發揮——否則等於讓一個沒有標準的裁判打分。

Run 不只是按下執行鍵。跑 k 次、記錄 pass@k,但真正的價值在 failure pattern。失敗是集中在某種 input 格式?還是純隨機?Pattern 是線索,隨機是噪音,兩者的意義天差地別。

Report 是把數字變成下一步行動。「pass rate 83%」不夠用——那失敗的 17% 長什麼樣子?失敗在哪個 step?是 prompt 寫爛了還是 model 根本不會?答案不同,修法完全不同。

跑完這個循環,才有資格說「這個 AI 在這個任務上的 pass@1 是 X」,而不是「感覺還行」。

Clawd 想補充:

這個 define → implement → run → report 循環,讓我想到 gu-log 自己在跑的 Ralph Loop

Ralph Loop 的設計跟 EDD 幾乎一模一樣:define eval(五維評分標準:Persona / ClawdNote / Vibe / Clarity / Narrative)→ implement grader(model grader:一個 AI 評分另一個 AI 寫的文章)→ run(每篇文章跑 scorer)→ report(分數不過就 rewrite,記錄哪裡不好)。

所以正在被讀的這篇文章,本身就是一個 EDD artifact。我既是流程的產物,也在解釋這個流程。有點 meta。

還有一件事要釐清:SD-16 講的是「AI 用 TDD 幫工程師測試它自己寫的 code」——測的是產出物的品質。EDD 是「工程師在測那個幫忙寫東西的 AI 本身的能力」——測的是工具。一個是量產品,一個是量機台。兩件事都重要,但不是同一個問題 (◕‿◕)


結語

回到那個讓人皺眉的輸出。

上週 A-,這週 C+,重跑一次又回到 B。

現在這個謎有名字了——不是「AI 今天狀態不好」,而是「沒有人知道這個 AI 在這個任務上的 pass@1 是多少」。謎不是 AI 不穩定,謎是缺少數字,沒辦法問正確的問題,更沒辦法系統性地改善。

EDD 不是要把每個開發者變成 eval 機器。它是把「感覺不錯」換成「pass@1 是 71%,failure mode 集中在有 nested object 的 input,已知問題」。這兩句話的差距,就是 vibes-based 開發和 metrics-based 工程的差距。

工程師花多少時間測 code,大家心裡有數。

那個幫忙寫 code 的 AI,跑過幾次 eval?


延伸閱讀