RAGChecker(ラグチェッカー)は、RAG(Retrieval-Augmented Generation=検索拡張生成)の回答品質を、検索(リトリーバー)と生成(ジェネレーター)に分けて数値化する評価フレームワークです。Amazonの研究者らが開発し、論文「RAGChecker: A Fine-grained Framework for Diagnosing Retrieval-Augmented Generation」(arXiv 2408.08067)はNeurIPS 2024のDatasets and Benchmarks Trackに採択されました。回答と正解を「クレーム(主張)」単位に分解して照合するので、精度を落としている工程を指標で切り分けられます。この記事では論文の評価結果、11個の指標の読み方、pip install ragcheckerからの使い方に加え、公式READMEに書かれていない動作環境の制約とLLM呼び出し回数の見積もり方を、0.1.9のソースコードとGitHubのIssueで確かめた内容に沿って解説します。
まとめ
- 正体:Amazon製のRAG評価OSS(Apache-2.0)。GitHubのamazon-science/RAGCheckerで公開。論文はarXiv 2408.08067。
- 評価結果:人手の選好との相関(総合評価のPearson)は61.93で、比較対象のうち最も高いRAGASのAnswer Similarity(48.31)を上回る。
- 指標:全体3個・検索2個・生成6個の計11個。どれが悪いかで直すべき工程が分かる。
- 動く環境:PyPIの表記はPython 3.9以上だが、0.1.9はPython 3.10以上でないと構文エラーになる。3.10〜3.12で使う。
- 費用:1問あたりのLLM呼び出しは「2+(検索チャンク数+1)×(クレーム数÷5の切り上げ合計)」回。チャンク5件・クレーム各10件なら26回。
- 判断:本体の最終リリースは2024年9月25日の0.1.9で、2024年12月13日を最後にコミットが無い。日本語のRAGや本番監視の主軸には据えず、検索と生成のどちらが悪いかを切り分けたい検証局面で使う。
RAGCheckerの開発元と論文(arXiv 2408.08067・NeurIPS 2024)
RAGは外部文書を検索して取り込み、その内容を根拠にLLMが回答する仕組みです。検索器と生成器の複合システムなので、回答が誤ったとき「検索が拾えていない」のか「拾った文書を生成が使えていない」のかを全体スコアだけでは区別できません。RAGCheckerはこの切り分けを目的に作られました。
論文は2024年8月15日にarXivへ投稿され、NeurIPS 2024のDatasets and Benchmarks Trackに掲載されています。実装は同じAmazon製の事実性チェックライブラリRefCheckerを土台にしています。
論文の評価設定:4,162問・10領域・8つのRAG
論文はWikipedia・小説・生物医学・金融・技術など10領域の公開QAデータを転用し、4,162問のベンチマークを作りました。検索器2種(BM25とE5-Mistral)と生成器4種(GPT-4・Mixtral-8x7B・Llama3-8B・Llama3-70B)を組み合わせた8システムを評価し、最も成績が良かったのはE5-MistralとGPT-4の組み合わせです。クレームの抽出と照合には、抽出器・照合器ともLlama3-70Bを使っています。
人手評価との相関:RAGASなど既存指標との比較
メタ評価では、8システムの回答を2つずつ並べた280組に人手で優劣を付け、各指標が人の判断とどれだけ一致するかを測っています。各フレームワークで最も相関が高かった指標同士の比較が次の表です(論文Table 2の総合評価の列から主要な行を抜粋。BLEUは35.14、BERTScoreは33.51)。
| 評価方法(指標) | Pearson | Spearman |
|---|---|---|
| RAGChecker | 61.93 | 60.90 |
| RAGAS(Answer Similarity) | 48.31 | 57.23 |
| ROUGE-L | 43.10 | 43.21 |
| CRUD-RAG(Recall) | 41.25 | 39.71 |
| TruLens(Answer Relevance) | 35.15 | 33.59 |
| ARES(Answer Relevance) | 17.81 | 16.26 |
| 人間の評価者どうし(上限の目安) | 70.09 | 68.89 |
RAGCheckerは比較対象の中で最も高い一方、人間どうしの一致(70.09)にはまだ届いていません。スコアを人の判断の代わりにする場合も、少数の人手確認は残すべきだと読めます。
クレーム単位で照合する仕組み
RAGCheckerは、LLMの抽出器(extractor)で回答と正解を「(主語, 関係, 目的語)」の三つ組のクレームに分解し、別のLLMの照合器(checker)で各クレームが参照テキストに含意されるかを判定します。照合は次の4種類で、どの指標を計算するかによって必要な照合が変わります(0.1.9のmetrics.pyの定義)。
| 照合の種類 | 何を何に照らすか | 使う指標の例 |
|---|---|---|
| answer2response | 回答のクレーム → 正解 | precision・hallucination |
| response2answer | 正解のクレーム → 回答 | recall・context_utilization |
| retrieved2answer | 正解のクレーム → 各チャンク | claim_recall・context_precision |
| retrieved2response | 回答のクレーム → 各チャンク | faithfulness・self_knowledge |
正解(gt_answer)の中身を使わないのはfaithfulnessだけです(入力JSONにgt_answerキー自体は必要で、空文字で構いません)。公式チュートリアルのFAQも、正解を用意できない本番監視ではfaithfulnessを使うよう案内しています。それ以外の10指標は、人が書いた正解が無いと計算できません。
評価指標11個の一覧と改善の読み方
| 分類 | 指標 | 意味 | 良い方向 |
|---|---|---|---|
| 全体 | precision | 回答のクレームのうち正しい割合 | 高い |
| 全体 | recall | 正解のクレームを回答が含む割合 | 高い |
| 全体 | f1 | precisionとrecallの調和平均 | 高い |
| 検索 | claim_recall | 正解のクレームをチャンクが含む割合 | 高い |
| 検索 | context_precision | 取得チャンクのうち関連する割合 | 高い |
| 生成 | context_utilization | 取得できた正解情報を回答が使った割合 | 高い |
| 生成 | noise_sensitivity_in_relevant | 関連チャンク内のノイズで誤った割合 | 低い |
| 生成 | noise_sensitivity_in_irrelevant | 無関係チャンクに引きずられて誤った割合 | 低い |
| 生成 | hallucination | どのチャンクにも無く誤ったクレームの割合 | 低い |
| 生成 | self_knowledge | どのチャンクにも無いが正しいクレームの割合 | 用途次第 |
| 生成 | faithfulness | 回答がチャンクに沿っている割合 | 高い |
ここでの「関連チャンク」は、正解のクレームを1つでも含むチャンクを指します。self_knowledgeだけは良し悪しが決まっておらず、社内文書だけで答えさせたいRAGなら低い方が望ましく、一般知識での補完を許すなら高くても問題ありません。
検索側の指標が低いときの打ち手
claim_recallが低いのは、答えに必要な情報をチャンクが含んでいない状態です。公式チュートリアルは、検索モデルの変更か取得件数を増やすことを勧めています。逆にcontext_precisionが低いのは無関係なチャンクを拾いすぎている状態で、取得件数を減らすのが第一手です。取得件数を減らさずに上位の質を上げるなら、リランクモデル(リランカー)とは?種類・2026年の代表モデルと選び方で扱うリランクを挟む方法があります。
論文の分析では、取得件数kを増やすとcontext_precisionは下がり、チャンクを大きくすると上がりました。チャンク間の重なり(オーバーラップ)を増やすとcontext_precisionは上がるものの、拾える有用情報の総量は増えなかったと報告されています。
生成側の指標が悪いときの打ち手
faithfulnessが低い、またはhallucinationが高いときは、取得した情報だけで答えるようプロンプトで指示を強めます。context_utilizationが低いなら、チャンクの中から関連箇所を探して使うよう促す指示が効きます。noise_sensitivityが高いなら、無関係な情報を捨てる推論ステップをプロンプトに入れます(いずれも公式チュートリアルの推奨)。長い文脈の中ほどにある情報が使われない問題はLost in the Middle現象とは|RAG精度が落ちる仕組みと設計での対策で詳しく扱っています。
RAGASとの違いと使い分け
RAGASは、正解なしで測れる指標(faithfulnessやanswer relevancyなど)を多く持ち、指標ごとに別の方法でスコアを出します。RAGCheckerは11指標すべてを同じクレーム照合の結果から計算し、検索側と生成側の診断指標を分けて出す点が違います。そのぶん、ほとんどの指標で人が書いた正解データを要求します。
使い分けははっきりしています。正解データを用意できない段階や、CIで毎回回す軽い評価にはRAGASを使います(指標と0.4系の実装はRAGASとは?RAG評価フレームワークの指標・0.4系の実装手順・導入判断【2026年版】)。正解付きの評価セットがあり、検索と生成のどちらを直すべきか決めたい場面でRAGCheckerを使います。RAG評価の指標全体の整理はRAG評価とは?検索と生成を分けて測る指標・Ragasでの実装・運用への組み込み【2026年版】にまとめています。
RAGCheckerのインストールと実行手順
動作するPythonの版と依存パッケージ
PyPIのragcheckerは0.1.9(2024年9月25日公開)が最新で、要件は「Python 3.9以上4.0未満」と表記されています。ただし0.1.9のevaluator.pyはPython 3.10で導入されたmatch文を使っており、Python 3.9.6で構文チェックするとSyntaxErrorになりました(2026年10月29日に配布物のソースで確認)。上限側も、Windows上のPython 3.13で導入に失敗し3.12では成功したという報告がIssue #32にあります。土台のrefchecker 0.2.17もPyPIで要件を「Python 3.10以上」と宣言しています。新しく環境を作るならPython 3.10〜3.12を選びます。
依存は軽くありません。土台のrefchecker 0.2.17がtorch・transformers・spaCy・litellm・anthropicなどを要求し、uvでLinux向けに依存を解決すると135パッケージになり、そのうち15個がCUDA関連のnvidia-*パッケージで、torch 2.15.0とtritonも入りました。評価器のLLMをAPIで呼ぶだけでGPUを使わないなら、PyTorchのCPU版を先に入れておくとコンテナを小さくできます。
python3.12 -m venv .venv
source .venv/bin/activate
pip install ragchecker
python -m spacy download en_core_web_sm
評価データ(JSON)の形式
入力は1つのJSONファイルで、results配列に1問ずつ、質問・正解・RAGの回答・取得チャンクを入れます。人が用意するのは正解(gt_answer)だけで、残りは評価したいRAGを実際に動かして集めます。
{
"results": [
{
"query_id": "000",
"query": "有給休暇は入社後いつから取得できますか",
"gt_answer": "入社6か月後から10日付与されます。",
"response": "入社から6か月が経つと、有給休暇が10日付与されます。",
"retrieved_context": [
{"doc_id": "rule-12", "text": "年次有給休暇は、雇入れの日から6か月継続勤務した者に10日を付与する。"},
{"doc_id": "rule-31", "text": "慶弔休暇の日数は別表に定める。"}
]
}
]
}
CLIでの実行とBedrock既定値の不具合
ragchecker-cliに入出力のパスと、抽出器・照合器のモデル名を渡します。CLIの--checker_nameには既定値が無いので省略できません。モデルの指定はlitellmの形式(bedrock/…、openai/…など)で、litellm自体の仕組みはLiteLLMとは?複数LLMを1つのAPIで呼ぶProxyの構築手順とフォールバック・予算設定【2026年10月】で解説しています。
ragchecker-cli \
--input_path=checking_inputs.json \
--output_path=checking_outputs.json \
--extractor_name=bedrock/meta.llama3-1-70b-instruct-v1:0 \
--checker_name=bedrock/meta.llama3-1-70b-instruct-v1:0 \
--extractor_api_base=https://bedrock-runtime.us-west-2.amazonaws.com \
--batch_size_extractor=32 \
--batch_size_checker=32 \
--metrics all_metrics
上の--extractor_api_baseはREADMEの例にはありませんが、Bedrockで使うなら付けておきます(Issue #37の報告者が回避策として示した方法です)。0.1.9のCLIはこの引数の既定値にモデル名の文字列が入っており、Bedrockへのリクエストが組み立てられずにエラーと10秒待ちの再試行を繰り返すことがIssue #37で報告されています。修正のプルリクエスト #41は2026年10月29日時点で未マージです。リージョン部分(us-west-2)は利用するモデルのあるリージョンに合わせてください。後述のPython APIは既定値が空なので、この問題は起きません。
Python APIと自前LLMでの実行
アプリのテストに組み込むならPython APIが扱いやすいです。0.1.9のCLIは結果ファイルのクレームや回答の日本語を\u形式のエスケープで書き出します(改善のプルリクエスト #25は未マージ)。Python APIならto_json(indent=2, ensure_ascii=False)で書き出せば日本語のまま読めます。
import json
from ragchecker import RAGResults, RAGChecker
from ragchecker.metrics import all_metrics
with open("checking_inputs.json", encoding="utf-8") as fp:
rag_results = RAGResults.from_json(fp.read())
evaluator = RAGChecker(
extractor_name="bedrock/meta.llama3-1-70b-instruct-v1:0",
checker_name="bedrock/meta.llama3-1-70b-instruct-v1:0",
batch_size_extractor=32,
batch_size_checker=32,
)
evaluator.evaluate(rag_results, all_metrics)
print(json.dumps(rag_results.metrics, indent=2))
# クレームや回答の日本語をエスケープせずに保存する
with open("checking_outputs.json", "w", encoding="utf-8") as f:
f.write(rag_results.to_json(indent=2, ensure_ascii=False))
litellmで呼べない社内のLLMやvLLMのサーバーを使うときは、custom_llm_api_funcにプロンプトのリストを受けて回答のリストを返す関数を渡します。RAGCheckerは大量のプロンプトを一度に渡すので、関数の中で並列に投げます。
from concurrent.futures import ThreadPoolExecutor
from openai import OpenAI
from ragchecker import RAGChecker
# vLLMなどOpenAI互換のサーバー(URLとモデル名は自分の環境に合わせる)
client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
MODEL = "meta-llama/Llama-3.1-70B-Instruct"
def ask(prompt):
r = client.chat.completions.create(
model=MODEL,
messages=[{"role": "user", "content": prompt}],
temperature=0,
)
return r.choices[0].message.content
def my_llm_api_func(prompts):
# 回答は prompts と同じ順番で返す
with ThreadPoolExecutor(max_workers=8) as ex:
return list(ex.map(ask, prompts))
evaluator = RAGChecker(custom_llm_api_func=my_llm_api_func)
LlamaIndexの回答の評価手順
LlamaIndexで作ったRAGは、ragchecker.integrations.llama_indexのresponse_to_rag_resultsで入力形式に変換できます(LlamaIndex公式の連携手順)。変換結果のquery_idはNoneになるため、自分で番号を振ってから渡します。
from ragchecker import RAGResults
from ragchecker.integrations.llama_index import response_to_rag_results
# query_engine・query・gt_answer は自分のRAGと評価セットのものを使う
response = query_engine.query(query)
result = response_to_rag_results(query=query, gt_answer=gt_answer, response_object=response)
result["query_id"] = "000"
rag_results = RAGResults.from_dict({"results": [result]})
LLM呼び出し回数と費用の見積もり方
RAGCheckerの費用は、評価に使うLLMの呼び出し回数でほぼ決まります。0.1.9とrefchecker 0.2.17のソースを読むと、全指標を計算するときの1問あたりの回数は次の式になります。照合は既定でクレームを5個ずつまとめて1回のプロンプトにする(joint_check_num=5)ためです。
- クレーム抽出:回答と正解で2回
- 照合:(取得チャンク数+1)×(正解のクレーム数÷5の切り上げ+回答のクレーム数÷5の切り上げ)回
取得チャンク5件、正解と回答のクレームが各10件なら、2+6×(2+2)=26回です。200問の評価セットなら5,200回になります。CLIの--disable_joint_checkでクレームを1個ずつ照合すると精度は少し上がりますが、同じ条件で1問122回、200問で24,400回に増えます。照合のたびにチャンク本文がプロンプトに入るので、入力トークンはチャンクが長いほど比例して増えます。
レート制限・APIエラー・タイムアウトに当たると、refcheckerは10秒待って上限なく再試行します。ログに[sleep 10 seconds]が並び続けたら止めて、バッチサイズを下げるかモデルの上限を見直してください。また、照合器にはtemperature=0、抽出器には1e-5を固定で送るため、temperatureの指定を受け付けないモデルはそのままでは使えません。custom_llm_api_func経由ならtemperatureは送られないので、自前の関数で呼べば回避できます。
導入前に確認する注意点と向かない場面
- 本体の保守が止まっている:RAGChecker本体の最終リリースは2024年9月25日、最終コミットは2024年12月13日です。transformers 4.50以降でimportが失敗する問題(Issue #34)は土台のrefchecker 0.2.15(2025年5月14日)以降で直り、現行の0.2.17(2025年5月16日)も対応済みですが、本体側のCLIの不具合や日本語出力の改善提案はオープンのまま残っています。依存をそろえ直すときは、refcheckerを0.2.15以降に上げてください。
- 日本語は保証外:論文のベンチマークは英語のみで、論文自身がLimitationsで言語の偏りを挙げています。公式FAQの回答は「多言語に強いLLMを抽出器・照合器に使えば動きうる」までです。日本語で使うなら、数十問を人手で採点してスコアの傾向が合うかを先に確かめます。
- スコアが実行ごとに揺れる:同じデータで実行するたびにスコアが変わるという報告があります(Issue #24)。小さな改善を比べるときは、同じ条件で複数回測って平均を見ます。
- 独自指標は足せない:公式FAQで、カスタム指標は未対応と明言されています。
- 矛盾と根拠なしを区別しない:照合結果の「矛盾」と「どちらとも言えない」を同じ誤りとして数える点も、論文のLimitationsに書かれています。
以上から、RAGCheckerを社内RAGの常時監視の土台にするのは勧めません。向いているのは、正解付きの評価セットを数百問用意できるチームが、チャンク設計や検索方式を変える前後で「検索と生成のどちらが悪いか」を一度きっちり測る場面です。正解データが無い、日本語の業務文書が中心、毎日CIで回したいという条件が重なるなら、RAGASやLLM-as-a-Judgeとは?評価プロンプトの書き方・3つのバイアス対策と人手との一致率の測り方で自前の評価を組む方が保守しやすくなります。評価の設計からRAGの作り込みまでまとめて任せたい場合は、一創のAIチャットボット開発でも相談を受け付けています。
よくある質問
RAGCheckerのGitHubリポジトリはどこですか?
github.com/amazon-science/RAGCheckerです。英語と中国語のチュートリアル、入力例のexamples/checking_inputs.json、メタ評価用データが含まれています。
日本語のRAGでも使えますか?
多言語に対応したLLMを抽出器と照合器に指定すれば実行はできますが、公式には保証されていません。論文のベンチマークも英語だけです。導入前に数十問を人手で採点し、RAGCheckerのスコアと傾向が一致するかを確かめてから使ってください。
正解データ(gt_answer)が無くても評価できますか?
計算できるのはfaithfulnessだけです。ほかの10指標は正解のクレームとの照合が必要です。ただし入力JSONのgt_answerキーは省略できない(省くとKeyErrorで止まる)ため、空文字""を入れたうえで、CLIなら--metrics faithfulness、Python APIならevaluate(rag_results, "faithfulness")を指定します。正解を用意できないなら、正解なしの指標が多いRAGASの方が向いています。
RAGChecker自体は無料ですか?
本体はApache-2.0のOSSで無料です。費用がかかるのは抽出器と照合器に使うLLMの利用料で、全指標なら1問あたり数十回の呼び出しになります。
ローカルLLMで動かせますか?
動かせます。vLLMなどOpenAI互換のサーバーを立て、CLIなら--extractor_name=openai/meta-llama/Llama-3.1-70B-Instructのようにopenai/を付けたモデル名と、--extractor_api_base・--checker_api_baseでサーバーのURLを指定するか、Python APIのcustom_llm_api_funcで自前の呼び出し関数を渡します。評価の精度は使うモデルの性能に左右され、論文ではLlama3-70Bを抽出器と照合器に使っています。