第5章 評価とモニタリング / 想定学習時間:30〜40分 / 最終確認:2026年8月

5-3. カスタムスコアラーの実装

🎯 この節の学習目標

1. なぜカスタムスコアラーが必要か

5-2で見た組み込みジャッジ(relevance、groundedness など)は汎用的な観点をカバーしますが、実際のアプリにはドメイン固有の品質基準があります。

こうした基準は組み込みジャッジには存在しないため、カスタムスコアラーとして自分で定義します。MLflow 3 の統合評価フレームワークでは、スコアラーを普通の Python 関数として書き、組み込みジャッジと同じ仕組みで mlflow.genai.evaluate() に渡せます。開発時の一括評価にも、本番トレースに対するオンライン評価(5-5)にも、同じスコアラーをそのまま使えるのが MLflow 3 の設計です。

2. @scorer デコレータによる実装

カスタムスコアラーは、MLflow 3 の @scorer デコレータ(mlflow.genai.scorers)を付けた Python 関数として実装します。関数は評価ケースごとに呼ばれ、次の引数を(必要なものだけ)受け取れます。

引数内容
inputsアプリへの入力(質問など)
outputsアプリの出力(回答)
expectations期待値(期待回答、正解ラベルなど。評価データセットで与える)
trace実行トレース(中間ステップも見たい場合。5-6参照)

戻り値は数値・bool・Feedback オブジェクトのいずれかです。Feedback を使うと、スコアに加えて判定理由(rationale)を残せます。

💼 例:「回答に出典URLが含まれているか」を bool で返すスコアラー

from mlflow.genai.scorers import scorer

@scorer
def has_source_url(outputs) -> bool:
    """回答に出典URL(http/https)が含まれているかを判定する"""
    return "http://" in outputs or "https://" in outputs

理由付きで返したい場合は Feedback を使います。

from mlflow.entities import Feedback
from mlflow.genai.scorers import scorer

@scorer
def answer_length_check(outputs) -> Feedback:
    n = len(outputs)
    return Feedback(
        value=n <= 500,
        rationale=f"回答は{n}文字(上限500文字)",
    )

定義したスコアラーは組み込みジャッジと並べて渡すだけで使えます。

results = mlflow.genai.evaluate(
    data=eval_data,
    predict_fn=my_rag_app,
    scorers=[Correctness(), has_source_url, answer_length_check],
)

3. 2系統のカスタムスコアラー:ヒューリスティック型とLLM判定型

カスタムスコアラーの中身は、大きく2系統に分かれます。

ヒューリスティック型(コードで判定)

正規表現・完全一致・長さチェック・JSONパースなど、決定的なコードで判定します。

LLM判定型(カスタムプロンプトのジャッジ)

組み込みジャッジにない意味的な基準を、独自のプロンプトを与えたLLMジャッジとして実装します。MLflow 3 には2つの経路があります。基準を自然言語の文章で表現できるなら Guidelines スコアラーに基準文(guidelines)を渡すのが最も手軽です(5-2)。合否の2択に収まらない多段階の判定など、より細かく制御したい場合は、カスタムプロンプトからジャッジを作る仕組み(custom prompt judge)で独自ジャッジを定義し、スコアラー関数の中から呼び出して使えます。

📝 試験のポイント

使い分けの判断軸は「機械的に判定できるか」です。形式・パターンで判定できるならヒューリスティック型(安価・再現可能)、意味の理解が必要ならLLM判定型。「出典URLが含まれるかを評価したい」という問題に対して、LLMジャッジを使う選択肢は過剰であり、単純な文字列チェックのカスタムスコアラーが正解になります。

4. 評価の再現性:スコアラーとデータセットのバージョン管理

評価は「一度きりの測定」ではなく、変更のたびに繰り返す回帰テストとして運用します。そのとき比較を意味のあるものにするには、再現性が不可欠です。

「先週より品質が上がった」と主張するには、同じ物差し(スコアラー)と同じ試験問題(データセット)で測っている必要がある、と覚えてください。

✅ この節のまとめ

練習問題

問1. 社内規程QAボットの業務要件として「すべての回答に出典URLを含めること」がある。この要件への準拠を評価する方法として最もコスト効率が良いのはどれか。

  1. groundedness ジャッジを使う
  2. URLの有無を文字列チェックで判定するヒューリスティック型カスタムスコアラーを実装する
  3. 大型LLMに「URLが含まれるか」を判定させるカスタムジャッジを実装する
  4. 人間のレビュアーが全件を目視確認する
解答と解説を見る

正解:B

「URLが含まれるか」は機械的に判定できる形式チェックであり、文字列判定のヒューリスティック型スコアラーが最も安価・高速・再現可能です。Aの groundedness は回答内容がコンテキストに裏付けられているかを見る観点でURLの有無は判定しません。CはLLM推論コストがかかる上、決定的に判定できるものをわざわざ確率的に判定する過剰な設計です。Dはスケールしません。

問2. MLflow 3 の統合評価フレームワークでカスタムスコアラーを実装する方法として正しいのはどれか。

  1. @scorer デコレータを付けた Python 関数として実装し、数値・bool・Feedback のいずれかを返す
  2. 評価基準を YAML ファイルに記述し、Model Serving エンドポイントに直接アップロードする
  3. スコアラーは組み込みのもののみ使用可能で、カスタム実装はできない
  4. Delta テーブルに SQL の CHECK 制約として評価基準を定義する
解答と解説を見る

正解:A

カスタムスコアラーは @scorer デコレータ付きの Python 関数で、inputs / outputs / expectations などを受け取り、数値・bool・Feedback を返します。Bのような YAML アップロード方式やDの CHECK 制約は評価の仕組みではありません。Cは誤りで、カスタム実装こそがこの機能の目的です。

問3. 「回答が社内の正式な製品名称を使っているか(略称や旧名称は不可。文脈により表記ゆれの許容判断が必要)」を評価したい。最も適切な実装はどれか。

  1. 回答の文字数を数えるヒューリスティックスコアラー
  2. 正式名称の完全一致のみを見る正規表現(文脈は考慮しない)
  3. 判定基準をプロンプトに記述した LLM 判定型カスタムスコアラー(custom prompt judge)
  4. ROUGE スコア
解答と解説を見る

正解:C

「文脈により許容判断が必要」という要件は意味理解を伴うため、LLM判定型が適切です。Aは要件と無関係、Bは完全一致だけでは文脈依存の判断(引用文中の旧名称は許容する等)ができません。Dは参照テキストとの n-gram 一致を測る指標で、名称の正しさの判定には使えません。単純な有無チェックならBのようなヒューリスティックで十分ですが、本問は文脈判断が要件に含まれる点がポイントです。

問4. プロンプト改修の前後で評価スコアを比較し、改善効果を判断したい。比較を有効にするための前提として最も適切なのはどれか。

  1. 改修後の評価では、より難しい質問に入れ替えた新しいデータセットを使う
  2. 評価データセットとスコアラーを同一バージョンに固定し、同じ条件で前後を評価する
  3. スコアが上がるまでスコアラーの判定基準を調整する
  4. 評価は初回のみ実施し、以後は実施しない
解答と解説を見る

正解:B

前後比較は「同じ物差し・同じ試験問題」で測って初めて意味を持ちます。そのため評価データセットとスコアラーの両方をバージョン管理し、同一バージョンで比較します。Aはデータセットが変わるとスコア変動の原因が改修なのか問題の難易度なのか区別できません。Cは評価の目的を破壊する行為です。Dでは改修の効果検証(回帰テスト)ができません。