【MLflow GenAI 教學】#04 Evaluation:用 LLM 評估 LLM 輸出品質

測驗:MLflow GenAI 教學 – Evaluation

共 5 題,點選答案後會立即顯示結果

1. MLflow Evaluation 採用的核心評估方法稱為什麼?

  • A. Human-in-the-Loop
  • B. A/B Testing
  • C. LLM-as-a-Judge
  • D. Reinforcement Learning

2. 在 MLflow 評估框架中,定義評估標準的核心元件稱為什麼?

  • A. Evaluator
  • B. Scorer
  • C. Metric
  • D. Judge

3. 下列哪個 Scorer 不需要 Ground Truth(預期答案)就能運作?

  • A. Correctness
  • B. Equivalence
  • C. Guidelines
  • D. RelevanceToQuery

4. 使用 mlflow.genai.evaluate() 時,必須提供哪三個核心元素?

  • A. Model、Prompt、Temperature
  • B. Dataset、Predict Function、Scorers
  • C. Input、Output、Metrics
  • D. Experiment、Run、Artifacts

5. 根據 MLflow 最佳實踐,評分方式應該優先使用哪種類型?

  • A. 1-10 的數值評分
  • B. 百分比評分
  • C. 二元(pass/fail)或少量類別的評分
  • D. 連續數值評分(0.0-1.0)

為什麼需要自動化評估?

當你開發 GenAI 應用時,一定會遇到這個問題:怎麼知道模型輸出的品質好不好?

傳統的做法是人工測試——寫幾個問題、看看回答、憑感覺判斷。但這種方式有幾個致命缺陷:

  1. 無法規模化:測 10 個案例還行,測 1000 個就崩潰
  2. 品質難以量化:「感覺不錯」無法追蹤改善幅度
  3. 無法持續監控:Production 環境的品質退化很難發現
  4. 難以比較版本:新 prompt 真的比舊的好嗎?

MLflow Evaluation 解決的正是這些問題。它讓你用程式化的方式定義品質標準,然後自動評估每一次輸出。


LLM-as-a-Judge 原理

MLflow 採用的核心方法叫做 LLM-as-a-Judge——用一個 LLM 來評估另一個 LLM 的輸出。

聽起來有點奇怪:用 AI 評估 AI,可靠嗎?

研究顯示,當評估標準明確定義時,LLM 判斷的一致性其實相當高。特別是對於以下任務:

  • 回答是否相關
  • 內容是否有害
  • 是否符合特定風格指南
  • 事實是否正確(需要參考資料)

MLflow 預設使用 GPT-4o-mini 作為 Judge 模型,但你可以換成其他模型:

from mlflow.genai.scorers import Correctness

# 使用不同的 Judge 模型
Correctness(model="anthropic:/claude-4-opus")
Correctness(model="openai:/gpt-4o")
Code language: PHP (php)

Scorer 是什麼?

在 MLflow 的評估框架中,Scorer 是定義評估標準的核心元件。你可以把它想成一個評分器,輸入是模型的輸出,輸出是品質分數。

MLflow 提供五種 Scorer:

類型 說明 適用場景
Predefined Scorers 內建的評估器 快速開始
Guidelines-based 用自然語言描述 pass/fail 條件 合規檢查、風格驗證
Template-based 用模板變數定義評估邏輯 自訂複雜評估
Agent-as-a-Judge 分析完整 Trace 多步驟流程評估
Code-based 純 Python 邏輯 確定性規則檢查

內建評估指標

MLflow 提供多個預定義的 Scorer,讓你不用從零開始:

單輪對話評估

from mlflow.genai.scorers import (
    Correctness,          # 答案正確性(需要 ground truth)
    RelevanceToQuery,     # 回答是否切題
    Completeness,         # 是否完整回答所有問題
    Fluency,              # 語法流暢度
    Safety,               # 是否包含有害內容
    RetrievalGroundedness, # 回答是否有根據(RAG 應用)
    RetrievalRelevance,   # 檢索結果是否相關
    Guidelines,           # 自訂指南檢查
)
Code language: PHP (php)

需要 Ground Truth 的 Scorer

Scorer 說明
Correctness 回答是否與預期答案一致
Equivalence 回答是否等價於預期輸出
Guidelines 是否符合特定指南

不需要 Ground Truth 的 Scorer

Scorer 說明
RelevanceToQuery 回答是否針對問題
Completeness 是否完整回答
Fluency 語法是否流暢
Safety 是否安全無害
RetrievalGroundedness 回答是否有檢索依據

mlflow.genai.evaluate() 基本用法

現在來看實際的程式碼。評估流程有三個核心元素:

  1. Dataset:評估資料集
  2. Predict Function:你的模型或應用
  3. Scorers:評估標準

最小範例

import mlflow
from mlflow.genai.scorers import Correctness, RelevanceToQuery

# 1. 準備評估資料集
eval_dataset = [
    {
        "inputs": {"question": "MLflow 可以管理 prompt 嗎?"},
        "expectations": {"expected_response": "可以,MLflow 提供 Prompt Registry 功能"},
    },
    {
        "inputs": {"question": "什麼是 Tracing?"},
        "expectations": {"expected_response": "Tracing 是追蹤 LLM 應用執行流程的功能"},
    },
]

# 2. 定義你的應用(這裡用簡單函數示範)
def my_app(question: str) -> str:
    # 實際上這裡會呼叫 LLM
    return "MLflow 提供完整的 prompt 管理功能"

# 3. 執行評估
results = mlflow.genai.evaluate(
    data=eval_dataset,
    predict_fn=my_app,
    scorers=[Correctness(), RelevanceToQuery()],
)
Code language: PHP (php)

資料集結構

每筆資料包含:

  • inputs:傳給模型的輸入(dict 格式)
  • expectations:預期結果(用於需要 ground truth 的 Scorer)
  • tags:可選的分類標籤
{
    "inputs": {"question": "如何使用 Docker?"},
    "expectations": {
        "expected_response": "...",
        "key_concepts": ["container", "image", "dockerfile"]
    },
    "tags": {"topic": "devops", "difficulty": "beginner"},
}
Code language: JSON / JSON with Comments (json)

使用 Guidelines Scorer

當內建 Scorer 無法滿足需求時,Guidelines 是最簡單的自訂方式:

from mlflow.genai.scorers import Guidelines

# 定義你的評估指南
professional_tone = Guidelines(
    name="professional_tone",
    guidelines="回答必須保持專業語調,不使用口語或表情符號"
)

no_code_in_response = Guidelines(
    name="no_code",
    guidelines="回答中不應包含程式碼範例"
)

# 使用多個指南
results = mlflow.genai.evaluate(
    data=eval_dataset,
    predict_fn=my_app,
    scorers=[professional_tone, no_code_in_response],
)
Code language: PHP (php)

Guidelines Scorer 會:

  1. 把你的指南轉成評估 prompt
  2. 讓 Judge 模型判斷 pass 或 fail
  3. 提供判斷理由

建立自訂評估指標:make_judge()

當你需要更複雜的評估邏輯時,使用 make_judge() 建立自訂 Scorer:

from mlflow.genai.judges import make_judge
from typing import Literal

# 建立一個評估「連貫性」的 Judge
coherence_judge = make_judge(
    name="coherence",
    instructions=(
        "評估回答是否連貫,保持一致的語調,並有清楚的邏輯流程。\n"
        "問題: {{ inputs }}\n"
        "回答: {{ outputs }}\n"
    ),
    feedback_value_type=Literal["coherent", "somewhat_coherent", "incoherent"],
    model="openai:/gpt-4o-mini",
)
Code language: PHP (php)

Template 變數

make_judge() 支援以下保留變數:

變數 說明
{{ inputs }} 模型的輸入資料
{{ outputs }} 模型的輸出結果
{{ expectations }} 預期答案(ground truth)
{{ trace }} 完整執行追蹤(不能與其他變數混用)
{{ conversation }} 多輪對話歷史

feedback_value_type 選項

# 布林值:pass/fail
make_judge(..., feedback_value_type=bool)

# 數值評分
make_judge(..., feedback_value_type=int)    # 整數
make_judge(..., feedback_value_type=float)  # 浮點數

# 分類結果(推薦)
make_judge(..., feedback_value_type=Literal["good", "acceptable", "poor"])
Code language: PHP (php)

完整範例:評估事實正確性

from mlflow.genai.judges import make_judge
from typing import Literal

factual_accuracy_judge = make_judge(
    name="factual_accuracy",
    instructions="""
    評估回答的事實正確性。

    參考資料: {{ expectations }}

    回答: {{ outputs }}

    檢查回答中的事實陳述是否與參考資料一致。
    - "accurate": 所有事實陳述都正確
    - "partially_accurate": 部分正確,部分錯誤或遺漏
    - "inaccurate": 主要事實錯誤或存在幻覺
    """,
    feedback_value_type=Literal["accurate", "partially_accurate", "inaccurate"],
    model="openai:/gpt-4o-mini",
)

# 使用自訂 Judge
results = mlflow.genai.evaluate(
    data=eval_dataset,
    predict_fn=my_app,
    scorers=[factual_accuracy_judge],
)
Code language: PHP (php)

從 Production Traces 建立評估資料集

MLflow 最強大的功能之一是能從實際運行的 Traces 擷取評估資料。這解決了「評估資料集不夠真實」的問題。

步驟 1:搜尋 Traces

import mlflow
from datetime import datetime, timedelta

# 取得過去 24 小時的 traces
yesterday = datetime.now() - timedelta(days=1)
traces = mlflow.search_traces(
    filter_string=f"timestamp > {int(yesterday.timestamp() * 1000)}"
)

# traces 是 pandas DataFrame
print(f"找到 {len(traces)} 筆 traces")
Code language: PHP (php)

步驟 2:直接評估 Traces

關鍵來了——你可以直接把 traces 丟進 evaluate()不需要 predict_fn

from mlflow.genai.scorers import RetrievalGroundedness, RelevanceToQuery, Guidelines

# 定義 Scorers
scorers = [
    RetrievalGroundedness(),
    RelevanceToQuery(),
    Guidelines(
        name="professional_tone",
        guidelines="回答必須保持專業語調"
    ),
]

# 直接評估 traces
results = mlflow.genai.evaluate(
    data=traces,
    scorers=scorers,
)
Code language: PHP (php)

MLflow 會自動從 Trace 物件中提取 inputs、outputs 和其他資訊。

為什麼這很重要?

  1. 離線評估:不用重新跑模型,節省成本
  2. 真實資料:評估的是實際用戶互動
  3. 品質監控:定期評估 production traces 以發現退化
  4. 建立 Ground Truth:從真實案例中挑選好的回答作為標準

實戰:比較不同 Prompt 版本

現在來看一個完整的實戰案例:比較兩個 prompt 版本的效果。

情境設定

假設你有一個 QA 應用,想測試兩種不同的 system prompt:

import mlflow
from openai import OpenAI

client = OpenAI()

# Prompt 版本 1:簡潔風格
PROMPT_V1 = [
    {"role": "system", "content": "你是一個助手。簡潔回答問題。"},
    {"role": "user", "content": "問題: {question}"},
]

# Prompt 版本 2:詳細風格
PROMPT_V2 = [
    {"role": "system", "content": "你是一個專業的技術助手。請詳細解釋概念,並提供相關範例。"},
    {"role": "user", "content": "問題: {question}"},
]
Code language: PHP (php)

建立評估資料集

eval_dataset = [
    {
        "inputs": {"question": "什麼是 Docker?"},
        "expectations": {
            "key_concepts": ["容器", "虛擬化", "映像檔", "隔離"]
        },
    },
    {
        "inputs": {"question": "如何建立 REST API?"},
        "expectations": {
            "key_concepts": ["HTTP", "端點", "請求", "回應"]
        },
    },
    {
        "inputs": {"question": "Git 和 GitHub 有什麼不同?"},
        "expectations": {
            "key_concepts": ["版本控制", "本地", "遠端", "平台"]
        },
    },
]
Code language: JavaScript (javascript)

定義 Scorers

from mlflow.genai.scorers import RelevanceToQuery, Completeness, Guidelines
from mlflow.genai.judges import make_judge
from typing import Literal

# 自訂 Scorer:概念涵蓋度
concept_coverage = make_judge(
    name="concept_coverage",
    instructions="""
    檢查回答是否涵蓋預期的關鍵概念。

    預期概念: {{ expectations }}
    回答: {{ outputs }}

    評估回答涵蓋了多少預期概念。
    """,
    feedback_value_type=Literal["full", "partial", "minimal"],
    model="openai:/gpt-4o-mini",
)

scorers = [
    RelevanceToQuery(),
    Completeness(),
    Guidelines(name="is_professional", guidelines="回答必須專業且有條理"),
    concept_coverage,
]
Code language: PHP (php)

執行比較評估

# 版本 1 的 predict function
@mlflow.trace
def predict_v1(question: str) -> str:
    messages = [
        {"role": "system", "content": "你是一個助手。簡潔回答問題。"},
        {"role": "user", "content": f"問題: {question}"},
    ]
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=messages,
    )
    return response.choices[0].message.content

# 版本 2 的 predict function
@mlflow.trace
def predict_v2(question: str) -> str:
    messages = [
        {"role": "system", "content": "你是一個專業的技術助手。請詳細解釋概念,並提供相關範例。"},
        {"role": "user", "content": f"問題: {question}"},
    ]
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=messages,
    )
    return response.choices[0].message.content

# 分別評估兩個版本
with mlflow.start_run(run_name="prompt_v1_evaluation"):
    results_v1 = mlflow.genai.evaluate(
        data=eval_dataset,
        predict_fn=predict_v1,
        scorers=scorers,
    )

with mlflow.start_run(run_name="prompt_v2_evaluation"):
    results_v2 = mlflow.genai.evaluate(
        data=eval_dataset,
        predict_fn=predict_v2,
        scorers=scorers,
    )
Code language: PHP (php)

查看結果

評估完成後,你可以:

  1. 在 MLflow UI 查看:比較兩個 run 的指標
  2. 程式化分析
# 取得評估結果的 DataFrame
print("=== Prompt V1 結果 ===")
print(results_v1.tables["eval_results"])

print("\n=== Prompt V2 結果 ===")
print(results_v2.tables["eval_results"])
Code language: PHP (php)

評估結果視覺化

MLflow UI 提供多種視覺化功能:

1. 評估表格

每次評估會產生一個結果表格,包含:

  • 每筆資料的輸入、輸出
  • 每個 Scorer 的分數和理由
  • 彙總統計

2. 比較視圖

在 MLflow UI 中,你可以:

  • 選擇多個評估 run
  • 並排比較指標
  • 追蹤版本間的改善或退化

3. Trace 視圖

點擊任一評估結果,可以深入查看:

  • 完整的 Trace 執行流程
  • Judge 的評估理由
  • 輸入輸出對照

最佳實踐

1. 選擇正確的 Judge 模型

  • 開發階段:使用強大的模型(GPT-4o、Claude Opus)發現問題模式
  • Production:切換到較小的模型(GPT-4o-mini、Claude Haiku)降低成本

2. 通用 vs 專用指標

研究顯示,通用指標如「Hallucination」或「Toxicity」在實務上效果有限。成功的做法是分析真實資料、發現 domain-specific 的失敗模式,然後從頭定義自訂評估標準。

3. 二元評分優於數值評分

MLflow 建議使用二元(pass/fail)或少量類別的評分,而非 1-5 的數值評分。原因:

  • LLM 產生的判斷更一致
  • 更容易設定閾值
  • 決策更明確

4. 迭代改善流程

  1. 從真實用戶互動中收集 Traces
  2. 讓 domain experts 標註品質問題
  3. 分析常見的失敗模式
  4. 定義針對這些模式的 Scorers
  5. 使用自動對齊功能校準 Scorers

小結

本篇介紹了 MLflow Evaluation 的完整功能:

概念 說明
LLM-as-a-Judge 用 LLM 評估 LLM 輸出,可規模化且一致
Scorer 定義評估標準的元件
內建 Scorer RelevanceToQuery、Correctness、Safety 等
Guidelines 用自然語言定義 pass/fail 條件
make_judge() 建立自訂評估指標
Trace 評估 從 production 擷取真實資料評估

透過這些工具,你可以建立一個完整的品質保證流程:

  • 開發時快速迭代 prompt
  • 上線前驗證品質
  • Production 環境持續監控

系列總結

恭喜你完成了【MLflow GenAI 教學】系列!讓我們回顧整個系列:

篇章 主題 核心能力
#01 快速開始 安裝設定、基本概念
#02 Tracing 追蹤 LLM 執行流程、Debug
#03 Prompt Engineering 版本控制、Prompt Registry
#04 Evaluation 自動化品質評估

這四個功能形成一個完整的 GenAI 開發循環:

設計 Prompt → 追蹤執行 → 評估品質 → 改善 Prompt → ...
    ↑                                    |
    └────────────────────────────────────┘

MLflow GenAI 讓這個循環可以被系統化、可追蹤、可量化。祝你開發順利!


參考資源

進階測驗:MLflow GenAI 教學 – Evaluation

測驗目標:驗證你是否能在實際情境中應用 MLflow Evaluation 功能。
共 5 題,包含情境題與錯誤診斷題。

1. 你正在開發一個客服聊天機器人,需要確保回答不會包含有害內容,且回答要切題。你不需要預先準備標準答案,應該選用哪些 Scorer? 情境題

  • A. CorrectnessEquivalence
  • B. GuidelinesCompleteness
  • C. SafetyRelevanceToQuery
  • D. RetrievalGroundednessRetrievalRelevance

2. 同事寫了以下評估程式碼,但執行後 my_app 沒有被呼叫。問題出在哪裡? 錯誤診斷

eval_dataset = [ {“question”: “MLflow 可以管理 prompt 嗎?”}, {“question”: “什麼是 Tracing?”}, ] def my_app(question: str) -> str: return “這是回答” results = mlflow.genai.evaluate( data=eval_dataset, predict_fn=my_app, scorers=[RelevanceToQuery()], )
  • A. 缺少 import mlflow
  • B. 資料集格式錯誤,應該用 {"inputs": {"question": "..."}} 結構
  • C. my_app 函式應該是 async 函式
  • D. 缺少 mlflow.start_run()

3. 你的 RAG 應用有時會產生幻覺(回答中包含檢索資料沒有的內容)。你想建立自動化檢測機制,應該使用哪個 Scorer? 情境題

  • A. Correctness
  • B. Safety
  • C. RelevanceToQuery
  • D. RetrievalGroundedness

4. 你想建立一個自訂評估指標,用三個等級評估回答的連貫性。下面的 make_judge() 程式碼有什麼問題? 錯誤診斷

from mlflow.genai.judges import make_judge coherence_judge = make_judge( name=”coherence”, instructions=”評估回答是否連貫。”, feedback_value_type=[“coherent”, “somewhat_coherent”, “incoherent”], model=”openai:/gpt-4o-mini”, )
  • A. name 參數不能有底線
  • B. instructions 沒有使用 {{ outputs }} 變數
  • C. feedback_value_type 應該用 Literal["coherent", "somewhat_coherent", "incoherent"]
  • D. model 參數格式錯誤

5. 你想從 Production 環境收集的 Traces 中評估品質,而不想重新執行模型。下面哪種做法正確? 情境題

  • A. 必須提供 predict_fn,無法直接評估 Traces
  • B. 使用 mlflow.search_traces() 取得 Traces 後,直接傳入 mlflow.genai.evaluate(data=traces, scorers=...)
  • C. 需要先將 Traces 轉換成 CSV 格式再評估
  • D. 只有 CLI 模式才能評估 Production Traces

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *