RAGの精度評価をRagasで自動化してみた 〜 いつまで「目視確認」で消耗してるの?
RAGの精度評価をRagasで自動化してみた:いつまで「目視確認」で消耗してるの?
はじめに:「なんとなく動く」からの脱却
RAG(Retrieval-Augmented Generation)アプリケーション開発における最大の敵は、開発者自身の「主観」です。
「いくつか質問してみたけど、いい感じに回答してくれている気がする」
「プロンプトを変えたら、なんとなく良くなった気がする」
PoC(概念実証)段階ではこれでも許されますが、プロダクション運用やチーム開発において「気がする」は通用しません。上司やクライアントからの「で、精度は何%なの?」という問いに、数字で答えられなければエンジニアとしての信頼に関わります。
そこで導入するのが、**「LLM-as-a-Judge(LLMを用いてLLMを評価する)」**フレームワークである Ragas です。この記事では、Ragasを用いてRAGの精度を定量的に計測し、CI/CDに組み込める状態を目指すための実装手順を解説します。
Ragasで計測する「4つの主要指標」
Ragasは多くのメトリクスを提供していますが、RAG評価において重要なのは以下の4つです。これらは「検索(Retrieval)」と「生成(Generation)」の質を切り分けて評価するために設計されています。
- Faithfulness(誠実さ)
- 生成の評価。回答が、検索してきたコンテキスト(情報源)に基づいているかを見ます。「ハルシネーション(もっともらしい嘘)」を検知するために使います。
- Answer Relevancy(回答の関連性)
- 生成の評価。ユーザーの質問に対して、的確で無駄のない回答になっているかを見ます。
- Context Precision(コンテキストの適合率)
- 検索の評価。検索結果の上位に、正解を導き出すために必要な情報(Ground Truthに関連する情報)が含まれているかを見ます。
- Context Recall(コンテキストの再現率)
- 検索の評価。正解(Ground Truth)を導き出すために必要な情報が、検索結果の中に漏れなく含まれているかを見ます。
実装:準備編(データセットの作成)
Ragasで評価を実行するには、以下の4つのデータを含んだデータセットが必要となります。
-
question: ユーザーの質問 -
answer: RAGシステムが生成した回答 -
contexts: 検索システムが取得してきたドキュメントのリスト(list[str]) -
ground_truth: 人間が用意した正解データ(strまたはlist[str])
実務では、ログから抽出した質問と回答に、人間が正解(Ground Truth)を付与したCSVなどを用意することが多いです。ここではPython辞書から構築する例を示します。
import pandas as pd
from datasets import Dataset
# 評価用データ
data = {
'question': [
'フランスの首都はどこですか?',
'量子コンピュータの主な方式は?'
],
'answer': [
'フランスの首都はパリです。',
'超伝導回路方式やイオントラップ方式などがあります。'
],
'contexts': [
['フランス共和国の首都はパリであり、同国最大の都市である。', 'パリはセーヌ川のほとりに位置する。'],
['量子コンピュータには、超伝導回路を用いる方式や、捕捉イオンを用いる方式などが研究されている。']
],
'ground_truth': [
'パリ',
'超伝導回路方式、イオントラップ方式'
]
}
# RagasはHuggingFaceのDataset形式を要求するため変換する
dataset = Dataset.from_dict(data)
print(dataset)
実装:評価実行編(Code)
データの準備ができたら、実際に評価を行います。まずはライブラリをインストールしましょう。
pip install ragas langchain openai
次に、OpenAIのAPIキーを設定し、評価を実行します。Ragasは内部でGPT-4(または指定したモデル)を呼び出し、データセットの内容を「採点」します。
import os
from ragas import evaluate
from ragas.metrics import (
faithfulness,
answer_relevancy,
context_precision,
context_recall,
)
# OpenAI APIキーの設定
os.environ["OPENAI_API_KEY"] = "sk-..."
# 評価の実行
# metrics引数に計測したい指標のリストを渡す
result = evaluate(
dataset=dataset,
metrics=[
faithfulness,
answer_relevancy,
context_precision,
context_recall,
],
)
print(f"Total Score: {result}")
結果の分析と可視化
result オブジェクトはPandas DataFrameに簡単に変換できます。これにより、どの質問でスコアが低かったかを分析できます。
# 結果をDataFrameに変換
df_result = result.to_pandas()
# スコアの確認(見やすくするため一部カラムを表示)
print(df_result[['question', 'faithfulness', 'context_recall']])
出力イメージ:
| question | faithfulness | context_recall |
|---|---|---|
| フランスの首都は... | 1.0 | 1.0 |
| 量子コンピュータの... | 0.5 | 1.0 |
スコアから読み取れること
-
Faithfulnessが低い:
検索したコンテキストに書いていないことを、LLMが勝手に(ハルシネーションで)答えている可能性があります。プロンプトで「コンテキストに基づかない場合は『わからない』と答えろ」と指示するなどの対策が必要です。 -
Context Recallが低い:
そもそも検索システムが必要なドキュメントを拾えていません。チャンク分割サイズの見直しや、Hybrid Search(キーワード検索 + ベクトル検索)の導入を検討しましょう。
おわりに:評価は「守り」の要
「自動評価」の環境構築は、地味ですが極めて重要です。
これがあって初めて、「プロンプトを変える」「検索ロジックを変える」といった改善作業を、デグレ(品質劣化)の恐怖に怯えることなく大胆に行えるようになります。評価は攻めるための守りの要です。
今回はRagasの基本的な導入と指標の見方に絞って解説しましたが、これを実運用でどう回していくかには、さらに深い設計が必要になります。
Ragasによる評価はGenAIOpsの入り口に過ぎません。この評価パイプラインをどう実際のプロダクト開発フローに組み込むか、そして「守りのAIエンジニア」から「攻めのAIエンジニア」になるためのキャリア戦略については、以下のブログ記事で深掘りしています。
Discussion