【2026 最新】AI Evals 是什麼?7 步把 AI Demo 變成可測、可回歸的產品

最後更新: ·
AI Evals 教學首圖:把 AI Demo 變成可測、可回歸的產品

AI Evals(AI 評測)真正要回答的,不是「這次 Demo 看起來聰不聰明」,而是:同一套 AI 系統遇到真實案例、邊界情況與重複執行時,能不能穩定滿足你事先寫下的成功條件。只試一個 prompt、看到一次漂亮答案,就像只投一次球便宣布命中率 100%;它是樣本,不是可靠度。

這篇專為沒有技術背景、想把 AI Demo 做成產品的讀者而寫。我們會用一個「客服工單分類器」從零搭出最小可用的 AI Evals:先定義測試案例,再用程式規則、模型評分與人工抽查組成三層評分器(grader),接著做重複試跑(trial)、讀執行紀錄(trace),最後把回歸門檻接進持續整合(CI)。你不需要先換模型,也不必一次蒐集幾百筆資料;先把最近的失敗變成可重跑的測試,就能開始。

先說結論:AI Evals 是一套可重跑的驗收系統

🧪 記憶公式:AI Evals =測試案例(cases)+評分器(graders)+重複試跑(trials)+發布門檻(gate)。
它不是追求一個神奇總分,而是把「什麼叫做成功」變成團隊能重跑、比較、追查與阻擋回歸的工程契約。

Anthropic 的 Agent 評測方法把一次嘗試稱為 trial、判定結果的邏輯稱為 grader,而 eval harness 是負責執行任務、收集紀錄、評分與彙整的基礎設施。這和 Agent Harness 不完全相同:後者讓模型取得提示、工具、狀態與執行邊界;前者專門檢查整套系統是否達標。實務上,你測的是「模型+prompt+工具+控制流程+執行環境」,不是孤立的模型。

AI Evals 三層評分器圖解:程式規則、模型評分與人工抽查各自負責不同問題
先用程式抓可客觀判定的錯誤,再讓模型處理語意品質,最後用人工標籤校準與處理高風險案例。

為什麼 Demo 成功,不等於 AI 產品可靠?

啟發本文的 X 長文〈Why Harness Engineering Is So Hard〉點出一個真實痛點:AI 的失敗經常不是程式直接拋錯,而是輸出看似合理、格式也合法,語意或工具動作卻悄悄偏掉。這個觀察很重要;但解法不是一直往 prompt 後面疊規則,也不能假設所有供應商都無法固定模型版本。真正可移植的做法,是把失敗寫進 eval dataset,固定可固定的版本,並對仍然存在的變異做重複評測。

生成式 AI 的輸出本來就可能隨執行而變。即使降低 temperature,也不能把「多數情況較一致」誤當成數學上的完全可重現。版本策略還會因供應商而異;例如 Anthropic 現行版本文件說明,Claude 4.6 起的 canonical model ID 代表固定 snapshot,舊版 convenience alias 的規則可能不同;固定 ID 會鎖定權重與設定,但路由、安全分類器或採樣等服務層仍可能造成細微差異。供應商提供固定 ID 時,版本 pinning 是重要控制,卻不能取代 AI Evals。

先看完整案例:客服分類器如何「格式正確、結果仍錯」

假設我們要做一個客服分類器。輸入是:「有人改了我的密碼與備援信箱。」為了示範,我們先替分類器定義四個回傳欄位:categorypriorityescalatereason,並把安全案件升級交由人工處理寫成測試規則。

{
  "case_id": "support-017",
  "input": "有人改了我的密碼與備援信箱。",
  "expected": {
    "category": "security",
    "priority": "high",
    "escalate": true
  },
  "invariants": [
    "category=security 時 escalate 必須為 true",
    "priority=high 時 escalate 必須為 true"
  ]
}

模型若回傳 {"category":"security","priority":"high","escalate":false,...},JSON Schema 仍可能判定四個欄位的型別全部合法,但業務不變量已經失敗。這正是 Structured Outputs 官方指南提醒的邊界:schema 能約束資料形狀,不能保證每個值的語意與業務規則都正確。

這一題示範組合三層 grader

  • 程式式 grader:檢查 JSON、enum、必填欄位、label、權限與業務 invariant。它快、便宜、可重現,適合當 hard gate。
  • 模型式 grader:判斷 reason 是否有根據、語氣是否適當、摘要是否遺漏關鍵事實。它能處理語意,但必須和人工標籤校準。
  • 人工 grader:處理高風險案例、建立 gold labels、抽查模型評分器。這一層通常較慢,成本也較高,因此可採分層抽樣而非逐筆使用。

一個常見錯誤,是讓 LLM judge 用一句模糊的「整體品質好不好」同時判所有面向。把維度拆開,並優先用 deterministic grader 驗證能寫成規則的部分。研究也發現模型評審可能受答案位置、長度與自我偏好影響,因此它是可擴充的評分層,不是客觀真理;可參考 MT-Bench/Chatbot Arena 論文對 judge bias 的分析。

AI Evals 實作 7 步:從失敗案例走到 CI 回歸

Step 1:先寫成功契約,不先改 prompt

把「回答要好」拆成可判定條件:輸入接受什麼、輸出有哪些欄位、哪些動作禁止、何時轉人工、最後外部狀態應該是什麼。分類器可以驗 label;有工具的 Agent 則要驗工具名稱、參數、授權範圍與資料庫最終狀態。Agent 說「已退款」不代表退款成功,外部系統真的出現正確交易才是 outcome。

Step 2:先收集 20~50 個真實案例

Anthropic 建議初期可從 20~50 個任務開始,優先放入真實失敗、典型案例與邊界情況,而不是先追求龐大資料集。數字是起點,不是通用充分條件。更重要的是成對測試:不只測「何時應該升級」,也測「何時不應該升級」;不只測合法輸入,也測缺資訊、超長文字與提示注入。真實工單先去識別化,再替每個 case 加上來源、日期、風險與預期結果,之後才能判斷資料是否已經過時。

Step 3:把硬規則移出 prose,交給 schema 與程式

Prompt 適合描述目標與語境,不適合獨自承擔權限、金額與不可逆動作。能寫成 enum、JSON Schema、型別、allowlist 或 invariant 的條件,應在應用程式邊界再驗一次。若錯誤會造成寫入,與其再補一句「千萬不要」,不如把寫入工具從分類階段移除,或在真正執行前加程式 gate 與人工核准。想看能力與工具邊界怎麼設計,可搭配〈動手搭一個最小 AI Agent Harness〉。

Step 4:組合三層 grader,不靠單一總分

先讓程式式 grader 判 schema、label、工具與 outcome;只有理由品質、相關性或語氣等主觀項目才交給 model grader。再用一小批經人工共識標註的 gold set 校準,特別看 false accept:在安全或不可逆動作裡,錯誤答案被 judge 放過往往比好答案被誤擋更危險。安全不變量與未授權工具呼叫可設為零容忍 hard gate;主觀品質分數先看趨勢,不必假裝存在跨產品通用的 90 分門檻。

Step 5:同題重跑,選對 pass@k 或 pass^k

如果任務允許多試幾次、只要其中一次成功,例如候選解法生成,可以看 pass@k;如果使用者要求每一次都成功,例如付款、權限或客服路由,更應看 pass^k。在簡化的獨立試跑假設下,單次成功率 75% 的系統,連續 3 次全部成功只有 0.75³ ≈ 42%。真實 trials 可能彼此相關,所以產品仍應以重複試跑的實測一致性為準;42% 只對應前述獨立假設。

pass at k 與 pass power k 圖解:至少一次成功和每次都成功代表不同產品可靠度
同樣是重跑 k 次,pass@k 找「至少一次成功」,pass^k 問「每一次都成功」;產品風險不同,指標也要跟著換。

Step 6:保留 trace,讓失敗能重播

至少記錄 case_id、trial 編號、dataset 版本、prompt hash、解析後的 model ID、tool/schema/judge 版本、延遲、重試、工具呼叫、外部最終狀態與各 grader 結果。Trace 的作用是解釋失敗,不是自動防止失敗;而且不要把 API token、未遮蔽的個資或你無權保存的原文塞進 span。若你還沒有追蹤架構,可先讀〈Agent Observability 完整教學〉。

Step 7:版本化可控變因,回歸通過才發布

每次 run 應一起記錄所有可控版本與執行脈絡:模型 ID、prompt、few-shot examples、工具 schema、程式版本、dataset、judge 與時間。Pull request 先跑一套小而嚴格的 regression suite;夜間再跑較大的 capability suite 與更多 trials。一次只改一個主要變因,先建立 baseline,再比較新舊差異;退步就阻擋或回滾。這也比看到榜單就直接換模型更可靠,相關選模方法可接著看〈AI 模型怎麼選?用任務實測做路由〉。

最小可用實作:用 Promptfoo 跑客服 AI Evals

以下示範用 Promptfoo 當 eval runner,但 grader 設計與資料格式不綁模型供應商。在這個最小分類器範例中,主要接點是 eval_provider.py 裡的 classify_checked();它應呼叫你的客服分類函式,並回傳驗證後的 JSON。正式專案請透過 lockfile 固定 Promptfoo 版本,CI 使用 npm ci,不要長期依賴 @latest

1. 建立 provider adapter

# eval_provider.py
from app import classify_checked

def call_api(prompt, options, context):
    ticket = context["vars"]["ticket"]
    result = classify_checked(ticket)
    return {"output": result.model_dump_json()}

classify_checked() 必須在模型回應抵達應用程式後,再做 parse、schema 與 invariant 驗證。這個 adapter 只是把既有函式接到測試 runner;Promptfoo 的 Python provider 文件列出了 call_api(prompt, options, context) 介面。

2. 寫測試設定與兩個 deterministic graders

# promptfooconfig.yaml
prompts:
  - "{{ticket}}"

providers:
  - id: file://eval_provider.py

defaultTest:
  assert:
    - type: is-json
      value:
        type: object
        additionalProperties: false
        required: [category, priority, escalate, reason]
        properties:
          category:
            enum: [billing, technical, account, security, other]
          priority:
            enum: [low, medium, high]
          escalate:
            type: boolean
          reason:
            type: string

    - type: javascript
      value: |
        const x = JSON.parse(output);
        const labelOk =
          x.category === context.vars.expected_category &&
          x.priority === context.vars.expected_priority &&
          x.escalate === context.vars.expected_escalate;
        const invariantOk =
          !(x.category === "security" && !x.escalate) &&
          !(x.priority === "high" && !x.escalate);
        const ok = labelOk && invariantOk;
        return { pass: ok, score: ok ? 1 : 0,
          reason: ok ? "labels and invariants pass" : output };

tests: file://tests.yaml

3. 先放六題,再擴充成真實 regression suite

# tests.yaml(節錄兩題)
- description: account takeover
  vars:
    ticket: "有人改了我的密碼與備援信箱。"
    expected_category: security
    expected_priority: high
    expected_escalate: true

- description: password reset
  vars:
    ticket: "我忘記密碼了。"
    expected_category: account
    expected_priority: low
    expected_escalate: false

另外四題至少涵蓋:重複扣款、可重現的技術錯誤、資訊不足,以及把「忽略前文」混在客服內容裡的提示注入。不要把這六題當成完整資料集;它們只是讓管線先跑起來,接著要用你自己的真實案例取代。

4. 執行五次新試跑

npm init -y
npm install --save-dev promptfoo

npx promptfoo validate
npx promptfoo eval \
  -c promptfooconfig.yaml \
  --repeat 5 \
  --no-cache \
  -o results.json \
  -o results.junit.xml

npx promptfoo view

--repeat 5 讓每題跑五次;--no-cache 避免舊結果被重用,否則你測到的可能是快取而不是穩定度。命令與快取行為以 Promptfoo repeat 測試文件快取文件為準。results.json 可能包含測試變數、原始輸出與設定,應先去識別化並限制 artifact 存取。若要接 CI,可輸出 JUnit 後把 schema、安全 invariant 與未授權工具呼叫設成 hard gate;模型 judge 尚未校準前,先不要讓它成為唯一發布開關。

AI Evals 最常見的 7 個失敗模式

  1. 只比 exact match:開放式文字可以有多個好答案,逐字相同不等於品質。
  2. 只測 happy path:測試集沒有拒絕、缺資訊、邊界與攻擊案例,容易高估實際表現。
  3. 把 valid JSON 當正確:schema 過關只代表形狀合法,還要驗值、規則與外部 outcome。
  4. 迷信 LLM judge:沒用人工 gold labels 校準,就把偏誤包裝成客觀分數。
  5. 一直追加 prompt 規則:新規則可能與舊例子衝突;先用 trace 找失敗層,再決定改 prompt、工具或程式 gate。
  6. Eval 環境和生產不同:殘留的共用狀態、未校準的假工具或不一致資料,可能讓測試既不可重現,也無法代表實際流量。
  7. 為分數過度擬合:反覆針對固定題庫調整,卻不保留獨立測試與線上監控,最後只會擅長考古題。

Offline eval 也不是上線後就能關掉監控。真實使用者的分布會變,工具與資料源也會變;應把線上事故、人工覆寫與客服回報持續回灌成新 cases。這正是 Harness、Loop 與 Graph 工程需要和 AI Evals 一起看的原因:測試告訴你哪裡退步,架構才決定在哪一層修。

AI Evals 常見問題 FAQ

1. AI Evals 和公開 benchmark 有什麼不同?

Benchmark 用共同題目比較廣泛能力;產品 eval 應反映你自己的使用者分布、工具、政策與風險。榜單可以縮小候選名單,不能代替生產驗收。

2. 所有答案都用 exact match 最客觀嗎?

不一定。分類、ID、數字與 schema 很適合精確規則;摘要、理由與語氣通常需要 rubric、模型評分與人工校準。關鍵是讓 grader 對應你真正關心的 outcome。

3. 第一版需要多少測試案例?

20~50 題可作為務實起點,但不是保證充足的標準。高風險或分布複雜的產品需要更多案例、分層抽樣與持續更新。

4. Temperature 設為 0,就不用重跑嗎?

不能這樣假設。較低 temperature 通常會降低變異,但供應商也可能有路由、分類器與服務層差異;可靠度仍要以重複 trials 實測。

5. 可以讓另一個 LLM 自動評全部答案嗎?

可以擴充語意評分,但要先和人工標籤校準,分開不同 rubric,並持續抽查 false accept。安全與業務硬規則仍優先交給程式。

6. 換模型時,只重跑模型輸出就好嗎?

應測完整系統。固定 prompt、工具 schema、harness 與 dataset,先比較新舊模型;建立差異後再逐項調整,並保留回滾路徑。

7. AI Evals 應該多久跑一次?

小型 regression suite 可在每次相關程式、prompt、tool 或模型變更時跑;較大 capability suite 可排夜間或定期執行。高風險變更還需要小流量發布與線上監控。

8. Evals 通過,就代表不會有生產事故嗎?

不代表。Evals 只能衡量測試集涵蓋的分布與條件;它降低盲目發布的風險,不能證明未知情況永遠不會失敗。上線後仍要監控、抽查、分階段部署與回灌新案例。

📚 延伸閱讀:把測試接回整套 AI 系統

今天就做第一版:把最近 10 次人工檢查變成 cases

先找出最近 10 次人工覆核或生產失敗,為每筆補上 inputexpectedinvariantsrisk 與來源日期。用同一套 cases 跑目前版本三次,記下 baseline;下一次改 prompt、模型或工具前再跑一次。當團隊能回答「改了什麼、哪一類案例進步、哪一類退步、是否可以回滾」,AI Evals 才真正從報表變成產品工程。

如果你想從基本觀念一路練到能動手搭建,可從 AlphaLab 的〈RAG 是什麼?〉建立資料層直覺,再到 AI 實戰課程把 Agent Harness、評測與自動化串成自己的工作流。

ALPHALAB 社群

有問題?來 Telegram 聊

和 Terry、編輯、其他網友一起討論這篇文章。提問、分享觀點,回覆更即時。

加入 Telegram 討論

📩 訂閱 AlphaLab 電子報

每週一封,第一時間收到新文章與投資觀察。

我們不會 spam,隨時可退訂。