測驗:用 LLM-as-a-Judge 評估你的模型輸出
共 5 題,點選答案後會立即顯示結果
1. 文章指出,為什麼 LLM 的輸出「難以用傳統 metric(如 exact match、BLEU)評估」?
2. 在評估資料集中,一筆資料的 inputs 和 expectations 分別代表什麼?
3. 關於內建 scorer 需不需要「標準答案(expected_response)」,下列何者正確?
4. 在 make_judge 建立自訂 judge 時,判準(rubric)具體是寫在哪個部分?
5. 文章說要用評估來「比較不同 prompt 或模型版本」,關鍵前提是什麼?
系列第 2 篇,共 4 篇|難度:L3-熟練
前置:已讀 #01(Tracing 入門),了解 trace 概念;有基本 Python 與 LLM API 經驗
一句話說明
LLM 的輸出沒有標準答案,所以我們請「另一個 LLM 當評審」來打分,MLflow 把這整套包成 mlflow.genai.evaluate。
為什麼 LLM 輸出不能用傳統 metric
傳統 ML 評估很單純:分類問題比對 label 算 accuracy,回歸問題算 RMSE。有標準答案,一個 == 就分勝負。
LLM 不是這樣。你問「幫我把這封信寫得更客氣」,正確答案有無限多種。用字串比對(exact match)會把 99% 的好答案判成錯;用 BLEU、ROUGE 這種比對「字重疊」的指標,也只是在測「跟參考答案用字像不像」,測不出「這句話到底通不通、有沒有唬爛」。
所以現在的主流做法是 LLM-as-a-Judge:拿一個 LLM 當評審,給它「題目、AI 的回答、(可選的)標準答案」,請它照一份判準(rubric)打分或給 pass/fail。MLflow 的 GenAI 評估就是把這件事標準化。
作為 Vibe Coder,你的任務不是從零實作評審邏輯——那是 mlflow.genai 幫你做的。你的任務是看懂 AI 幫你寫的評估腳本在評什麼、判準嚴不嚴、結果能不能信。這篇就是教你讀這種 code。
✅ 必看懂(這篇的核心):
- 評估資料集長什麼樣(inputs / expectations)
- mlflow.genai.evaluate(...) 三個關鍵參數
- 內建 scorer(Correctness / RelevanceToQuery / Guidelines…)
- 自訂 judge(make_judge)的判準寫在哪
📌 知道就好(遇到再查):
- 把既有 trace 撈出來當評估資料
- 在 MLflow UI 比較兩個 run
🕰️ 認得就好(舊寫法,維護舊專案會看到):
- mlflow.evaluate(model_type="question-answering")(舊版評估入口)
Code language: JavaScript (javascript)30 秒範例:一個最小的評估
uv add mlflow openai
import mlflow
from mlflow.genai.scorers import Correctness
# 1. 評估資料:一筆一筆的「題目 + 期望」
data = [
{
"inputs": {"question": "MLflow 的 tracking server 預設 port 是幾號?"},
"expectations": {"expected_response": "5000"},
},
]
# 2. 被評估的東西:一個吃 inputs、吐回答的函式
def my_app(question: str) -> str:
return call_my_llm(question) # 你的 LLM 應用
# 3. 跑評估
results = mlflow.genai.evaluate(
data=data,
predict_fn=my_app,
scorers=[Correctness()], # 用內建的「正確性」評審
)
Code language: PHP (php)這段代碼做了什麼:
data:準備一份評估集,每筆有inputs(餵給你 app 的題目)和expectations(你期望它答成怎樣)predict_fn:指向你要被打分的應用,MLflow 會把每筆inputs餵進去拿回答scorers:指定評審。Correctness()是內建的 LLM judge,會拿「回答」對「expected_response」判對錯- 跑完,結果進 MLflow,可以在 UI 看每一題的分數和評審理由
核心概念翻譯
| 你會看到 | 意思 |
|---|---|
inputs |
餵給你 app 的輸入(題目、context…),一個 dict |
expectations |
你對這題的期望(標準答案、該遵守的規則),評審會參考 |
predict_fn |
被評估的應用函式,吃 inputs 吐 outputs |
scorers=[...] |
一串評審。可以混用內建 scorer 和自訂 judge |
Correctness() |
內建 LLM judge:回答對不對(比對 expected_response) |
RelevanceToQuery() |
內建:回答有沒有切題(不需要標準答案) |
RetrievalGroundedness() |
內建:回答有沒有「根據 context」而不是自己瞎編(測 RAG 幻覺) |
Guidelines(...) |
內建:你用白話寫一條規則,judge 判有沒有遵守 |
make_judge(...) |
自己造一個 judge,判準(rubric)你自己寫 |
一個關鍵直覺:有些 scorer 需要 expectations(標準答案),有些不需要。
Correctness要標準答案(拿回答比對 expected_response)RelevanceToQuery、RetrievalGroundedness不用標準答案(只看題目、回答、context 之間合不合理)
這很重要,因為準備標準答案很貴。看到一份評估腳本只用了「不需標準答案」的 scorer,你就知道它省了人工標註,但也就評不了「答案正不正確」這件事。
評估資料集:一筆資料長怎樣
這是整個評估的地基,一定要看懂。最完整的一筆長這樣:
{
"inputs": { # 餵給 app 的輸入
"question": "退貨要幾天內?",
"context": "本店退貨政策為 7 天內…", # RAG 場景會有檢索到的資料
},
"expectations": { # 你的期望(評審參考用)
"expected_response": "7 天內可退貨", # 標準答案
"expected_facts": ["7 天"], # 必須提到的事實點
},
}
Code language: PHP (php)逐欄翻譯:
"inputs" # 這題要問 app 什麼(會被餵進 predict_fn)
"question" # 使用者的問題
"context" # 檢索到的參考資料(RAG 才有)
"expectations" # 這題「答對」長什麼樣
"expected_response" # 完整的理想答案
"expected_facts" # 只要答案包含這些關鍵事實就算對(比逐字比對寬鬆)
Code language: PHP (php)你不用每個欄位都填。最省的版本只有 inputs(配不需標準答案的 scorer);要評正確性才需要 expectations。
把 trace 轉成評估資料(承接 #01)
#01 教你的 trace,其實就是現成的評估素材——裡面已經有真實使用者問了什麼、你的 app 回了什麼。MLflow 可以把 trace 撈出來直接當 data:
# 把過去記錄下來的 trace 撈出來當評估集
traces = mlflow.search_traces(
experiment_ids=["123"],
max_results=50,
)
results = mlflow.genai.evaluate(
data=traces, # 直接餵 trace,不用手寫 inputs
scorers=[RelevanceToQuery()],
)
Code language: PHP (php)這在幹嘛:不用自己手刻評估集,直接拿線上真實流量來評。MLflow 認得 trace 格式,會自動抽出 inputs / outputs。這也是為什麼 #01 要你先學會 tracing——沒有 trace 就沒有真實評估資料。
內建 scorers:AI 最常用這幾個
看評估腳本時,先看它 import 了哪些 scorer,就大概知道它在評什麼。
用法 1:Guidelines —— 用白話寫規則
這是最好懂、也最常被 AI 拿來用的一種。你用自然語言寫一條規則,judge 幫你判有沒有遵守:
from mlflow.genai.scorers import Guidelines
tone = Guidelines(
name="polite_tone",
guidelines="回答必須保持禮貌、專業,不能出現情緒性或責備使用者的字眼。",
)
results = mlflow.genai.evaluate(
data=data,
predict_fn=my_app,
scorers=[tone],
)
Code language: JavaScript (javascript)翻譯:「請一個 LLM 讀每個回答,判斷它有沒有做到『禮貌專業』這條規則,給 pass 或 fail 加理由。」不需要標準答案,因為判的是「風格有沒有守規矩」。
用法 2:多個 scorer 一起評
真實腳本通常一次掛好幾個評審,從不同角度打分:
from mlflow.genai.scorers import (
Correctness, RelevanceToQuery, RetrievalGroundedness,
)
results = mlflow.genai.evaluate(
data=data,
predict_fn=rag_app,
scorers=[
Correctness(), # 答對嗎(要 expected_response)
RelevanceToQuery(), # 切題嗎
RetrievalGroundedness(), # 有沒有根據檢索資料、還是在幻覺
],
)
Code language: PHP (php)翻譯:這是典型的 RAG 評估組合——同時測「正確、切題、不亂編」。結果表格每個 scorer 一欄,你能看出「答對但離題」或「切題但在唬爛」這種細節。
自訂 judge:判準(rubric)自己寫
內建 scorer 不夠用時,AI 會幫你用 make_judge 造一個。這是評估腳本裡最需要盯緊的部分,因為判準的鬆緊全在這段文字裡。
from mlflow.genai.judges import make_judge
conciseness = make_judge(
name="conciseness",
instructions=(
"評估這個回答是否簡潔。\n"
"問題:{{ inputs }}\n"
"回答:{{ outputs }}\n"
"如果回答直接、沒有廢話、沒有重複,評為 'pass';\n"
"如果冗長、繞圈子、重複同樣的意思,評為 'fail'。"
),
model="openai:/gpt-4o", # 用哪個模型當評審
)
Code language: PHP (php)逐段翻譯:
name="conciseness" # 這個評審的名字(會變成結果表格的欄名)
instructions="..." # 判準本體:告訴評審 LLM 怎麼打分
"{{ inputs }}" # 佔位符,跑的時候換成該題的輸入
"{{ outputs }}" # 佔位符,換成 app 的回答
"評為 'pass' / 'fail'" # 明確的輸出格式(judge 要回這個)
model="openai:/gpt-4o" # 指定當評審的模型(越強的模型判得越準,但越貴)
Code language: PHP (php)這在幹嘛:你在 instructions 裡寫清楚「什麼算好、什麼算壞」,{{ inputs }} / {{ outputs }} 這些佔位符會在每一題被自動代換。這就是你的 rubric——judge 好不好用,全看這段寫得夠不夠具體。
判準設計的重點:越具體越可靠。「評估回答品質」這種模糊指令會讓 judge 亂給分;「有沒有提到退貨天數、語氣禮不禮貌」這種可檢查的條件才穩定。
讀懂評估結果
跑完 evaluate 會回一個結果物件,也會寫進 MLflow。你會看到類似這樣的表格(每列一題,每個 scorer 一欄):
question | correctness | relevance | conciseness
----------------------|-------------|-----------|------------
退貨要幾天? | pass | pass | fail
運費怎麼算? | fail | pass | pass
怎麼讀:橫著看單題(這題哪個面向掛了),直著看趨勢(哪個 scorer 整體偏低)。上面第一列「答對、切題,但太囉嗦」;第二列「切題、簡潔,但答錯」。
在 UI 比較不同 prompt / 模型版本
評估最大的價值是比較。你改了 prompt 或換了模型,各跑一次 evaluate,就是兩個 MLflow run,在 UI 並排看哪個分數高:
# 版本 A
with mlflow.start_run(run_name="prompt-v1"):
mlflow.genai.evaluate(data=data, predict_fn=app_v1, scorers=scorers)
# 版本 B
with mlflow.start_run(run_name="prompt-v2"):
mlflow.genai.evaluate(data=data, predict_fn=app_v2, scorers=scorers)
Code language: PHP (php)這在幹嘛:兩次評估用同一份 data 和同一組 scorers,只換 predict_fn。這樣兩個 run 的分數才可比——你才能理直氣壯說「v2 的 correctness 從 70% 升到 85%」。到 MLflow UI 勾選兩個 run 就能並排比較。
🚩 紅旗:評估腳本最容易出的問題
評估這種東西最陰險的地方是——它永遠會給你一個數字,但數字不一定有意義。以下幾個是 AI 幫你寫評估時最常見的坑。
🚩 紅旗 1:judge prompt 過於寬鬆
quality = make_judge(
name="quality",
instructions="判斷這個回答好不好。{{ outputs }}", # 🚩 判準太模糊
model="openai:/gpt-4o",
)
Code language: PHP (php)為什麼危險:「好不好」沒有可檢查的標準,judge 只能憑感覺,結果幾乎全 pass,你會誤以為模型很棒。這種評估等於沒評。
跟 AI 這樣說:「把這個 judge 的 instructions 改具體,列出明確可檢查的條件(例如要包含哪些資訊、語氣要求、長度限制),並要求它輸出 pass/fail 加理由。」
🚩 紅旗 2:資料洩漏(標準答案混進輸入)
data = [{
"inputs": {
"question": "退貨幾天?",
"answer": "7 天", # 🚩 標準答案被放進 inputs 餵給 app 了
},
"expectations": {"expected_response": "7 天"},
}]
Code language: PHP (php)為什麼危險:inputs 是會餵進你 app 的東西。把答案夾在 inputs 裡,等於考試把答案印在考卷上——app 直接抄,評估分數虛高,上線就現形。標準答案只該放在 expectations。
跟 AI 這樣說:「檢查我的評估集,標準答案應該只出現在 expectations,不能出現在 inputs 裡。」
🚩 紅旗 3:用被評估的同一個模型當評審
judge = make_judge(name="x", instructions="...", model="openai:/gpt-4o")
# 而 my_app 內部也是用 gpt-4o 生成回答 🚩 球員兼裁判
Code language: PHP (php)為什麼危險:同一個模型有共同盲點,它看不出自己的錯,還可能偏好「跟自己風格像」的答案(self-preference bias),分數會系統性偏高。
跟 AI 這樣說:「評審模型和被評估的模型不要用同一個,換一個獨立的(最好是更強的)模型當 judge。」
🚩 紅旗 4:只信 judge,完全沒有人工抽查
為什麼危險:LLM judge 本身也會出錯、也會有偏好。如果你從沒人工看過 judge 的判斷對不對,你等於用一個沒被驗證過的尺在量東西。
跟 AI 這樣說:「幫我抽 10 筆 judge 判 pass 和 fail 的結果列出來,我要人工核對 judge 判得對不對。」(正式做法是先讓 judge 和人類標註對齊,再放心大規模用。)
Vibe Coder 驗收檢查點
拿到一份 AI 寫的評估腳本,照這個清單過一遍:
- [ ] 打開評估集,確認 標準答案只在
expectations、沒混進inputs(防資料洩漏) - [ ] 找到每個
make_judge的instructions,讀一遍——判準是具體可檢查的,還是「好不好」這種模糊詞? - [ ] 確認 judge 的 model 和被評估的 model 不是同一個
- [ ] 跑一次評估,到 MLflow UI 打開結果表格,手動看 3-5 題 judge 的評分理由,判斷它判得合不合理
- [ ] 要比較版本時,確認兩個 run 用了同一份 data 和同一組 scorers(否則分數不可比)
- [ ] 問 AI:「這份評估有沒有需要標準答案的 scorer?我的評估集有準備 expectations 嗎?」
看不懂就這樣問 AI
「用白話一段一段解釋這份 MLflow 評估腳本在評什麼:它用了哪些 scorer、每個 scorer 需不需要標準答案、判準寫在哪。我要能對別人講清楚。」
「這個 make_judge 的 instructions 判準夠具體嗎?會不會太寬鬆導致什麼答案都 pass?幫我列出可以改進的地方。」
「幫我檢查這份評估集有沒有資料洩漏——標準答案有沒有不小心出現在會餵給 app 的 inputs 裡?」
小結
- LLM 輸出沒有唯一正解,所以用 LLM-as-a-Judge 打分,MLflow 用
mlflow.genai.evaluate把它標準化 - 評估集的地基是
inputs(餵給 app)+expectations(你的期望);標準答案只放 expectations - 內建 scorer(Correctness / RelevanceToQuery / RetrievalGroundedness / Guidelines)能快速上手,其中有些需要標準答案、有些不用
- 自訂 judge 用
make_judge,判準(rubric)就是那段instructions,越具體越可靠 - 讀結果表格要橫看單題、直看趨勢;比較版本要固定 data 和 scorers
- 四大紅旗:judge 太寬鬆、資料洩漏、球員兼裁判、完全不做人工抽查
下一篇(#03)我們會把評估接進實際的迭代流程,看怎麼用評估結果驅動 prompt 優化。
進階測驗:用 LLM-as-a-Judge 評估你的模型輸出
共 5 題,包含情境題與錯誤診斷題。