DanLevy.net

LLM評価で悪を討つ!

ベンチマークはベンチマークを測るだけ。あなたのシステムには独自の測定基準が必要だ。

新しいモデルが登場するたび、メイド服のようなベンチマークの集まりを着ている。

MMLU: 92.4%。HumanEval: 87.2%。LLeMU: 88.7%。MATH: 73.6%。AGI: 127%!

しかし、ビジネスでのプロセスと製品の構築を行う99%の人にとって、それらのことは何の意味も持たない。

何が重要か?あなたのワークロードはどのように振る舞っているのか?改善しているのか、劣化しているのか?それを知る唯一の健全な方法は、その特定のタスク、データ、およびシステムの失敗パターンを反映した評価(LLMのためのテスト)を書くことだ。

ベンチマークは嘘をついていない。彼らは他の人の質問に答えているだけだ。


「バイブスベース評価」が実際に何を意味するのか

標準的なアプローチ:モデルの変更をリリースし、不満のチャンネルを見守り、部屋が騒がしくなればロールバックする。

それはほとんどの興味深い部分を見落としている。

**騒がしい失敗しかキャッチできない。**自信を持って間違った答えを返し、それに気づいていないユーザー?無言。悪くなった答えを返し機能を放棄するユーザー?無言。サポートチケットとエラー率は品質の回帰の一部しかキャッチできない。

**回帰と改善を区別できない。**新しいモデルがタスクAでは良くてタスクBでは悪くなる場合、Bに関する不満は一般的な「AIが悪くなった」というフィードバックと同じように見える。何を修正すべきか分からない。

**あなたのユーザーをテストインフラとして使用している。**彼らはそれに同意していない。


評価スペクトル(そして多くのチームが間違っている場所)

評価アプローチは、「高速だが不安定」から「高コストだが有効」までのスケールに位置する。

A spectrum diagram comparing deterministic checks, LLM-as-judge, and human evaluation by speed, cost, and validity.

失敗を誠実にキャッチできる最も安価な評価方法を使え。

LLM-as-judgeは現在の熱心な支持者だ:強力なモデルに別のモデルの出力を採点させる。高速、スケーラブル、安価。問題:採点モデル自身のバイアスが組み込まれ、遊びに負けやすく、循環的な依存関係を作成する。GPT-5を使用してGPT-5の出力を採点する場合、何か別のもの、あなたが思っているものとは違うものを採点していることになる。それは決して無駄ではないが、あなたが思っていることではない。

人間評価は、スキップしようとするゴールドスタンダードだ。人間に評価を依頼することは高コスト、遅い、評価者間の一貫性がなく、スケジュールするのが面倒だ。しかし、あなたのシステムが実際の人間にとって役立っているかどうかを検証する唯一のものだ。

タスク固有の自動チェックは、多くのチームがより多くの時間を費やすべき場所だ。それは華々しくないが、高速、決定論的であり、あなたのシステムで重要なものに結びついている。


実際に機能するもの

1. 出荷前に失敗を定義する

モデルやプロンプトを変更する前に、どんなに悪いかを書き留める。具体的に。

「出力は正確でなければならない」とはテストではない。もっと次のようなもの:

これらはプログラムでチェックできる。採点モデルは不要だ。

評価ハーネス:決定論的チェック

type EvalResult = { passed: boolean; reason?: string };
const evals: Record<string, (output: string, context: EvalContext) => EvalResult> = {
// JSON must parse
validJson: (output) => {
try {
JSON.parse(output);
return { passed: true };
} catch (e) {
return { passed: false, reason: `Invalid JSON: ${e.message}` };
}
},
// No hallucinated citations — every claim must appear in context
groundedCitations: (output, { retrievedChunks }) => {
const claims = extractCitations(output);
const ungrounded = claims.filter(
(claim) => !retrievedChunks.some((chunk) => chunk.includes(claim))
);
return ungrounded.length === 0
? { passed: true }
: { passed: false, reason: `Ungrounded claims: ${ungrounded.join(', ')}` };
},
// Response length sanity check — catch truncation or runaway generation
reasonableLength: (output) => {
const words = output.split(/\s+/).length;
return words >= 10 && words <= 2000
? { passed: true }
: { passed: false, reason: `Word count ${words} out of bounds` };
},
};

2. 最も悪い日に基づいて金セットを作る

最良の評価データは、恥ずかしいものだ:誰かがチケットを出した、幻覚をスクリーンショットした、または無言で機能を停止させた出力。

ユーザーが悪い出力を報告するたび、幻覚をフラグが付く、または手動で失敗を気づくたびに、それをあなたの金セット(入力、コンテキスト、正しい動作)に追加する。50-100個のケースを保管し、すべてのモデル変更で実行する。

最初は手動に感じる。6ヶ月後には、パブリックベンチマークで操作できないテストスイートを持つことになる。すべてのケースがあなた自身の失敗履歴から来ているためだ。

A workflow diagram showing how bad production incidents become golden cases, then CI eval runs, then blocked regressions or approved releases.

金セットは恥ずかしいものを回帰スイートに変える。

金ケースの形状

interface GoldenCase {
id: string;
input: string;
context: Record<string, unknown>;
expectedBehavior: {
mustContain?: string[];
mustNotContain?: string[];
structureCheck?: (output: string) => boolean;
minSimilarityToReference?: number; // cosine similarity to a reference answer
};
sourceIncident?: string; // link back to the bug report or ticket
}

3. 受入テストだけでなく、回帰テストを行う

多くのチームはモデル変更を検討する場合にのみ評価を実行する。それは受入テストだ:「この新しいものは十分に良いか?」

回帰テストも必要だ:「これは以前機能していたものを壊したか?」

ベースラインがなければ気づけない。古く機能していたプロンプトに新しいツールを追加する、RAG取得戦略を変更する、またはコンテキストテンプレートを更新すると、サイレントに劣化する可能性がある。ダッシュボードではなく、インシデントレポートにのみ現れる回帰を知るために、すべてのプロンプト変更に対して金セットを実行する。Langfuseのようなツールは、評価スコアを生産トラックに接続するため、ダッシュボードではなくインシデントレポートにだけ現れる回帰を表示する。

評価ハーネス:ベースラインと候補の比較
async function compareModelVersions(
goldenCases: GoldenCase[],
baselinePipeline: Pipeline,
candidatePipeline: Pipeline
) {
const results = await Promise.all(
goldenCases.map(async (tc) => {
const [baseline, candidate] = await Promise.all([
baselinePipeline.run(tc.input, tc.context),
candidatePipeline.run(tc.input, tc.context),
]);
return {
id: tc.id,
baselinePassed: runEvals(baseline, tc.expectedBehavior),
candidatePassed: runEvals(candidate, tc.expectedBehavior),
regression: /* baseline passed */ && /* candidate failed */,
improvement: /* baseline failed */ && /* candidate passed */,
};
})
);
const regressions = results.filter((r) => r.regression);
const improvements = results.filter((r) => r.improvement);
console.log(`Regressions: ${regressions.length} / ${goldenCases.length}`);
console.log(`Improvements: ${improvements.length} / ${goldenCases.length}`);
if (regressions.length > 0) {
console.error('Blocking regressions found:');
regressions.forEach((r) => console.error(` - ${r.id}`));
}
return { regressions, improvements };
}

候補が既知の失敗で回帰した場合、アップグレードの会話は魅力的に具体的になる:どのケースが改善し、どのケースが壊れ、そのトレードが値するかどうか。

4. 正確に一つのことのためにLLM-as-Judgeを使う

LLM-as-judgeは、決定論的な正解がない開放された出力に便利だ:「この応答は役に立っているか?」「このサマリーは重要な点を保存しているか?」「この説明は初心者に合っているか?」

そこで使う。決定論的な答えには使ってはならない。使用するときは採点ルールブリッドを明確にする。

評価ハーネス:ルールベース採点者

async function judgeHelpfulness(
userQuery: string,
modelResponse: string
): Promise<{ score: number; reasoning: string }> {
const judgePrompt = `
You are evaluating a customer support response.
User question: ${userQuery}
Response: ${modelResponse}
Rate the response on a scale of 1-5:
5 = Directly answers the question with accurate, actionable information
4 = Answers the question but could be more specific or actionable
3 = Partially addresses the question; key information is missing
2 = Tangentially related but doesn't answer the question
1 = Off-topic, factually wrong, or harmful
Respond with JSON: {"score": <number>, "reasoning": "<one sentence>"}
`;
const result = await judgeModel.generate(judgePrompt);
return JSON.parse(result);
}

明確なルールブリッドは評価者のバリエーションを削減し、解釈可能な出力を与え、採点者が間違っているときに監査しやすくする。AutoevalsBraintrustのようなライブラリは、一般的なタスクの事前構築された採点関数を商品にする——あなた自身からゼロから書く前に盗む価値がある。


知っておく価値のあるツール

すべてをゼロから構築する必要はない。いくつかのツールが評価インフラ問題でかなりの進歩を遂げている。

Braintrust — 完全な評価プラットフォーム。実験トラッキング、データセット管理、および採点関数。プロンプト、モデル、デプロイごとに評価実行を整理するため、時間ではなくリリース間で品質を比較できる。オープンソースの**Autoevals**ライブラリと組み合わせると良い選択だ。一般的なタスク(事実の正確性、役立ち、有害性、意味的類似性)の事前構築されたモデル採点関数を商品にする。

Langfuse — モデルとあなたのアプリの間に位置するオープンソースのLLM可観察性。すべての呼び出しを追跡し、個々のスパンに評価スコア(人間または自動)を接続し、生産トラフィック上の品質のトレンドを表示する。可観察性と評価を同じツールでやりたい場合の良い選択。

Evalite — Matt PocockによるTypeScriptネイティブ評価フレームワーク。儀式が少ない:タスクを定義し、採点者を定義し、既存のテスト設定で実行する。評価を別のML実験プラットフォームではなく、単体テストのように感じるチームを対象にしている。

promptfoo — プロンプト比較とレッドチームへの焦点を当てたCLI優先の評価ランナー。YAMLで簡単に設定でき、ほとんどのモデルプロバイダと統合し、プロンプトインジェクションやその他の攻撃的な入力を検出する機能がある。

deepeval — Python評価フレームワーク。大規模な組み込みメトリックのライブラリ(G-Eval、RAG忠実性、答えの関連性、幻覚検出)がある。取得品質だけでなく生成品質向けの特定の採点が必要なRAGパイプラインに有用。

適切なツールはあなたのスタックとどこから始めているかに依存する。実行するという習慣よりも重要なのは、すべての重要な変更において一貫して評価を実行することだ。


不快な部分

多くのチームはこれをスキップする。なぜなら、早期に不愉快な質問を投げかけるからだ:「ここで『良い』とは何か?」。

新しいAI機能については本当に困難だ。信頼性を気にするなら、これは非オプションだ。信頼できるAIをリリースするチームは、重要なコードパスのための何でも一緒に行うことをする:期待される動作を定義し、それをテストし、それらのテストを継続的に実行する。

ベンチマークは嘘をついていない。彼らは他の人の質問に答えているだけだ。製品ロードマップとしてそれらを読むのをやめ、システムに合ったテストを書き始めよう。

ダッシュボードが気づく前に、あなたのユーザーが気づくだろう。まずテストスイートを構築する。

(End of file - total 265 lines)