Context Recallをざっくり調査する

Context Recall(コンテキスト リコール)
雑な初感
関連ドキュメントがどれだけ正常に取得されたかを測定する?
数値が高いほど関連ドキュメントが多いとのことなので、割合が評価軸になりそう。

LLMContextRecall
LLMベースのContext Recall。
以下Claude3.7 Sonnetによる要約。
1. 使用するデータ
- ユーザーの質問(user_input)
- 参照回答(reference)- 理想的な回答
- 検索されたコンテキスト(retrieved_contexts)- RAGシステムが取得した情報
2. 測定方法
- 参照回答を複数の「主張」(claims)に分解
- 各主張について、検索されたコンテキストから、その主張を導き出せるかをLLMが判断
- 検索されたコンテキストから導き出せる主張の割合を計算
3. 目的:
- 参照回答を作成するために必要な情報がどれだけ検索コンテキストに含まれているかを評価
- 参照コンテキスト(reference_contexts)の代わりに参照回答(reference)を使うことで、評価の手間を削減
4. スコアの解釈:
- 0~1の範囲(高いほど良い)
- 1に近いほど、検索コンテキストが参照回答のすべての主張をサポートできることを意味する
これを元に実際に調査していく。

実際にやってみる
ドキュメント通りにやってみる。
from ragas.dataset_schema import SingleTurnSample
from ragas.metrics import LLMContextRecall
sample = SingleTurnSample(
user_input="Where is the Eiffel Tower located?",
response="The Eiffel Tower is located in Paris.",
reference="The Eiffel Tower is located in Paris.",
retrieved_contexts=["Paris is the capital of France."],
)
context_recall = LLMContextRecall(llm=evaluator_llm)
await context_recall.single_turn_ascore(sample)
ドキュメント通り、1.0
と表示された。
retrieved_contextsに不純物を入れてみる。
sample = SingleTurnSample(
user_input="Where is the Eiffel Tower located?",
response="The Eiffel Tower is located in Paris.",
reference="The Eiffel Tower is located in Paris.",
retrieved_contexts=[
"Paris is the capital of France.",
"東京は日本の首都です。",
"アメリカはメキシコと接しています。",
"苑田です。",
],
)
context_recall = LLMContextRecall(llm=evaluator_llm)
res = await context_recall.single_turn_ascore(sample)
スコアは1.0
だった。理由としては、referenceを生成するのにretrieved_contextsで十分であるため1.0
になったと考えられる。
なので、referenceをもう少し詳細に記載した場合、点数が下がるかを検証する。
sample = SingleTurnSample(
user_input="Where is the Eiffel Tower located?",
response="The Eiffel Tower is located in Paris.",
reference="The Eiffel Tower is located in Paris and was built in 1889.", # もっと詳細に記載
retrieved_contexts=[
"Paris is the capital of France.",
"東京は日本の首都です。",
"アメリカはメキシコと接しています。",
"苑田です。",
],
)
スコアは0.5
になった。「パリにある」という主張はサポートされているが、「1889年に建てられた」という主張はサポートされていない。
したがって、このretrieved_contextsでreferenceうまく生成できないを意味する。

NonLLMContextRecall
LLMを使用せずにContextRecallを行う。
検索されたコンテキスト(retrieved_contexts)が参照コンテキスト(reference_contexts)の情報をどの程度カバーしているかを測定。
以下Claude3.7 Sonnetによる要約。
1. 使用するデータ
- 検索されたコンテキスト(retrieved_contexts)- RAGシステムが取得した文脈情報
- 参照コンテキスト(reference_contexts)- 理想的な文脈情報(手動で用意された正解コンテキスト)
2. 評価方法
- LLMを使わず、文字列比較などの非LLMベースの類似度測定を使用
- 各参照コンテキストについて、検索されたコンテキストの中に十分に類似したものがあるかを判断
- カバーされている参照コンテキストの割合を計算
3. 値の範囲:
- 0~1の範囲(高いほど良い)
- 1に近いほど、検索されたコンテキストが参照コンテキストの情報を完全にカバーしていることを意味する
これを元に調査していく。

実際にやってみる
ドキュメント通りにやってみる。
sample = SingleTurnSample(
retrieved_contexts=["Paris is the capital of France."],
reference_contexts=["Paris is the capital of France.", "The Eiffel Tower is one of the most famous landmarks in Paris."]
)
context_recall = NonLLMContextRecall()
res = await context_recall.single_turn_ascore(sample)
print(res)
スコアは0.5
であった。
全然関係ないreference_contextsを増やしてみた。
sample = SingleTurnSample(
retrieved_contexts=["Paris is the capital of France."],
reference_contexts=[
"Paris is the capital of France",
"The Eiffel Tower is one of the most famous landmarks in Paris.",
"東京は日本の首都です。",
"アメリカはメキシコと接しています。",
"苑田です。",
]
)
スコアは0.2
だったので、5個のreference_contextsから有益なreference_contextは1つだけなので0.2となる。

結論
Context Recallはreferenceを生成するのにretrieved_contextsがどれくらい有益かを判断する指標っぽい。
retrieved_contextsを大量に入れてる場合、referenceを生成する上で必要な情報は確保できるので、スコアは上がりそうな気がする。しかし、RAGとして不要なデータをプロンプトに入れることになるので、料金やLLMの精度(モデルがきちんと文脈を理解するか)に直結しそう。
逆にretrieved_contextsを3つとかに減らすと、referenceに必要な情報が不足しているので、スコアが下がりそう。
どちらにせよ一長一短あるので、個人的に重要な評価要素だと感じた。