8.1.8 RAG 評価

学習目標
この節を終えると、あなたは次のことができるようになります。
- RAG を 1 回のデモだけで良し悪し判断してはいけない理由を理解する
- 検索評価と回答評価の違いを整理する
- 小さなサンプルで簡単な指標を計算する
- 「まず評価し、それから改善する」という開発習慣を身につける
一、なぜ RAG には特に評価が必要なのか?
単一のモジュールではないから
RAG は 1 つのモデルではなく、少なくとも次の要素を含みます。
- 文書処理
- 検索
- コンテキストの組み立て
- 回答生成
どれか 1 つでも失敗すると、最終的な答えは悪くなる可能性があります。
だから「正解したか」だけでは足りない
次の点も確認する必要があります。
- 検索できなかったのか?
- 検索はできたが、うまく使えなかったのか?
- それとも、回答の文章がうまくまとまっていないのか?
だからこそ、RAG の評価は階層ごとに見る必要があります。
二、第一層:検索評価
最もよく使う直感的な指標:Hit@k
Hit@k の意味はとてもシンプルです。
正しい証拠が、上位 k 件の検索結果に入っているか?
ユーザーの質問に対する正しい証拠が top-3 にあれば、hit とみなします。
なぜこの指標が重要なのか?
正しい資料がそもそも取り出せていなければ、その後の生成で安定して正解するのはほぼ不可能だからです。
つまり、
検索評価は RAG 評価の土台です。
三、第二層:回答評価
「文章が自然」だけではまったく足りない
回答評価では、少なくとも次の点を見る必要があります。
- 答えが正しいか
- 根拠があるか
- 勝手に作っていないか
よく見る観点
| 観点 | 注目する点 |
|---|---|
| Correctness | 事実として正しいか |
| Faithfulness | 与えられた資料に基づいているか |
| Relevance | ユーザーの質問に答えているか |
| Completeness | 重要な情報が漏れていないか |
実際の業務では、観点ごとの重要度は異なります。


よい評価は 1 回で終わるものではなく、テストセット -> 検索 -> 回答 -> 引用 -> 失敗分析 -> 修正 -> 再評価、というループです。
最終回答のスコアだけを見ないでください。まず retrieval 層でヒットしているかを見て、次に generation 層で正しく完全かを見ます。最後に citation 層で、その結論を本当に支えているかを確認します。
四、最小の評価データセット
ここでは、手作業で作ったミニ評価データセットを用意します。
dataset = [
{
"question": "いつまで返金できますか?",
"gold_doc": "返金ポリシー",
"gold_answer": "コース購入後 7 日以内に返金を申請できます"
},
{
"question": "どうやって証明書を取得しますか?",
"gold_doc": "証明書の説明",
"gold_answer": "プロジェクトを完了し、テストに合格すると証明書を取得できます"
}
]
predictions = [
{
"retrieved_docs": ["返金ポリシー", "学習順序"],
"answer": "コース購入後 7 日以内に返金を申請できます"
},
{
"retrieved_docs": ["学習順序", "証明書の説明"],
"answer": "プロジェクトを完了し、テストに合格すると証明書を取得できます"
}
]
print(dataset)
print(predictions)
期待される出力:
[{'question': 'いつまで返金できますか?', 'gold_doc': '返金ポリシー', 'gold_answer': 'コース購入後 7 日以内に返金を申請できます'}, {'question': 'どうやって証明書を取得しますか?', 'gold_doc': '証明書の説明', 'gold_answer': 'プロジェクトを完了し、テストに合格すると証明書を取得できます'}]
[{'retrieved_docs': ['返金ポリシー', '学習順序'], 'answer': 'コース購入後 7 日以内に返金を申請できます'}, {'retrieved_docs': ['学習順序', '証明書の説明'], 'answer': 'プロジェクトを完了し、テストに合格すると証明書を取得できます'}]
このデータは「正解」と「予測」に分けて読みます。gold_doc / gold_answer は参照基準で、retrieved_docs / answer は RAG システムが出した結果です。
五、簡単な Hit@k を計算する
実行できる例
dataset = [
{
"question": "いつまで返金できますか?",
"gold_doc": "返金ポリシー"
},
{
"question": "どうやって証明書を取得しますか?",
"gold_doc": "証明書の説明"
}
]
predictions = [
{
"retrieved_docs": ["返金ポリシー", "学習順序"]
},
{
"retrieved_docs": ["学習順序", "証明書の説明"]
}
]
hits = 0
for item, pred in zip(dataset, predictions):
if item["gold_doc"] in pred["retrieved_docs"]:
hits += 1
hit_at_2 = hits / len(dataset)
print("Hit@2 =", round(hit_at_2, 4))
期待される出力:
Hit@2 = 1.0
正しい文書がすべて上位 2 件に入っていれば、この値は 1.0 になります。
この指標の限界
これで分かるのは「取り出せたかどうか」だけです。
次のことは分かりません。
- 何位だったのか
- 回答が本当に正しいのか
なので、これはあくまで最初の一歩です。
六、簡単な回答正解率を計算する
最もシンプルな Exact Match の考え方
構造化された短い回答なら、まずは素朴な方法で確認できます。
dataset = [
{
"gold_answer": "コース購入後 7 日以内に返金を申請できます"
},
{
"gold_answer": "プロジェクトを完了し、テストに合格すると証明書を取得できます"
}
]
predictions = [
{
"answer": "コース購入後 7 日以内に返金を申請できます"
},
{
"answer": "プロジェクトを完了し、テストに合格すると証明書を取得できます"
}
]
correct = 0
for item, pred in zip(dataset, predictions):
if item["gold_answer"] == pred["answer"]:
correct += 1
exact_match = correct / len(dataset)
print("Exact Match =", round(exact_match, 4))
期待される出力:
Exact Match = 1.0
でも実際の場面はそんなに単純ではない
同じ正解でも、言い方はいろいろあります。
そのため、実運用では次のような方法もよく使います。
- 意味ベースのマッチング
- LLM-as-a-judge
- 人手によるサンプルチェック
七、Faithfulness: 回答は根拠に基づいているか?
「それっぽく見える」より大事
文章としては流暢でも、検索した資料に基づいていないなら危険です。
簡単な確認方法の例
以下の例はかなり単純ですが、「回答が証拠で支えられているか」を理解する助けになります。
evidence = "コース購入後 7 日以内に返金を申請できます"
answer = "コース購入後 7 日以内に返金を申請できます"
faithful = answer in evidence or evidence in answer
print("証拠に支えられているか:", faithful)
期待される出力:
証拠に支えられているか: True

実際のシステムでは、もちろんこんな文字列比較だけではありません。
ただ、考え方としては正しいです。
回答は、できるだけ検索した証拠の中で支えられるべきです。

回答をいくつかの重要な結論に分けて、それぞれを evidence に戻して確認します。つながるものは supported、つながらないものは unsupported です。これは「見た目が自然か」より信頼できます。
八、評価データセットはどう作る?
最小限で使える評価セット
少なくとも次を含めましょう。
- ユーザーの質問
- 標準回答
- 正しい証拠文書または証拠スニペット
難しさの違う問題を混ぜるのがおすすめ
たとえば次のような問題です。
- 簡単な事実問答
- 同義表現の質問
- 複数段落にまたがる質問
- 混同しやすい質問
評価セットが単一的すぎると、改善結果が実態より良く見えてしまいます。
九、オンライン評価もとても重要
オフライン評価だけでは全部は分からない
ローカルのデータセットがどれだけ良くても、実際のユーザー質問を完全にはカバーできません。
よく見るオンラインのシグナル
たとえば次のようなものです。
- ユーザーの追加質問率
- ユーザーの修正率
- いいね / 低評価
- 人手による品質チェックのサンプリング
成熟した RAG システムでは、通常「オフライン評価 + オンラインフィードバック」をセットで見ます。
十、目標が「知識ベース駆動の教材生成アシスタント」なら、何を重視して評価する?
このタイプのプロジェクトは、普通の QA システムとは少し違います。
大事なのは「答えがそれっぽいか」だけではなく、次の点です。
- テーマ資料を正しく見つけられているか
- 例題を適切に取れているか
- 最終的なセクションを正しい場所に置けているか
- 出典をたどれるか
このようなプロジェクトに向いた評価表では、少なくとも次のような層を追加するとよいです。
| 観点 | 何を見るか |
|---|---|
| テーマ命中 | そのテーマの核心資料を見つけられたか |
| 例題の再現 | 説明用の例題として適切な材料を見つけられたか |
| 構造の正しさ | 概念、例題、練習が正しいセクションに入っているか |
| 出典の完全性 | 最終結果を元資料までたどれるか |
まずは次のように理解するとよいです。
教材生成プロジェクトの評価は、「答えたか」ではなく「見つけたか、置けたか、引用できたか」を見ることです。
十一、教材生成プロジェクトに近い最小評価例
dataset = [
{
"topic": "割引の応用問題",
"gold_concepts": ["割引 = 元の価格 × 割引率"],
"gold_examples": ["商品は元値 100 円、8 割引後の価格はいくらですか?"],
}
]
prediction = {
"concepts": ["割引 = 元の価格 × 割引率"],
"examples": ["商品は元値 100 円、8 割引後の価格はいくらですか?"],
"source_refs": [{"doc_id": "word_001", "page_or_slide": 3}],
}
print(dataset[0])
print(prediction)
期待される出力:
{'topic': '割引の応用問題', 'gold_concepts': ['割引 = 元の価格 × 割引率'], 'gold_examples': ['商品は元値 100 円、8 割引後の価格はいくらですか?']}
{'concepts': ['割引 = 元の価格 × 割引率'], 'examples': ['商品は元値 100 円、8 割引後の価格はいくらですか?'], 'source_refs': [{'doc_id': 'word_001', 'page_or_slide': 3}]}
この例は小さいですが、初学者が評価の感覚をつかむのに役立ちます。
- この種のシステムで最終的に評価するのは、たいてい「1 文の答え」ではない
- 1 つの構造化された結果全体である
十二、初学者によくある誤解
1 つか 2 つの成功例だけを見る
デモはやる気を出させますが、評価の代わりにはなりません。
回答だけ評価して、検索を評価しない
これだと、問題がどの層で起きているのか分かりにくくなります。
システムを修正しながら、評価セットを固定しない
固定された評価セットがないと、本当に改善したのか、それともたまたま変動しただけなのか判断しにくくなります。
RAG プロジェクトの評価指標まとめ表
RAG プロジェクトでは、「答えがそれっぽいか」だけを見てはいけません。より安定した方法は、評価を検索、生成、引用、システムの 4 層に分けることです。
| 層 | 指標 | 説明 |
|---|---|---|
| 検索層 | 命中率、Recall@K、MRR | 正しい資料が見つかったか、上位に来ているか |
| 生成層 | 回答正解率、完全性、一貫性 | 資料に基づいて答えられているか、重要条件を落としていないか |
| 引用層 | 引用カバレッジ、引用の真正性 | 回答中の重要な結論が出典にたどれるか |
| システム層 | レイテンシ、コスト、失敗率 | 実ユーザーに安定して、無理なく提供できるか |
最小評価セットは、まず 20〜50 問ほど用意するのがおすすめです。各問題に標準回答、命中すべき文書、重要な引用を付けておきます。こうしておけば、chunk、embedding、rerank、query rewrite を改善したときに、本当に良くなったのか、それとも一部の例だけ見栄えが良くなったのかを判断できます。
層ごとの失敗原因の切り分け表
評価の価値は、単に総合点を出すことではありません。次にどこを直すべきかを知ることです。下の表は、実験記録にそのまま使えます。失敗が出たら、まずどの層の問題かを切り分けましょう。
| 失敗の現象 | 失敗層 | 確認すべき点 | 次のアクション |
|---|---|---|---|
| 正しい文書が top-k に入らない | 検索層 | query、chunk、embedding、キーワード一致 | チャンク分割を調整する、混合検索や query rewrite を加える |
| 正しい文書は top-k にあるが、最終 context に入らない | コンテキスト層 | context packing、重複除去、長さ制限 | 並び順、圧縮、パッキング戦略を調整する |
| context に証拠はあるが、回答が重要条件を落としている | 生成層 | prompt、回答形式、モデルが証拠に従っているか | 証拠に基づいて 1 つずつ答えるように指示し、制約条件を残す |
| 結論は正しいが、引用が支えていない | 引用層 | source_refs、引用スニペット、回答文 | 引用の真正性チェックを行い、証拠のない引用を禁止する |
| オフライン評価は良いのに、ユーザーが何度も追い質問する | プロダクト層 | 実際の質問分布、評価セットのカバー範囲 | 実際の質問を評価セットに追加する |
「最終的に正解したか」だけを見ると、これらの問題は混ざってしまいます。層ごとに切り分けると、改善のアクションがはっきりします。検索が悪いなら prompt をいじる前に検索を直すべきですし、引用が悪いなら答えの自然さだけを見ても意味がありません。
そのまま使える評価記録テンプレート
RAG プロジェクトでは、毎回の評価を固定フォーマットで残すのがおすすめです。最初は十数件でも、単発のデモを見るよりずっと安定して状況を把握できます。
| フィールド | 例 | 用途 |
|---|---|---|
question | コースはいつまで返金できますか? | ユーザーの質問 |
gold_doc | 返金ポリシー | 命中すべき資料 |
gold_answer | コース購入後 7 日以内に返金を申請できます | 標準回答または重要事実 |
retrieved_docs | 返金ポリシー, 学習順序 | 実際に命中した文書 |
answer | 7 日以内に返金を申請できます | システムの回答 |
citation_ok | true | 引用が回答を支えているか |
failure_type | none / retrieval / generation / citation | 失敗原因 |
notes | 正しく命中し、引用も支えている | 人手メモ |
最小の CSV は次のように書けます。
question,gold_doc,gold_answer,retrieved_docs,answer,citation_ok,failure_type,notes
コースはいつまで返金できますか?,返金ポリシー,コース購入後 7 日以内に返金を申請できます,"返金ポリシー;学習順序",コース購入後 7 日以内に返金を申請できます,true,none,正しく命中し引用も支えている
どうやって証明書を取得しますか?,証明書の説明,プロジェクトを完了し、テストに合格すると証明書を取得できます,"学習順序;証明書の説明",プロジェクトを完了すると証明書を取得できます,false,generation,テストに合格するという重要条件が抜けている
このテンプレートのポイントは、項目が多いことではありません。各サンプルについて、次の 3 つが分かることです。何を命中すべきか、実際に何を命中したか、最終回答は証拠に支えられているか。
教材生成 RAG の受け入れ Rubric
プロジェクトの目的が教材や学習資料の生成なら、評価は QA の段階だけで終わらせるべきではありません。次の rubric は、ポートフォリオ用プロジェクトの受け入れ基準として使えます。
| レベル | 検索要件 | 生成要件 | 引用要件 |
|---|---|---|---|
| 練習レベル | テーマ関連資料を命中できる | 基本的な回答や断片を生成できる | 参照ファイル名を表示できる |
| プロジェクトレベル | topic と content_type に応じて概念、例題、練習を検索できる | 決まったセクション構成で出力できる | 重要セクションごとに出典がある |
| ポートフォリオレベル | 固定の評価セットと失敗サンプルがある | 失敗が検索・生成・テンプレートのどれか説明できる | 重要な結論を原文までたどれる |
| 面接レベル | baseline、混合検索、rerank などの戦略を比較できる | 品質、コスト、レイテンシのトレードオフを説明できる | 引用の真正性を抽出確認し、改善記録を残せる |
この表はそのまま README に入れられます。そうすれば、見る人に「ただ質問に答えるデモを作った」のではなく、「知識ベース駆動システムを工程として評価している」ことが伝わります。
まとめ
この節で最も大事なポイントは次の通りです。
RAG 評価はおまけではなく、システム改善のためのハンドルです。
評価がなければ、感覚でしか改善できません。
評価があれば、どこが悪いのか、変更が本当に効果を出したのかが分かります。
練習
- 評価セットにさらに 3 問追加して、自分で
gold_docとgold_answerを書いてみましょう。 predictionsを変更して、わざと 1 つの回答を間違えさせ、Hit@k と Exact Match をもう一度計算してみましょう。- 考えてみましょう。Hit@k は高いのに、最終回答がよく間違うなら、問題はどの層にある可能性が高いでしょうか?