LLMの評価(Evals)とは?モデル選定を実測で行う方法
「新しいモデルが出たので乗り換えたい。でも本当に良くなるのか?」——LLMを組み込んだプロダクトを運用していると、必ずここで止まります。ベンチマークのスコアは上がっている。手元で何回か試した感触も悪くない。それでも本番を差し替える判断はできない。
この状態を抜けるための仕組みが LLMの評価(eval / Evals) です。この記事では、evalで何を測るのか、モデル候補をどう比較するのか、そして見落とされがちな「eval自体をどう検証するか」を実測例つきで解説します。
LLMの評価(Evals)とは
evalとは、自分のプロダクトのタスクに対して、モデルの出力を繰り返し・自動で採点する仕組みです。単体テストとの最大の違いは、正解が1つに決まらないこと。そのため「正解と一致するか」ではなく、完了したか・どれだけ効率よく完了したか・出力の質・1回あたりのコスト、という測り方をします。
重要なのは、evalが測るのがあなたのプロダクトのタスクだという点です。汎用ベンチマークとの決定的な差はここにあります。
公開ベンチマークでは「自社で良くなるか」は分からない
公開ベンチマークはモデルの一般的な能力を比べるには有用ですが、乗り換え判断の根拠にはなりません。理由は3つあります。
- タスクが違う。 ベンチマークが測るのは数学やコーディングの正答率です。あなたが知りたいのは「問い合わせ要約が使い物になるか」かもしれません。
- プロンプトが違う。 ベンチマークはモデル単体を測ります。実際の品質は、システムプロンプトやコンテキストの組み立て方と不可分です。
- コストと速度が入っていない。 品質が5%上がってもコストが3倍なら採用できません。逆に品質が同等でコストが半分なら即採用です。
ベンチマークで上位のモデルが、自社のプロダクトで上位とは限りません。
evalで測る4つの指標
| 指標 | 何が分かるか |
|---|---|
| タスク完了率 | そもそも仕事を終えられるか |
| 完了までのターン数・呼び出し数 | 効率。待ち時間とコストに直結 |
| 品質スコア(LLM判定) | 出力が読めるものか、自然か |
| 1回あたりのコスト | 採用可能かどうかの最終判断 |
品質スコアには LLM-as-a-judge(別のモデルに採点させる方式)がよく使われます。人手の採点は正確ですが変更のたびには回せません。判定モデルを固定しておけば、変更の前後で同じものさしを使えます。
実測例:無料アプリでのモデル移行
具体例として、ConvoLive というAI会話練習アプリの実測値を挙げます。
ConvoLive
AIキャラクターと外国語で声に出して会話しながら、画面上のチェックリストを埋めていく学習アプリです。iOS / Android / ブラウザで動作し、8言語に対応しています。
動画の上部に出ているチェックリストが、毎ターン「達成できたか」を判定される対象です。この判定の正しさが、後半で出てくる「評価そのものを検証する」という話に直結します。
そしてこのアプリは完全無料で提供されています。有料プランはありません。つまり、会話ごとに発生するAIコストはそのまま運営側の負担になります。
ConvoLive で英語を練習する無料であることが、この事例の性格を決めています。品質だけを見てモデルを選ぶという選択肢が最初から無く、コストが同じ表に載っていなければ判断できない。 evalの必要性が最もはっきり出るタイプのケースです。
前提:1タスクが1回のAPI呼び出しとは限らない
コストを見積もる前に確認すべきことがあります。このアプリでは、学習者3ターンの会話1つに対して、次の呼び出しが発生していました。
| 呼び出しの種類 | 回数 |
|---|---|
| 会話の書き出し | 1 |
| キャラクターの返答 | 3 |
| チェックリストの達成判定 | 3 |
| 提案文の生成 | 3 |
| 訳の生成 | 2 |
| 締めのひとこと | 1 |
| 合計 | 13 |
ユーザーから見えるやりとりは3往復ですが、裏では13回のLLM呼び出しが走っています。自分のプロダクトが1タスクあたり何回モデルを呼んでいるかを把握していないと、コストの見積もりは成立しません。 evalを組む前に一度数えてください。
比較の結果
gpt-4o-mini から gpt-5.6-luna への移行を検討し、12シナリオ × 3ペルソナ(協力的な学習者・初心者・話が逸れる学習者)を固定して、合計36会話で比較しました。
| 指標 | 移行前 | 移行後 |
|---|---|---|
| シナリオ完了 | 33 / 36 | 34 / 36 |
| 完了までのターン数 | 3.9 | 3.4 |
| 1返信あたりのコスト | 約 $0.0002 | 約 $0.0002 |
決め手は完了率ではなく、コストが横ばいのままターン数が縮んだことでした。ユーザーがより少ないやりとりで目的を達成でき、支払いは変わらない。この形になって初めて「乗り換えるべき」と言えます。
ペルソナを複数用意している点も効いています。協力的なユーザーだけを想定すると、会話が破綻する経路を一度も踏まないまま「問題なし」と結論してしまいます。
モデルの差し替えはリクエスト境界で行う
候補ごとにアプリをビルドし直してはいけません。ビルドが違えば、モデル以外の差が結果に混ざります。正しいやり方は、実装は一切変えず、送信するリクエストの model の値だけを差し替えることです。
その前提が、モデル指定が文字列1個に寄っていることです。ここが、プロバイダを直接呼ぶ構成とゲートウェイを挟む構成ではっきり分かれます。
| 候補を1つ増やすときに必要なもの | プロバイダを直接呼ぶ場合 | ゲートウェイ経由の場合 |
|---|---|---|
| SDK・クライアント実装 | プロバイダごとに追加 | 変更なし |
| APIキーと認証方式 | 発行して環境変数を追加 | 変更なし |
| リクエスト/レスポンスの形 | プロバイダごとに差異を吸収 | 変更なし |
| 契約・請求先 | プロバイダごとに増える | 変更なし |
| コードの変更量 | 分岐が1つ増える | model の文字列1行 |
差分が文字列1個に収まると、モデルの切り替えがプログラムから制御できる状態になります。環境変数で切り替える、設定ファイルから読む、リクエストごとに動的に選ぶ、evalスクリプトが候補を順番に回す——どれも同じ1行を書き換えるだけになります。プロバイダごとに実装が分岐していると、この「順番に回す」が一番やりたいときに一番面倒になります。
curl https://api.fastmetal.ai/v1/chat/completions \
-H "Authorization: Bearer $FASTMETAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-luna",
"messages": [{"role": "user", "content": "この問い合わせを3行で要約して"}]
}'
候補Bを試すときに変えるのは "model": "anthropic-claude-haiku-4-5" の1行だけです。キーもエンドポイントも同じままで、OpenAI社のモデルからAnthropic社のモデルへ移っています。契約もキーも増えません。
コードから回すなら、候補をただの配列にできます。
from openai import OpenAI
client = OpenAI(api_key=FASTMETAL_API_KEY, base_url="https://api.fastmetal.ai/v1")
candidates = ["gpt-5.6-luna", "anthropic-claude-haiku-4-5", "gemini-3.5-flash"]
for model in candidates:
res = client.chat.completions.create(model=model, messages=messages)
record(model, res.choices[0].message.content, res.usage)
プロバイダを直接呼ぶ構成では、このループはSDKごとの分岐になります。利用できるモデルはモデル一覧で確認できます。
eval自体を検証する
最も見落とされる部分です。evalは、モデルを採点する前にまず自分自身を疑う必要があります。 実際に見つかりやすい失敗が3つあります。
判定役に渡すコンテキストが足りていない
前述の会話アプリでは、判定モデルに渡していたのが「画面表示用リストの末尾12件」でした。そのリスト自体が15件で切られていたため、会話の序盤にあった違反行為はすでにスクロールアウトし、判定モデルには見えていなかった。
症状は「判定が甘い」。しかし原因はモデルではなく入力の作り方です。判定に使うログは表示用と分け、切り詰めないものを渡す必要があります。
独立した採点者と突き合わせる
判定モデルを信用してよいかは、別プロンプト・別呼び出しの採点者(critic)に同じ会話を採点させ、結果を突き合わせることで確認できます。食い違った項目が、誤検知や取りこぼしの候補です。
このとき、不一致数を品質スコアに混ぜないことが重要です。不一致は会話の出来ではなく測定系の出来を表す数字だからです。混ぜると、品質が落ちたのか測定が壊れたのかを区別できなくなります。
タスク定義そのものを静的にチェックする
会話を1回も走らせず、タスクの達成条件を機械的にレビューさせるだけでも成果が出ます。前述の例では全50シナリオのうち3件に問題が見つかりました。動詞が曖昧で判定不能なもの、達成がAI側の出方に依存していてユーザーには制御できないもの、真偽が決まらない評価的な条件です。
これらはどのモデルに差し替えても改善しません。 モデルの問題に見えて、実は仕様の問題という典型例です。
落とし穴:新しいモデルが判定役に向くとは限らない
先の例では会話モデルを新世代に乗り換えた一方、判定モデルは旧世代に据え置くという結論になりました。新世代を判定役にすると、固定した採点者との不一致が増え、さらに1回あたり約400ms遅くなったためです。判定は毎ターン走るので、この遅延はそのままユーザーの体感に乗ります。
判定役に求められるのは賢さより基準からブレないことと速度です。「新しい方が上」で一括更新すると踏みます。
落とし穴:推論トークンの課金
先の実測でコストが横ばいだったのには理由があります。GPT-5系のモデルは reasoning_effort を明示しないと、思考(reasoning)トークンが出力として課金される場合があります。短い応答を返すだけの用途に推論は不要なので、ここは明示的に切る必要があります。
キャッシュの課金レートや出力トークンの数え方も、世代が変わると仕様が変わります。乗り換え検討では品質と同時に、実際にいくら請求されたかを必ず記録してください。料金の考え方は料金ページにまとめています。
よくある質問
Q. evalはどれくらいの規模から作る価値がありますか? A. 固定タスクが10件あれば十分に始められます。上の例も12シナリオです。重要なのは件数より、変更の前後で同じセットを使うことです。母集団が動くと前後比較が意味を失います。
Q. LLM-as-a-judge は信用できますか? A. そのままでは信用できません。判定モデルを固定し、独立した採点者と突き合わせて不一致を監視する運用とセットで初めて使えます。判定モデルを変えるとスコアの尺度も変わるため、比較は同じ判定モデル内でのみ有効です。
Q. 複数プロバイダのモデルを比較するには契約が必要ですか? A. LLMゲートウェイを使えば1つのキーで横断的に呼べます。比較のためだけに複数のアカウントを開設したり、請求先を分散させたりする必要はありません。
まとめ
- 公開ベンチマークは自社のプロダクトで良くなるかを教えてくれない。自分のタスクで測る。
- 測るのは完了率・効率・品質スコア・コストの4つ。品質だけでは採用判断ができない。
- 候補は同一の実装に対して
modelの値だけ差し替えて比較する。 - eval自体を疑う仕組みを最初から入れる。最初の数回は、evalがモデルではなく自分の実装を採点しにきます。
- 世代が変わると課金の仕様も変わる。推論トークンの扱いを確認する。
FastMetalは1つのAPIキーと1つの残高で複数モデルを横断して呼べる、OpenAI互換のLLMゲートウェイです。model の値を変えるだけで候補を切り替えられるため、evalでのモデル比較と相性のよい構成になっています。プリペイド制なので、比較のために契約を増やす必要も、残高を超える請求が届くこともありません。
無料でアカウントを作成して、手元のタスクで比較してみてください。