validate-evaluator について
validate-evaluatorは、LLM judgeを人間の判定に照らして調整するSkillです。データ分割、TPR・TNRによる反復評価、本番データの合格率補正と信頼区間の算出を案内します。
主な機能
- 01訓練・開発・テストデータの分割
- 02TPRとTNRの測定
- 03不一致に基づくjudgeプロンプトの改善
- 04合格率の補正と信頼区間の推定
活用シーン
- 01二値判定のLLM judgeを人間のラベルで検証
- 02開発データの結果に基づく評価プロンプトの調整
- 03本番トレースの真の合格率の推定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ ai-evals-course/ evals-skills --skill validate-evaluatorインストール後、Claude Code で/validate-evaluatorを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yaml
詳細
評価器の検証
LLM ジャッジを人間の判断に照らして調整します。
概要
- 人間がラベル付けしたデータを、トレーニング(10~20%)、開発(40~45%)、テスト(40~45%)に分割します
- 開発セットでジャッジを実行し、TPR/TNR を測定します
- 開発セットで TPR と TNR が 90%を超えるまで、ジャッジを反復調整します
- 最終的な TPR/TNR を測定するため、保留していたテストセットで一度だけ実行します
- 本番データにバイアス補正式を適用します
前提条件
- 構築済みの LLM ジャッジプロンプト(write-judge-prompt で作成)
- 人間がラベル付けしたデータ:失敗モードごとに Pass/Fail の二値ラベルを付けたトレースが約 100 件
- Pass 約 50 件、Fail 約 50 件を目指します(実際の分布に偏りがあっても、バランスを取ります)
- ラベルは外部委託のアノテーターではなく、ドメインの専門家が付ける必要があります
- ラベル付けしたデータから選んだ、候補となる少数ショットの例
主な手順
ステップ 1:データを分割する
人間がラベル付けしたデータを、互いに重複しない 3 つのセットに分割します。
| 分割 | サイズ | 目的 | ルール |
|---|---|---|---|
| トレーニング | 10~20%(約 10~20 件) | ジャッジプロンプト用の少数ショット例のソース | 明確な Pass と Fail のケースのみを使用します。プロンプトに直接含めます。 |
| 開発 | 40~45%(約 40~45 件) | 評価器を反復的に改善する | プロンプトには決して含めません。繰り返し評価に使用します。 |
| テスト | 40~45%(約 40~45 件) | 最終的な偏りのない精度測定 | 開発中は見ないでください。最後に一度だけ使用します。 |
目標:開発セットとテストセットの合計で、各クラス(Pass と Fail)を 30~50 件確保します。実際の発生率に偏りがあっても、バランスの取れた分割を使用してください。TNR を確実に測定するには、十分な数の Fail 例が必要です。
from sklearn.model_selection import train_test_split
# First split: separate test set
train_dev, test = train_test_split(
labeled_data, test_size=0.4, stratify=labeled_data['label'], random_state=42
)
# Second split: separate training examples from dev set
train, dev = train_test_split(
train_dev, test_size=0.75, stratify=train_dev['label'], random_state=42
)
# Result: ~15% train, ~45% dev, ~40% test
ステップ 2:開発セットで評価器を実行する
開発セットのすべての例に対してジャッジを実行します。予測結果を人間のラベルと比較します。
ステップ 3:TPR と TNR を測定する
TPR(真陽性率): 人間が Pass と判定したとき、ジャッジも Pass と判定する割合です。
TPR = (judge says Pass AND human says Pass) / (human says Pass)
TNR(真陰性率): 人間が Fail と判定したとき、ジャッジも Fail と判定する割合です。
TNR = (judge says Fail AND human says Fail) / (human says Fail)
from sklearn.metrics import confusion_matrix
tn, fp, fn, tp = confusion_matrix(human_labels, evaluator_labels,
labels=['Fail', 'Pass']).ravel()
tpr = tp / (tp + fn)
tnr = tn / (tn + fp)
Precision/Recall や単純な正解率ではなく、TPR/TNR を使用してください。この 2 つの指標は、バイアス補正式に直接対応しています。Cohen の Kappa は、2 人の人間のアノテーター間の一致度を測定する場合にのみ使用し、ジャッジと正解ラベルの比較には使用しないでください。
ステップ 4:不一致を調べる
ジャッジの判定が人間のラベルと異なるケースをすべて確認します。
| 不一致の種類 | ジャッジ | 人間 | 修正方法 |
|---|---|---|---|
| 誤った Pass 判定 | Pass | Fail | ジャッジの判定が甘すぎます。Fail の定義を強化するか、エッジケースの例を追加します。 |
| 誤った Fail 判定 | Fail | Pass | ジャッジの判定が厳しすぎます。Pass の定義を明確にするか、例を調整します。 |
不一致ごとに、次の対応が必要か判断します。
- ジャッジプロンプトの表現を明確にする
- トレーニングセットの少数ショット例を入れ替える、または追加する
- エッジケースに対する明示的なルールを追加する
- 基準を、より具体的なサブチェックに分割する
ステップ 5:反復する
ジャッジプロンプトを改善し、開発セットで再実行します。TPR と TNR が安定するまで繰り返します。
停止基準:
- 目標: TPR > 90%、かつ TNR > 90%
- 最低許容値: TPR > 80%、かつ TNR > 80%
調整が行き詰まった場合:
| 問題 | 解決策 |
|---|---|
| TPR と TNR の両方が低い | より高性能な LLM をジャッジに使用します |
| 一方の指標が低く、もう一方は許容範囲内 | 低い指標に関連する不一致を重点的に調べます |
| 両方の指標が目標未満で頭打ちになる | 基準をより小さく、より基本的なチェックに分解します |
| 特定の入力タイプで一貫して誤判定する | トレーニングセットから対象を絞った少数ショット例を追加します |
| ラベル自体に一貫性がないように見える | 人間のラベルを再確認します。評価基準の改善が必要な場合があります |
ステップ 6:テストセットで最終測定する
保留していたテストセットに対して、ジャッジをちょうど一度だけ実行します。最終的な TPR と TNR を記録します。
テストセットの結果を見た後は反復調整しないでください。必要に応じて、新しい開発データを用意してステップ 4 に戻ります。
ステップ 7(任意):真の成功率を推定する(Rogan-Gladen 補正)
ラベル付けされていない本番データに対する生の判定スコアには偏りがあります。正確な集計合格率が必要な場合は、既知の判定誤りを補正してください。
theta_hat = (p_obs + TNR - 1) / (TPR + TNR - 1)
ここで:
p_obs= 判定者が Pass とスコア付けした、ラベルなしトレースの割合TPR、TNR= テストセットで測定した値theta_hat= 真の成功率の補正済み推定値
[0, 1] の範囲に収めてください。TPR + TNR - 1 が 0 に近い場合は無効です(判定者の性能がランダムと同程度です)。
例:
- 判定者の TPR = 0.92、TNR = 0.88
- 本番トレース 500 件:400 件が Pass とスコア付けされた場合、p_obs = 0.80
- theta_hat = (0.80 + 0.88 - 1) / (0.92 + 0.88 - 1) = 0.68 / 0.80 = 0.85
- 真の成功率は約 85% であり、生の値である 80% ではありません
ステップ 8:信頼区間
ブートストラップ信頼区間を計算します。点推定だけでは不十分です。
import numpy as np
def bootstrap_ci(human_labels, eval_labels, p_obs, n_bootstrap=2000):
"""Bootstrap 95% CI for corrected success rate."""
n = len(human_labels)
estimates = []
for _ in range(n_bootstrap):
idx = np.random.choice(n, size=n, replace=True)
h = np.array(human_labels)[idx]
e = np.array(eval_labels)[idx]
tp = ((h == 'Pass') & (e == 'Pass')).sum()
fn = ((h == 'Pass') & (e == 'Fail')).sum()
tn = ((h == 'Fail') & (e == 'Fail')).sum()
fp = ((h == 'Fail') & (e == 'Pass')).sum()
tpr_b = tp / (tp + fn) if (tp + fn) > 0 else 0
tnr_b = tn / (tn + fp) if (tn + fp) > 0 else 0
denom = tpr_b + tnr_b - 1
if abs(denom) < 1e-6:
continue
theta = (p_obs + tnr_b - 1) / denom
estimates.append(np.clip(theta, 0, 1))
return np.percentile(estimates, 2.5), np.percentile(estimates, 97.5)
lower, upper = bootstrap_ci(test_human, test_eval, p_obs=0.80)
print(f"95% CI: [{lower:.2f}, {upper:.2f}]")
または judgy(pip install judgy)を使用します。
from judgy import estimate_success_rate
# judgy expects 0/1 integer labels (1 = Pass, 0 = Fail)
test_labels = [1 if l == 'Pass' else 0 for l in test_human_labels]
test_preds = [1 if l == 'Pass' else 0 for l in test_eval_labels]
unlabeled_preds = [1 if l == 'Pass' else 0 for l in prod_eval_labels]
theta_hat, lower, upper = estimate_success_rate(
test_labels, test_preds, unlabeled_preds
)
print(f"Corrected rate: {theta_hat:.2f}")
print(f"95% CI: [{lower:.2f}, {upper:.2f}]")
実践ガイダンス
- LLM 判定者では、モデルの正確なバージョンを固定してください(
<model>-<YYYY-MM-DD>のような日付付きスナップショット ID を使用し、変動するエイリアスは使いません)。プロバイダーは予告なくモデルを更新するため、気付かないうちに挙動が変わることがあります。 - 判定プロンプトを変更した場合、モデルを切り替えた場合、または本番の信頼区間が予想外に広がった場合は、再検証してください。
- ラベル付きの例を約 100 件使用します(Pass 50 件、Fail 50 件)。60 件未満では信頼区間が広くなります。
- ラベル付けには、信頼できるドメインエキスパート 1 名に依頼するのが最も効率的です。それが難しい場合は、2 名のアノテーターにトレース 20~50 件を個別にラベル付けしてもらい、先に不一致を解決してください。
- TPR の改善は、TNR の改善よりも信頼区間を狭めます。 補正では
(TPR + TNR - 1)で割るため、TPR が低いと分母が小さくなり、推定誤差が増幅されて信頼区間が広くなります。
アンチパターン
- 検証せずに判定者が「問題なく機能する」と思い込むこと。 判定者は失敗を一貫して見逃したり、合格したトレースを誤って不合格と判定したりする可能性があります。
- 生の正解率や一致率を使うこと。 TPR と TNR を使用してください。クラスに偏りがある場合、生の正解率は誤解を招きます。
- 開発用/テスト用の例を few-shot 例として使うこと。 これはデータリークです。
- 開発セットの性能を最終的な正解率として報告すること。 開発セットの数値は楽観的です。偏りのない推定値が得られるのはテストセットです。
- 偏り補正なしで判定者の生のスコアを使うこと。 集計合格率を報告する場合は、Rogan-Gladen の式を適用してください(ステップ 7)。
- 信頼区間を示さずに点推定だけを示すこと。 補正後の合格率が 85% でも、テストセットが小さければ 78~92% になる可能性があります。関係者が数値をどの程度信頼できるか把握できるよう、範囲を報告してください。