RAGの検索精度が劇的改善!「Reranking(リランク)」導入のススメ
はじめに
RAGシステムからの回答が「惜しいけどちょっと違う」「関係ない情報が混ざってる」こと、ありませんか?
これは、最初の検索フェーズ(ベクトル検索)で拾ってきたドキュメントに関連性が低いものが混ざっていることが原因です。この問題を解決する特効薬が「Reranking(リランク)」です。
2段階検索(Two-Stage Retrieval)とは
1. まず広めに関連しそうな文書を50件くらい集める(高速なベクトル検索)。
2. その50件を「本当に質問と関係あるか?」という視点で精密検査して、上位5件に絞る(高精度なリランク)。
この2段構えの構成にすることで、速度と精度のいいとこ取りができます。
なぜベクトル検索だけでは不十分なのか
ベクトル検索(Bi-Encoder)は、文章全体を1つのベクトルに圧縮するため、詳細なニュアンスや数値の違いなどが失われがちです。「2024年の売上」を聞いているのに「2023年の売上」の文書がヒットしてしまうのはこのためです。
Cross Encoderによる並び替え
リランクには「Cross Encoder」というモデルを使います。これは、質問と文書をペアにしてモデルに入力し、直接「関連度スコア」を算出します。
計算コストが高いため全文書に対して行うことはできませんが、絞り込んだ後の数十件に対してなら一瞬で終わります。
実装例(Cohere Rerank)
LangChainでは、ContextualCompressionRetriever
を使うことで既存のRetrieverにリランク機能を後付けできます。Cohere社のAPIが有名です。
from langchain.retrievers import ContextualCompressionRetriever
from langchain_cohere import CohereRerank
# ベースとなる検索機
base_retriever = vectorstore.as_retriever(search_kwargs={"k": 20})
# リランカーの設定
compressor = CohereRerank()
compression_retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=base_retriever
)
# これまで通り使うだけ
docs = compression_retriever.invoke("第3四半期の利益は?")
これだけで、検索上位に関連性の低いゴミが混ざる確率が激減します。
まとめ
RAGの精度に悩んだら、プロンプトをいじる前にRerankingの導入を検討してください。コストパフォーマンスが最も高い改善策の一つです。
次回は、RAGシステム自体の品質を自動テスト・評価するためのフレームワーク「Ragas」について解説します。
コメント
コメントを投稿