TestingEvaluationLLM APICI/CDProduction Engineering

LLM API 測試與評估:打造你的 CI/CD Pipeline(2026)

閱讀 1 分鐘

3.2% 會第一個出現在稽核報告裡——每 100,000 次 API 呼叫有 3,200 個格式錯誤的 JSON payload,每一個都是一次無聲無息的商業邏輯失敗。

起因只是一個 model 字串的變更。沒有任何 dashboard 抓到它。HTTP 一直維持綠燈,結構化輸出卻在默默劣化,而你只能一路把殘骸追回三個 sprint 之前。

CI 整合的 eval 在 pull request 階段就攔下語意迴歸——力道等同於 unit test 擋下 null pointer。

這條 pipeline 涵蓋從決定性檢查到 LLM-as-Judge 評分,還有一個把今天的失敗變成明天 CI 測試案例的 closed loop。

為什麼「看起來對」大概撐到 50 次 review——然後就失靈

為什麼「看起來對嗎?」無法擴展

一個人類 reviewer 盯著 LLM 輸出,會在三個具體、可測量的方面失準:

  1. 疲勞。 連續 review 約 50 次之後,準確度急遽下滑。你的第 51 次判斷會明顯比第 5 次差——而且你不會察覺到這個下滑。
  2. 不一致。 兩個人類 reviewer 對同一組 LLM 輸出的 inter-rater reliability,通常低於 0.6——也就是說兩位夠格的人,有 40% 的機率對「這樣對嗎?」意見分歧。
  3. 成本與延遲。 1,000 個輸出 × 每次 review 90 秒 = 25 小時的人力時間。那是每次 eval 執行的 $750-2,500——而且排程要花好幾天。

機器評估一致、即時、而且幾乎免費。但「機器評估」不是單一一種東西——它是由三個 primitive 疊起來的 stack,你要根據測試對象來組合它們。

三個評估 primitive

Layer 1:決定性檢查(Deterministic Checks)。 微秒級。API 成本為零。JSON Schema 驗證。精確字串比對。tool call 成功/失敗計數。引用存在性驗證。拒答(refusal)regex 比對。這些能攔下約 50% 的真實世界失敗——而且是唯一能在每個請求上執行、不用擔心預算的 layer。從這裡開始。

Layer 2:Embedding 型指標(Embedding-Based Metrics)。 毫秒級。每次檢查約 $0.001。BERTScore。與參考答案的餘弦相似度。當你有「gold」答案、需要容許改寫的同義性判斷時很有用。對於存在多個合法答案的開放式生成,則不適用。

Layer 3:LLM-as-Judge。 數百毫秒。每次檢查 $0.01-0.10。一個夠力的 LLM 用 chain-of-thought 推理,依 rubric 幫輸出打分。能抓到決定性檢查漏掉的語意失敗——不忠實的摘要、沒幫助的回應、不該拒答的拒答。需要對照人類標註做校正,並主動緩解偏誤(position bias、verbosity bias、self-enhancement bias)。

6 層生產環境評估 stack

Dataset —Metrics/Rubrics —Judge —CI Gate —Production Observation —Closed Loop

任何一環斷掉,評估就變成一份沒人看的離線報告。dataset 從生產環境取樣,朝失敗方向加權。rubric 用可測量的條件定義「正確」。judge 一致地、且大規模地評分。CI gate 在 merge 前擋下迴歸。生產環境觀察抓到 CI 漏掉的東西。closed loop 把今天的生產失敗變成明天的 CI 測試案例。六層。一條 pipeline。沒有縫隙。

為什麼系統化測試改變一切

迴歸的隱藏成本

3.2% 無聲無息格式錯誤的 JSON 回應,代表每 100,000 次 API 呼叫就有 3,200 個壞掉的輸出。如果這些輸出驅動下游動作,你就背著 3,200 個商業邏輯失敗——而且要等到財務對帳對不上,你才會發現,而那可能是幾週之後的事。

一條 eval pipeline 會在 model 字串變更到達生產環境之前,先在 CI 攔下那 3.2%。架設這條 pipeline 的成本,低於一次事件的成本。

Prompt 漂移偵測

小幅的 model 版本升級——gpt-5.5-2026-07-01gpt-5.5-2026-07-15——不會附行為變更說明。changelog 只寫「改善指令遵循」。你的結構化抽取準確度掉了 4 個百分點。除非你對每個 model 版本都跑同一套 eval,否則你不會知道。

多供應商評估問題

如果你在模型之間做 routing——為了成本與可靠度,你應該這麼做——你的 routing pool 裡每個 model 都需要 eval 結果。不是只有 primary。透過一個統一的 API endpoint,你可以在一次整合裡,對所有 model 跑同一套 eval。相同 request 格式。相同測試案例。相同 judge model。唯一會變的變數是 model: "..."

在打造 eval suite 之前,先了解 routing pool 裡每個 model 的效能與成本特性。我們的跨供應商 benchmark 比較提供每個 model 的資料,幫你把測試優先順序奠定基礎。

如何打造你的評估 pipeline

Step 1:建立你的 Eval Dataset

dataset 是最難的一步,也是大多數團隊最不願意投資的一步。壞的 dataset 會給你在錯的事情上很準的分數。好的 dataset 從生產環境取樣、朝失敗加權、每週更新。

建立流程:

  1. 從生產日誌隨機取樣 200-500 個 request。不是從你的測試環境。真實使用者會問出測試作者永遠想不到的問題。
  2. 手動為每個做標註:正確答案是什麼?什麼會讓這個回應變錯?model 應該處理哪些 edge case?
  3. 依難度分層:簡單三分之一、中等三分之一、困難三分之一。如果你的 eval set 全是簡單查詢,你的分數會被灌水。
  4. 每週更新:從最近 7 天的生產日誌取樣新資料。替換掉 eval set 最舊的 20%。這讓你的 eval 跟使用者實際在問的問題保持同步——而這些問題會隨時間漂移。

防止最常見錯誤的規則: 你的 eval set 至少有 20% 必須來自歷史失敗。如果 eval set 只含 happy path 查詢,你測的是 model 在理想條件下能不能運作——而不是它在生產環境真正會發生的條件下能不能優雅地失敗。

Step 2:定義 Rubric,而不是只問「好不好?」

四個校正良好的 rubric,勝過十五個雜訊多的。每個 rubric 需要:

  • 精確定義:「faithfulness = 回應中每個事實主張都被檢索到的 context 支持」
  • 評分尺度:1-5 或 0-1
  • 及格門檻:「faithfulness ≥ 0.85」
  • 兩到三個已評分的範例,作為 judge model 的校正參考

多數 LLM API 應用的核心 rubric 組合:faithfulness(事實對嗎?)、answer relevance(回應有對到查詢嗎?)、context precision(檢索到的 chunk 真的相關嗎?)、task completion(model 有做到被要求的事嗎?)、refusal correctness(model 該拒答時拒答了——不該拒答時沒拒答?)。

Step 3:選擇並校正你的 Judge

GPT-4 是最廣為使用的 LLM judge——它與人類標註者的一致性在 MT-Bench 超過 80%、在 G-Eval 超過 85%。但一個未校正的 judge,給你的是一組看起來很精準、實際上系統性錯誤的數字。

校正流程: 拿 50 個人類標註的範例。跑過你的 judge model。計算 judge 分數與人類分數的相關性。任何 rubric 的相關性低於 0.75,那個 rubric 的 judge prompt 就需要調整——或者你需要換一個 judge model。

必須緩解的三個偏誤:

  • Position bias(位置偏誤)。 Judge 偏好先出現的那個回應。修正:每次評估都把回應順序隨機化。
  • Verbosity bias(冗長偏誤)。 Judge 不管品質,就是給較長的回應較高分。修正:把相關性與完整性拆成獨立維度來評分。
  • Self-enhancement bias(自我增強偏誤)。 Judge 會對同一個 model family 產出的輸出灌分。修正:judge 用跟生產環境不同的 model family。如果生產跑 Claude,就用 GPT-4 來評。或者用一個專用的 judge model。關於讓 judge 與生產 model 安全分離的 API key 隔離與存取控制,見安全最佳實務指南

最容易被忽略的規則: 固定你的 judge model 版本。當你把 judge 從 GPT-4 升到 GPT-4o,每一筆歷史分數都會變得不可比較。你無法分辨是生產 model 變好了,還是 judge 變嚴格了。要嘛讓 judge 版本維持不變,要嘛每次升級 judge 之後,都用你那 50 個人類標註範例重新校正,並建立新舊 judge 之間的分數對應。

Step 4:設定 CI Gate

兩個工具,兩種哲學:

  • Promptfoo。 開源。Git 整合。用 YAML 寫宣告式設定。適合想讓 eval 以程式碼形式、跟 prompt 住在同一個 repo 裡的團隊。
  • DeepEval。 Python 原生。30+ 個內建 metric。基於 decorator 的 CI/CD 整合。適合想把 eval 深度整合進 Python 測試套件的團隊。

不管用哪個工具,CI gate 的邏輯都是:

tests:
  - path: eval_dataset.jsonl
    asserts:
      - type: python
        value: |
          def check_regression(output, context):
              baseline = context['baseline_scores']
              current = compute_scores(output)
              for rubric, score in current.items():
                  if baseline[rubric] - score > 2:
                      return False, f"{rubric} dropped {baseline[rubric] - score:.1f} points"
              return True, "All rubrics within threshold"

任何 rubric 比 baseline 掉了超過 2 分——CI 失敗——merge 被擋。這不是可選項。一個讓關鍵 rubric 品質掉 3 分的 prompt 變更,永遠不該進到生產環境。你的 unit test 擋 null pointer exception;你的 eval gate 就該用同樣的力道擋下語意迴歸。餵給 CI gate 的 prompt 最佳化流程,在我們的LLM API 生產環境 prompt 工程指南裡有完整說明。

Step 5:生產環境觀察+Closed Loop

CI 評估抓的是部署前的迴歸。它抓不到 distribution shift、對抗性輸入、或你的 eval set 沒覆蓋到的 edge case。那些需要對生產 trace 做持續評估。

把 eval 分數掛到你的 OTel span 上。任何 rubric 在滾動視窗內持續掉了 2-5 分,就觸發警示。judge 校正方法論,以及餵給 CI gate 的 prompt 最佳化流程,都已經在本文前幾步講過。這裡引用的 chain-of-thought 評估方法論,是由G-Eval 論文(Liu et al., 2023)確立的。失敗的 trace 會依錯誤類型、prompt 版本、model 自動分群。帶有代表性失敗的具名問題,會被推回你的離線 eval dataset——這次是手動標註,並記錄下具體的失敗模式。

這個 closed loop,就是一條會隨時間往下走的 eval 分數,跟一條持續進步的 eval 分數之間的差別。沒有它,你的 eval set 會變陳舊、model 會漂移、CI gate 會變成一道形式上通過、而生產品質持續劣化的儀式。

特定 API 情境的測試模式

測試結構化輸出

光靠 JSON Schema 驗證就能攔下約 70% 的結構化輸出失敗。剩下的 30% 加上商業規則檢查:「price 不能是負數」「email 必須符合 regex」「total 必須等於 subtotal 加 tax」。跨欄位一致性檢查:「如果 payment_method 是 ‘credit_card’,last_four 就不能是 null」。

供應商特定的陷阱:OpenAI 把 function.arguments 回傳成 JSON 字串;Anthropic 把 tool_use.input 回傳成 JSON 物件。你的 parser 必須兩種都處理——你的 eval suite 也必須兩種都測。在 CI 裡 mock 這兩種回應格式。

跨供應商的完整 request/response 格式參考——包括結構化輸出、tool call、串流——見chat completions API 文件

測試 Tool Calling

四道檢查,依失敗頻率排序:(1) tool 名稱符合 schema。(2) 必要引數存在且型別正確。(3) 並行的 tool call 彼此不干擾。(4) tool 錯誤之後,model 用修正過的引數重試——或升級求助——而不是迴圈。

在測試裡設一個硬性迴圈上限:同一個 tool 連續被呼叫超過三次——測試失敗。Model 應該認出這個模式,而不是重複它。

測試 RAG 品質

三個維度:context relevance(檢索到的 chunk 是不是使用者問的那件事?)、answer faithfulness(答案裡每個主張是不是都被檢索到的 chunk 支持?)、citation accuracy(每條引用是不是都指向一個真的含有被引用資訊的 chunk?)。最低門檻:top-1 citation 準確度——90% 以上。低於這個,使用者會失去信任——而且很快。

為什麼多數 LLM eval pipeline 三個月內就失敗

只測 Happy Path

你的 eval set 裡是「退貨政策是什麼?」「怎麼重設密碼?」——乾淨、友善、格式完整的查詢。生產環境裡是「i cant log in wtf???」和「URGENT: my refund still hasn’t processed and it’s been TWO WEEKS」——帶錯字、帶怒氣、帶缺漏的 context。如果你的 eval set 沒包含接近生產的 edge case,你的 95% eval 分數就什麼也不是。

修正: 從生產日誌取樣。確保 eval set 至少有 20% 來自歷史失敗——那些先前產生過錯誤答案、拒答、或幻覺的查詢。

沒固定 Judge Model 版本

你把 judge 從 GPT-4 升到 GPT-4o。所有 eval 分數上移了 3 分。團隊慶祝「品質提升」。生產環境什麼都沒變。只是 judge 變寬鬆了。

修正: 鎖住 judge model 版本。如果非升不可,就對你那 50 個人類標註範例重新校正,並建立分數對應。沒有它,你的 eval 分數歷史就是雜訊。

在 Eval Set 上最佳化

你對自己的 eval set 調 prompt。95% 準確度。出貨。生產準確度:68%。eval set 裡藏著你最佳化所針對的模式。生產環境裡是其他所有東西。

修正: train/eval/test 分割(70/15/15)。最佳化只看 training set。CI 對 eval set 執行。test set 被保留——release 前只跑一次,它報出來的分數,就是你在部署前能得到最接近生產效能的估計。

一旦你的 eval gate 在 CI 通過,canary rollout、fallback chain 這類部署模式會保護你免於生產環境的 distribution shift。rollout 策略與 model 失效切換設定,見生產最佳化指南

延伸閱讀。 用我們的JSON mode 與結構化輸出比較擴充測試套件的結構化輸出那一面,它涵蓋了你的 CI pipeline 需要驗證的供應商特定格式處理。prompt 最佳化方法論見 Step 4;rollout 策略與 model 失效切換設定,見上面的生產最佳化指南。

FAQ

一開始需要幾個測試案例?

五十個是方向性回饋的最低要求——足以告訴你一個變更讓事情變好還變壞,但對 CI gate 來說雜訊太多。一百到五百個案例就有統計顯著性——單一個 edge case 失敗最多只能把分數搖動幾個百分點。從 50 個開始。每週從生產日誌加 20-30 個新案例。如果你是程式化 LLM 測試的新手、想先打好 API 基礎,我們的LLM API 新手入門指南在你打造 eval suite 之前,先講 request 結構。

LLM-as-Judge vs. 人工評估——差距有多大?

GPT-4 judge 在事實查核與指令遵循任務上,與人類標註者一致的比例超過 80%。差距最大的是主觀維度(創意、文風品質)。在客觀維度——faithfulness、格式合規、任務完成——LLM judge 匹敵甚至超越單一的人類標註者,因為它消除了疲勞與不一致。

我該用跟生產環境一樣的 model 當 judge 嗎?

不該。self-enhancement bias 是真的、可測量的——model 會把同 family 產出的分數灌高 5-10%。用不同的 model family,或一個專用 judge model。如果你的生產 stack 跑 Claude,就用 GPT-4 評估。

串流回應怎麼評估?

評估完整串接起來的回應,而不是個別 token。加上效能 assertion:TTFT(time-to-first-token,第一個 token 時間)低於你的目標門檻、token 間延遲 P95 在預算內。串流特定的 bug——像是 SSE event data 裡沒跳脫的換行符弄壞 parser——需要專用的決定性檢查。

怎麼在不寫三個 adapter 的情況下,讓同一套 eval suite 跑三個供應商?

把完全相同的測試案例送進一個 base URL,只把 model 參數在 gpt-5.5claude-sonnet-4-20250514gemini-3.1-pro 之間切換。一種 request 格式。一條 eval pipeline。唯一會變的變數是處理 prompt 的 model——而那正是你的 eval suite 設計來量測的東西。你的第一個、透過單一 base URL 的統一 eval request,請照快速入門指南

LLM 評估不是一個完成即結束的階段。它是你要持續維護的基礎設施。那 6 層 stack——dataset、rubric、judge、CI gate、生產觀察、closed loop——是了解你那些由 LLM 驅動的功能到底在變好還是變壞的最小可行系統。

先從 50 個測試案例和決定性檢查開始。這週就把它們跑進 CI。每週從生產日誌加 20 個案例。一個月後,你就有一個統計上有意義的 eval set,以及一道在使用者之前就攔下迴歸的 CI gate。

你的 eval suite 不該為每個要測的 model 都準備一個供應商特定 adapter。在 TokSpan 開始測試——透過單一整合點,把同樣的 50 個測試案例拿去跑 GPT、Claude、Gemini。