評価スイートを構築し、テストにも合格しました。デプロイすると、評価が検出できなかったリグレッションについて、ユーザーからすぐに苦情が寄せられます。
これは、本番環境でのLLM開発において最もよくある、そして最も意欲をそぐパターンの一つです。見栄えは立派でも、重要なリグレッションを見逃す評価スイートです。それは誤った安心感を与えます。チームは評価を信頼し、品質を損なう変更をリリースし、ユーザーから指摘されて初めて問題に気づきます。
実際にリグレッションを検出できる評価の構築は、見た目以上に困難です。基本要素(データセット、期待される出力、スコアリング)は簡単です。それらを信頼できるシグナルにするところに、本当の作業があります。
この記事では、本番AIの品質を真剣に考えるチームに向けて、実運用に耐える評価の構築から得られた知見を解説します。
優れた評価が果たす役割
優れた評価スイートは、変更候補に対して実行したとき、「この変更は現行バージョンより良いのか、悪いのか、それとも同等なのか」という問いに、高い確信を持って答えられるものです。
その特徴は次のとおりです。
- リグレッションを検出します。 実世界のパターンにおける品質が低下すると、評価スコアも低下します。
- 改善を検出します。 品質が向上すると、都合よく選んだケースに限らず、スコアにその改善が反映されます。
- 実質的な変更がなければ安定します。 重要な変更がない場合、スコアは一貫しています。
- 意思決定の根拠として信頼できます。 評価スコアに基づく判断が、実際のユーザー成果と相関します。
どれも、言葉ほど簡単ではありません。
データセットの問題
評価の品質は、データセットの品質を超えられません。機能しない評価スイートの多くは、ここで失敗しています。
データセットによくある失敗
失敗1:都合のよい簡単なケースだけを選ぶ。 データセットは、システムが正常に動いているとき、多くの場合はそれを構築したエンジニア自身によって作られます。その人は、各挙動の明快な例など、「筋が通っている」ケースを選びます。実際の本番トラフィックはもっと雑然としています。難しいケース、曖昧なケース、エッジケースが失敗の大半を占めるにもかかわらず、データセットでは十分に表現されていません。
失敗2:データセットが古い。 データセットを構築したのは6か月前です。その後、ユーザーの行動は変化し、新たな機能領域が加わり、新しい製品機能がリリースされています。データセットがテストしているのは、過去の世界です。
失敗3:リグレッションが起きやすい領域を網羅していない。 評価は「正常系」を徹底的にカバーしていますが、実際にリグレッションが生じる境界を検証していません。
失敗4:データセットの汚染。 評価で使用する例が、プロンプトやファインチューニングデータにも含まれています。モデルはそれらを「記憶」しています。テストスコアは水増しされ、実際の性能はそれより劣ります。
失敗5:分布が偏っている。 データセットの80%が一種類の入力で、ロングテールは5%しかありません。ロングテールで実際にリグレッションが起きても、スコアはほとんど動きません。
強力なデータセットの構築
強力なデータセットを生み出す原則がいくつかあります。
実際の本番トラフィックから収集します。 最良の例は、個人を特定できる情報(PII)を除去した、実際のユーザー入力です。そこには、システムが対処すべき現実の雑然さが含まれています。
実践的なワークフローは次のとおりです。
- 適切なプライバシー対策を講じて、本番呼び出しのサンプルを取得します。
- 期待される出力を人手でラベル付けします(またはLLMでラベル付けした後、人間が検証します)。
- そのケースを評価データセットに追加します。
- データセットを定期的に更新します(月次が適切な頻度です)。
多様な失敗モードを含めます。 特に、過去に本番環境で失敗したケースを含めます。これらがリグレッションテストになります。バグを修正したら、失敗したケースを追加し、修正された状態を維持します。
データセットを層別化します。 ケースを、難易度(易しい/普通/難しい)、トピック、ユーザー種別、長さなどで分類します。各カテゴリーが十分に網羅されていることを確認します。全体だけでなく、カテゴリーごとのスコアを追跡します。
難易度を混在させます。 壊滅的なリグレッションを検出するための簡単なケース、実際のトラフィックの大半を占める中程度のケース、エッジケースとなる難しいケースを含めます。難しいケースだけのデータセットは、小さな変更でもスコアが大きく変動します。簡単なケースだけでは、実際のリグレッションが起きてもスコアが動きません。
適切な規模にします。 小さすぎると統計的なノイズが大きくなります。大きすぎると、実行に時間と費用がかかります。一般的な規模は次のとおりです。
- 分類:200~500ケース。
- 生成:50~200ケース。
- 複雑なエージェントフロー:20~50ケース。
小さく始めて、後から増やすこともできます。
更新を規律として定着させます。 データセットを毎月レビューする予定を組みます。新しい失敗モードを追加し、古くなったケースを廃止します。望ましい挙動が変わった場合は、期待される出力を更新します。
メトリクスの問題
何を測定するかによって、何を最適化するかが決まります。不適切なメトリクスの選択は、評価で2番目に多い失敗です。
メトリクスによくある失敗
失敗1:単一の数値による要約が問題を隠す。 全体の正解率が90%でも、ある重要なカテゴリーが95%から70%に低下し、ほかのカテゴリーが改善した事実を隠している場合があります。平均値だけを見ると問題はありません。
対策:カテゴリーごとに内訳を出します。必ず実施してください。
失敗2:メトリクスが誤った対象を測定する。 カスタマーサポートの回答に対する「正確性」メトリクスでは、回答が正しくても失礼であることを見逃す可能性があります。そのメトリクスは口調を捉えていません。
対策:多次元でスコアリングします。正確性、口調、長さ、形式を別々に評価します。
失敗3:重大度に反応しない。 些細な誤りでも危険なハルシネーションでも、誤回答として同じように扱われます。
対策:重み付きでスコアリングします。重大なエラーほど重く扱います。一部のエラーは0(安全性違反)、一部は-1(何も出力しないより悪い、壊滅的な失敗)とします。
失敗4:感度が二極化する。 スコアが100%から99%(知覚できない差)に変わるか、100%から50%(壊滅的な差)に変わるかのどちらかです。微妙なリグレッションは現れません。
対策:段階的にスコアリングします。各出力を二値ではなく、連続的な尺度(1~5または0~1)で評価します。
失敗5:異なる集団をまとめて集計する。 全ユーザーの平均では、10%を占めるサブグループの性能が急落しても見えません。
対策:ユーザー階層、クエリ種別、ロケールなど、関連するスライスごとに次元別の内訳を出します。
強力なメトリクスの構築
多次元にします。 各出力に複数のスコアを付けます。正確性、口調、形式、安全性、長さなど、重要なものを測定します。
重みを付けます。 重要度は次元によって異なります。複合メトリクスでは、それぞれに重みを付けます。
重大度をキャリブレーションします。 一つの次元の中でも、軽微なエラーと重大なエラーを区別します。事実として誤った回答は、少しずれた回答より深刻です。
カテゴリーごとのメトリクスを用意します。 関連するスライスごとにスコアの内訳を報告します。難易度別、トピック別、ユーザー種別に分けます。
時系列の傾向を追います。 単一のスコアは役に立ちませんが、傾向は役に立ちます。スコアを時系列でプロットし、ドリフトを検出します。
ユーザーに合わせます。 メトリクスは、ユーザーが実際に重視することと相関すべきです。ユーザーが無礼な応対に不満を述べているなら、無礼さを測定します。長さに不満があるなら、長さを測定します。
ジャッジの問題
LLM-as-judge(LLMが別のLLMの出力を採点する手法)を使用する場合、そのジャッジが採点者です。ジャッジに偏りや誤りがあれば、評価は役に立ちません。
ジャッジによくある失敗
失敗1:長さへの偏り。 LLMジャッジは長い回答を好む傾向があります。冗長であっても、長い回答に高いスコアを付けます。
失敗2:形式への偏り。 タスクにとってどちらが適切かにかかわらず、ジャッジは文章よりも構造化された出力(箇条書き、見出し)を好みます。
失敗3:自己選好。 ジャッジモデルが評価対象のモデルと同じファミリーの場合、自分のファミリーの出力に高いスコアを付けます。
失敗4:迎合。 ジャッジは、与えられたフレーミングに同意します。「以前のバージョンは悪かったので、新しいバージョンを採点せよ」と指示すると、新しいバージョンのスコアが水増しされます。
失敗5:根拠の欠如。 ジャッジが具体的な基準ではなく印象で採点します。同じプロンプトでも、実行するたびに異なるスコアが出ます。
強力なジャッジの構築
人間を基準にキャリブレーションします。 ジャッジのスコアからサンプルを取り、人間が採点し直します。一致しない箇所では、ジャッジのプロンプトを改善するか、その次元には人間が必要であると認めます。
異なるジャッジモデルを使用します。 可能であれば、評価対象のシステムとは異なるモデルファミリーのジャッジを使用します。自己選好を抑えられます。
基準を明示します。 ジャッジのプロンプトでは、良い状態と悪い状態を例とともに正確に定義します。曖昧な基準からは、曖昧なスコアしか得られません。
誘導的なフレーミングを避けます。 「大半の出力が良いとされる尺度で採点せよ」とジャッジに指示してはいけません。具体的な挙動を基準にします。
基準点のあるルーブリックを使います。 各レベルの例を定義したルーブリックで採点します。「スコア5:事実が正確で、具体的かつ十分に構造化されている。スコア4:ほぼ正確だが、一つの詳細が不足している場合がある。スコア3:……」のようにします。基準点があればジャッジは一貫します。なければドリフトします。
構造化出力を強制します。 ジャッジには自由形式の文章ではなく、次元ごとのスコアと理由を含む構造化された結果を出力させます。集計と監査が容易になります。
強力なジャッジプロンプトは次のようになります。
あなたはAIアシスタントの回答を評価しています。
ユーザーのクエリ:{query}
アシスタントの回答:{response}
以下の各次元を1~5の尺度で採点してください。
1. 事実の正確性:すべての主張は正しいですか?(5 = すべて正しい、4 = 軽微な問題はあるがほぼ正しい、3 = 一部が誤っている、2 = 多くが誤っている、1 = ほぼすべて誤っている)
2. 関連性:回答はユーザーの実際の質問に答えていますか?(5 = 完全に答えている、1 = 答えていない)
3. 完全性:回答には十分な情報が含まれていますか?(5 = 完全、1 = 著しく不完全)
4. 口調:回答は適切かつプロフェッショナルですか?(5 = 完璧な口調、1 = 不適切)
各スコアについて、以下を提示してください。
- スコア
- 具体的な理由を1文で
- スコアの根拠となる回答内の具体的な文言
JSONを出力してください:{"accuracy": {"score": N, "reason": "...", "evidence": "..."}, ...}
このジャッジを、人間が採点した例からなるキャリブレーションセットに対して実行します。ジャッジが許容範囲内で人間と一致するまで調整します。
本番環境向け評価スイートの設計
本番環境で有効なパターンをいくつか紹介します。
スイート1:リグレッションスイート
デプロイ前にシステムが必ず合格しなければならない、定義済みのテストケース群(200~500ケース)です。実際の失敗、エッジケース、既知の良好なパターンから選定します。頻繁には変更しません。
これは「壊してはならない」スイートです。CIと統合し、すべてのPRで実行します。リグレッションがあればマージをブロックします。
スイート2:スモークテスト
頻繁に実行する小規模なサブセット(10~30ケース)です。開発中に迅速なフィードバックを得られます。壊滅的なリグレッションを即座に検出します。
統合方法:pre-commitフック、またはメインの評価前に実行する簡易スモークテスト。
スイート3:探索スイート
実際の本番トラフィックからサンプリングした、より大規模で多様なデータセット(数千ケース)です。実行頻度は低め(毎週など)にします。小規模なスイートでは見逃す可能性があるパターンを探します。
統合方法:スケジュール済みジョブ。週次の品質会議で結果をレビューします。
スイート4:オンラインスイート
実際の本番トラフィックからサンプルを取り、自動(LLMジャッジ)またはユーザーシグナルで採点します。オフライン評価が見逃すドリフトを検出します。
統合方法:継続的に実行し、ダッシュボードで確認します。
スイート5:ユーザーフロースイート
単一のLLM呼び出しだけでなく、ユーザーフロー全体を実行するエンドツーエンドテストです。エージェントシステムや複数ステップのワークフローに使用します。
統合方法:大きな変更をデプロイする前に実行します。
成熟した本番システムは、この5種類をすべて備えています。まずリグレッションスイートから始め、余力が増えるにつれてほかを追加します。
コストと時間の規律
評価には、費用(LLM呼び出し)と時間(実行とレビュー)がかかります。
フラッグシップモデルをジャッジに使う500ケースの評価は、1回の実行で€5~20かかる場合があります。すべてのPR(1日10件)で実行すると、1日€50~200です。管理可能ではありますが、無視できない金額です。
戦略は次のとおりです。
PRではスモークテストを実行し、マージ時に完全なスイートを実行します。 マージされないPRにかかる費用を削減できます。
結果をキャッシュします。 プロンプトもモデルも変わっていないなら、再実行は不要です。(prompt_version, model, dataset_version) をキーとしてキャッシュします。
可能な場合は、安価なジャッジを使います。 適切にキャリブレーションされた安価なジャッジモデルで十分なことも少なくありません。
並列化します。 評価の実行は極めて並列化しやすい処理です。並行処理を利用します。
全件実行ではなくサンプリングします。 日常的なチェックでは、500ケースのデータセットから50ケースをサンプリングします。重要な変更では全件実行します。
時間については、通常「PRをどれだけ待たせられるか」が制約になります。完全な評価を15分未満で終えることを目指します。それ以上かかると、開発者は別の作業に切り替え、生産性が低下します。
運用パターン
成熟した評価プログラムを特徴づける実践方法をいくつか紹介します。
パターン1:評価をゲートとするデプロイ
LLMに影響する変更の本番デプロイは、評価の結果をゲートとします。スコアがしきい値を下回るまで低下した場合は、デプロイをブロックし、エンジニアが調査します。
しきい値は通常、相対値で設定します。たとえば「スコアとベースラインとの差が2%以内でなければならない」とします。ノイズを許容しながら、重大なリグレッションを検出できます。
パターン2:スコア変動時の調査
意味のあるスコアの変動は、上昇でも低下でもすべて調査します。スコアが上がったのはなぜでしょうか。実際に改善したのでしょうか。それともテストが簡単になったのでしょうか。スコアが下がった場合、正確にはどこでしょうか。リグレッションは一つのスライスに限定されているでしょうか。
集計値の変動だけを見て喜んだり慌てたりせず、調査してください。
パターン3:継続的なデータセットのキュレーション
データセットは一度作って終わりではありません。継続的にキュレーションします。そのプロセスは次のとおりです。
- ユーザーが回答について苦情を述べる → リグレッションテストとしてデータセットに追加します。
- 新機能をリリースする → その機能をカバーするケースを追加します。
- モデルの挙動が誰かの予想に反する → 実際の失敗であれば追加します。
- 古くなったケース(もはや関連性がない)→ 廃止します。
月次レビュー会議が効果的です。データセットを生きた資産として扱います。
パターン4:差分に基づくレビュー
評価の結果をレビューするときは、ベースラインとの差分に注目します。
- 新しいバージョンがベースラインより高いスコアを得たケース(改善)。
- 新しいバージョンが低いスコアを得たケース(リグレッション)。
- スコアが同じままだったケース(シグナルなし)。
差分こそがシグナルです。500ケースを順番にレビューするのは非現実的ですが、30件の差分なら対応できます。
パターン5:ジャッジの不一致を人間がレビューする
定期的に(毎週など)、ジャッジが低いスコアを付けたケースと高いスコアを付けたケースをサンプリングします。人による確認では、ジャッジに同意できるかを確認します。
不一致から明らかになることは次のとおりです。
- ジャッジの偏り(ジャッジプロンプトをキャリブレーションします)。
- 実際の品質問題(システムを修正します)。
- データセットの問題(そのケースで期待される出力が誤っています)。
このようにして、ジャッジの品質を長期にわたって維持します。
パターン6:四半期ごとの評価レビュー
評価プログラム自体について、四半期ごとに振り返ります。
- 今四半期、評価スイートはどの実際のリグレッションを検出しましたか。
- どの実際のリグレッションを見逃しましたか。
- どのような誤警報を出しましたか。
- 網羅性について、どのような不足が判明していますか。
- 現在の本番環境の挙動を、データセットはどの程度網羅していますか。
これはメタ評価、つまり評価そのものの評価です。これを行わなければ、評価プログラムは劣化します。
実例:カスタマーサポートの評価
具体的にするため、AIカスタマーサポート回答システム向けの本番品質の評価構成を紹介します。
目標: 顧客の問い合わせに対するAIの回答が正確で、役に立ち、ブランドに沿い、安全であることを保証します。
データセット:
-
リグレッションスイート(300ケース):
- 簡単なケース50件(明確な方針、単純な回答)。
- 中程度のケース100件(典型的な複雑さ)。
- 難しいケース100件(曖昧、慎重な扱いを要する、複数の論点)。
- 既知の失敗ケース50件(過去にリグレッションが起きたシナリオ)。
-
探索スイート(1000ケース): 実際の本番トラフィックから毎月サンプリングし、PIIを除去します。
-
敵対的スイート(50ケース): 情報の抽出、対象外ケースでの返金獲得、AIの操作を試みるよう特別に作成したプロンプトです。
メトリクス:
各ケースについて、ジャッジが次の項目を採点します。
- 事実の正確性(1~5)
- 方針への準拠(1~5)
- 口調の適切さ(1~5)
- 完全性(1~5)
- 長さの適切さ(1~5)
- 安全性(二値:合格/不合格)
ジャッジ:
- 主ジャッジ:Claude(テスト対象システムはGPTを使用しているため、異なるプロバイダーを選択します。異なるプロバイダーを選ぶことで、同一モデルによる自己選好の偏りを避けられます)。
- 100件の参照ケースについて、人間のレビュアーを基準にキャリブレーションします。
- 四半期ごとに再キャリブレーションします。
集計:
- スライス(チケット種別、顧客階層、言語)ごとに、各次元の平均スコアを算出します。
- 安全性の合格率(100%必須)。
- ケースごとの重み付きスコア(差分に使用)。
運用:
- すべてのPRでスモークテスト(30ケース)。
- PRのマージ時に完全なリグレッションスイート(300ケース)。
- 毎週、探索スイート(1000ケース)。
- プロンプトまたはモデルを変更する前に敵対的スイート(50ケース)。
- 本番トラフィックの1%をオンラインでサンプリングし、リアルタイムで判定。
レビュー:
- 月次会議:評価の傾向、新しい失敗モード、データセットの更新をレビューします。
- 四半期会議:メタ評価、ジャッジのキャリブレーション、データセットの監査を行います。
成果(類似システムの実際の導入事例から):
- 評価がなければリリースされていたはずのリグレッションを、月に約3件検出。
- 月に約1件の誤警報(評価が、実際には問題のない変更をリグレッションと判定)。
- ドリフトを数週間から数か月ではなく、数日以内に検出。
- プロンプトやモデルの変更をリリースする際の確信が向上。
これが本番品質の評価です。週末だけで完成する手軽なプロジェクトではなく、実際の投資対効果をもたらす継続的な取り組みです。
よくある落とし穴
繰り返し見られるパターンをいくつか紹介します。
落とし穴1:製品のリリース後に評価を構築する。 「評価は後で追加する」と考えても、その「後」は訪れません。初日から構築してください。
落とし穴2:一人のエンジニアだけが担当する。 一人が評価を構築し、ほかの誰も保守しません。その人が去ると、評価は朽ちていきます。担当を分散してください。
落とし穴3:評価を静的なものとして扱う。 一度構築した後は更新しません。製品の進化に伴い、役に立たなくなります。評価を生きた資産として扱ってください。
落とし穴4:評価スコアを盲信する。 評価が改善を示したからリリースする、という判断です。人による抜き取り確認がなければ、評価では高スコアでもユーザーには嫌われるものをリリースしてしまいます。重要な変更では、評価と人による確認を組み合わせてください。
落とし穴5:評価に最適化する。 評価で高いスコアを得るためだけにプロンプトを調整します。評価は改善しても、現実は改善しません。この点に注意してください。評価の改善が本番環境での改善を伴わないなら、テスト自体に最適化しています。
落とし穴6:インフラコストを無視する。 大規模な評価は高額です(LLM呼び出しの費用が積み上がります)。コストを追跡しなければ、月末になって初めて気づきます。
落とし穴7:合否基準が明確でない。 「スコアが4.2から4.0に下がった。これはリグレッションなのか」という状態です。しきい値を事前に定義し、それを守ってください。
落とし穴8:評価スイートがテストの労力を独占する。 基本的な正確性テストが不足しているのに、精巧な評価を構築する状態です。評価は品質のドリフトを検出するためのものです。すべてのテストが評価ではありません。
文化的な側面
本番評価で最も難しいのは、文化的な側面です。エンジニアとプロダクト担当者には、次の姿勢が必要です。
- デプロイのゲートにできるほど評価を信頼する。 そうしなければ、評価は見せかけにすぎません。
- 変動を調査する必要があるほど評価を疑う。 盲信すれば、テスト自体への最適化につながります。
- 継続的な業務としてデータセットのキュレーションに投資する。 一度限りのプロジェクトではありません。
- 評価は人間の判断に取って代わらないと理解する。 人間がレビューすべき範囲を減らすものです。
- 評価スイートが機能していないときに、それを認識する。 実際のリグレッションを見逃した場合、問題は苦情を述べたユーザーではなく、評価スイートにあります。
この文化を持つチームは、より速く、より確実にリリースできます。そうでないチームは、いずれ壊れた評価に過度に依存するか、評価がないために身動きが取れなくなります。
まとめ
実際にリグレッションを検出できる評価の構築は、見た目以上に困難ですが、実現可能です。
鍵となるのは次の点です。
- 本番環境の現実から収集した、実際の多様なデータセット。
- ユーザー体験に沿った、多次元かつスライスを考慮したメトリクス。
- 人間の判断と実際に照合した、キャリブレーション済みのジャッジ。
- 異なる目的に対応する複数の評価スイート(リグレッション、スモーク、探索、オンライン、エンドツーエンド)。
- 運用上の規律:評価をゲートとするデプロイ、継続的なデータセットのキュレーション、変動の調査。
- 評価を長期にわたって使用し、改善するための文化的なコミットメント。
適切に構築すれば、評価はAIスタックで最も価値のあるインフラになります。品質を維持しながら迅速にリリースするための仕組みです。評価がなければ、目隠しをしたまま飛ぶようなものです。
評価を構築し、信頼し、改善してください。それが本番AIの品質を維持する方法です。



