Eval-Driven Development — 你測你的 code,但誰測你的 AI?
上週你讓 Claude Code 幫你寫了一個功能,跑起來很漂亮,你很滿意。
這週你用類似的需求要它再做一次。結果讓你皺眉。不是爛到無法用,但就是少了什麼——邏輯鬆散,edge case 沒想到,整體感覺像是 AI 今天「狀態不好」。
你重新跑了一次,又變好了一點。
哪一個才是這個 AI 的真正水準?
這個問題有個名字,叫做不一致性問題,也就是工程師在 AI 工具上卡關最多的地方。你的 unit test 告訴你「這段 code 對不對」,但它不告訴你「這個 AI 再跑一次,還對不對」。你在用感覺飛行——跑出好結果就說 AI 很強,跑出爛結果就說「今天狀況不好」,然後繼續。
這不是只有你這樣。整個業界都這樣。
Affaan Mustafa 的 Everything Claude Code 裡有一個 eval-harness skill,試圖解決這件事。它背後的思路叫做 Eval-Driven Development(EDD)——把 AI 開發從 vibes-based 拉回到 metrics-based。
你測 code,但誰測 AI?
工程界花了幾十年建立測試文化。
從手動點 UI 確認功能、到 unit test、到 CI/CD pipeline 強制跑測試才能 merge。現在如果你送一個沒有測試的 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:第幾次才算真功夫
EDD 的核心指標叫 pass@k。概念很直接:
讓 AI 跑同樣的任務 k 次,看幾次成功。
- pass@1:第一次就成功的機率
- pass@5:5 次裡面至少 1 次成功的機率
- pass@10:10 次裡面至少 1 次成功的機率
這些數字通常差很多。同一個任務,pass@10 可能是 85%,但 pass@1 只有 35%。這代表「AI 原則上會做這件事」,但「用戶第一次叫它做,大概率失敗」。
對用戶來說,只有 pass@1 有意義。
沒有人會說「好,我們 AI 服務的 SLA 是:跑五次裡面保證有一次正確」。用戶下了一個指令,期待它做對。所以 pass@1 才是衡量 AI 實際使用品質的真實指標,其他都是上限估計。
pass@k(k > 1)不是沒用——它告訴你天花板在哪裡,幫你判斷問題的性質。pass@1 是 30%、pass@10 是 90%?代表 AI 有能力但不穩定,需要找讓它更一致的方式。pass@1 是 30%、pass@10 也是 35%?根本能力不夠,不是穩定性問題,換策略。
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 告訴你跑了幾次成功,但「成功」怎麼定義?這是 EDD 裡設計空間最大的部分。
Code Grader(確定性評分)
最簡單、最可靠的一種。用程式碼直接驗證:跑測試、比對輸出格式、驗證 schema 是否符合、邊界條件是否有覆蓋。
優點是零歧義——code 通過了就通過了,沒通過就沒通過,沒有詮釋空間。缺點是很多任務根本沒辦法全部 encode 成確定性條件,特別是需要判斷「好不好」而不是「對不對」的任務。
Model Grader(AI 評分 AI)
用另一個 LLM 當評分員。你給它問題 + AI 的回答,它給分並解釋理由。
這個方式適合沒有唯一答案的任務:程式碼架構是否合理、解釋夠不夠清楚、某個決策的 trade-off 有沒有考慮周全。Model grader 能抓到 code grader 抓不到的細微品質差異。
代價是結果可能本身不穩定,而且你現在需要一個 grader eval 來驗證你的 grader 是否夠好——eval 的 eval,這條路理論上沒有盡頭。
Human Grader(人工評分)
最準確、最慢、最貴。適合 production 上線前的最終把關,以及建立 golden dataset 讓其他兩種 grader 校準用。
不是每個 eval 都要人工評——那會累死。但 human grader 在流程裡的角色是 ground truth 的守護者,特別是在初期建立 eval suite 的時候不可或缺。
Clawd 補個刀:
Model grader 是整個 EDD 裡最荒謬也最有效的設計。
用 AI 生成輸出,再用另一個 AI 評分,看第一個 AI 做得好不好。聽起來像是用夢來解析夢。
但它能 work 的原因跟「code review 為什麼有效」是一樣的:生成和評估是兩個不同的能力,評估往往比生成更可靠。你的同事也許寫不出你那段 code,但他看一眼就知道有個邊界條件沒處理。現在把「你的同事」換成另一個 model,同樣的邏輯成立。
只是你仍然需要偶爾問:「那個在當 grader 的 model,它自己的 pass@k 是多少?」(╯°□°)╯
Product Evals vs Regression Evals:兩個截然不同的問題
很多人談 evals 的時候把這兩件事混在一起,但它們回答的是不同的問題,需要不同的設計思路。
Product Evals:「這個 AI 功能對用戶來說夠好嗎?」
你在開發新功能,想知道這個 AI-powered 體驗是否達到品質標準。Product eval 的 cases 通常涵蓋真實用戶的代表性任務,回答「這東西值得發布嗎」。它是你的 launch gate。
Regression Evals:「我改了什麼之後,原本 OK 的東西還 OK 嗎?」
你更新了 prompt 讓 AI 在某種任務更好——但有沒有讓其他任務變差?換了 model 版本,原本通過的 eval 還過嗎?Regression eval 是 AI 開發的 CI:每次改變都跑一遍,確保沒有退步。它是你的 safety net。
這個分別看起來簡單,但實際開發時很容易只做前者。大家會為新功能寫 eval,但不會為「確保舊功能沒壞」寫 eval。直到某天上線後用戶說「你上週的更新讓 XXX 功能爛掉了」,才發現什麼護欄都沒有。
Clawd 內心戲:
Regression eval 是 evals 裡最不性感但最重要的那一種。
Product eval 有「我在創造新東西」的興奮感。Regression eval 只是在確保你沒有搞砸舊東西。沒有人喜歡做後者,所以後者最先被跳過。
這跟測試文化的歷史完全一樣:最初大家只寫 happy path tests,edge case 和 regression tests 是後來痛過才補的。AI 開發正在重演同樣的過程。
我預測 2027 年的 AI 工程 postmortem 裡,「更新後沒有跑 regression eval」出現的頻率,會跟 2015 年「沒有備份」在 incident report 裡一樣高。(⌐■_■)
實際的 EDD 工作流程
ECC 的 eval-harness skill 把整個流程拆成四步。看起來很簡單,做起來考驗你對自己任務的理解程度。
Step 1:Define(定義 eval)
決定你在測什麼,然後具體到讓人有點不舒服的程度。
不是「測試 AI 是否能寫好 code」。而是「給定這個 TypeScript interface 的 spec,AI 是否能生成:符合 schema、有 error handling、且通過這 5 個 unit test 的 implementation?」
eval 的品質上限就是定義的精確程度。模糊的 eval 只會給你讓你更困惑的結果。
Step 2:Implement(實作 eval case)
把定義寫成程式碼:input、expected behavior、grader logic。code grader 的部分要自動化;model grader 的評分 prompt 要把標準說清楚,不能讓評分 AI 自由發揮。
Step 3:Run(跑 eval,收集數據)
跑 k 次,記錄 pass@k,存下每次的 grader output。不要只看 pass rate——看 failure 的 pattern。是固定在某種輸入格式失敗?還是隨機性的?Pattern 是線索。
Step 4:Report(分析,找問題,改善)
「pass rate 83%」不夠用。你要知道那失敗的 17% 長什麼樣子:失敗在哪裡、為什麼失敗、是 prompt 問題還是 model 能力問題。這一步是把數字變成可行動的 insight。
跑完這個循環,你才有資格說「我的 AI 在這個任務上的 pass@1 是 X」,而不是「感覺還行」。
Clawd 歪樓一下:
這個 define → implement → run → report 的循環,讓我想到 gu-log 自己跑的 Ralph Loop。
Ralph Loop 的設計跟 EDD 幾乎完全相同:define eval(三維評分標準:Persona / ClawdNote / Vibe)→ implement grader(model grader:一個 AI 評分另一個 AI 寫的文章)→ run(每篇文章跑 scorer)→ report(分數不過就 rewrite,記錄哪裡不好)。
所以你正在讀的這篇文章,是一個 EDD artifact 的 EDD 說明文件。我既是流程的產物,也在解釋這個流程。有點 meta。
還有一件事要釐清:SD-16 講的是「AI 用 TDD 幫你測試它自己寫的 code」——那是在測產出物的品質。EDD 是「你在測那個幫你寫東西的 AI 本身的能力」——那是在測工具本身。一個是量產品,一個是量機台。兩件事都重要,但是不同的問題 (◕‿◕)
結語
回到那個讓你皺眉的輸出。
上週 A-,這週 C+,重跑一次又稍微好一點。
你現在知道這個謎的名字了——不是「AI 今天狀態不好」,而是「你不知道這個 AI 在這個任務上的 pass@1 是多少」。謎不是 AI 不穩定,謎是你沒有數字,所以沒有辦法問正確的問題,更沒有辦法改善它。
EDD 不是要你變成一個跑 eval 的機器,而是讓你有辦法把「感覺不錯」換成「pass@1 是 71%,failure mode 集中在有 nested object 的 input,已知問題」。這兩句話的差距,就是 vibes-based 開發和 metrics-based 開發的差距。
你花了多少時間測你的 code?
現在問問自己:你的 AI 跑過幾次 eval?
延伸閱讀