Contextual Retrieval
コンテキスト付き検索では、LLMが作成した、各チャンクのドキュメント内での位置を示す説明をチャンクの先頭に追加します。これにより、埋め込みとBM25で適切な箇所を検索できます。
コンテキスト検索は、検索拡張生成(RAG)のインデックス作成手法です。大規模言語モデル(LLM)が文書全体を読み、各チャンクが文書内のどこに位置するかを示す短い注記(通常50~100トークン)を作成します。チャンクを埋め込んでキーワードインデックスに追加する前に注記を先頭へ追加するため、チャンク単独では記述されていない情報も検索で照合できます。Anthropicは2024年9月にコンテキスト検索を発表しました。
解決する課題#
RAGパイプラインでは、埋め込みの精度を高め、モデルのコンテキストウィンドウに複数のチャンクを収めるため、文書を小さなチャンクに分割します。しかし、文書から切り出したチャンクでは、検索に必要な事実が失われることがよくあります。Anthropicが挙げた例は、財務報告書から抜き出した「同社の収益は前四半期比で3%増加しました。」というチャンクです。会社名も四半期も記されていないため、ACMEの2023年第2四半期の収益に関する質問とは、埋め込みでもキーワード検索でも照合できません。コンテキスト検索では、次のように保存します。「このチャンクはACME Corpの2023年第2四半期の業績に関するSEC提出書類の一部です。前四半期の収益は3億1,400万ドルでした。同社の収益は前四半期比で3%増加しました。」
オブジェクトのクロップも、テキストチャンクと同じように文脈を失います。Ultralyticsのオブジェクトクロッピングソリューションは、画像や動画にYOLO26を適用して検出ごとに個別ファイルとして保存します。ファイル名はcrop_1.jpg、crop_2.jpgなどとなるため、クロップにはトラックが写っていても、どのカメラ、現場、シーンで撮影されたかは分かりません。各クロップに、カメラ名、時刻、周囲で検出されたほかのオブジェクトなど、元フレームを説明する短い接頭辞を付けてインデックス化すると、キーワード検索とセマンティック検索で文脈を復元できます。
コンテキスト検索の仕組み#
各チャンクについて、LLMに文書全体とチャンクを渡し、「チャンクの検索精度向上を目的として、文書全体の中での位置付けを示す簡潔なコンテキストを記述してください」と指示します。Anthropicは、各文書を一度だけ処理してすべてのチャンクで再利用できるprompt cachingとClaude 3 Haikuを使用し、100万文書トークンあたり1.02ドルの一回限りのコストを示しました。コンテキスト付きのチャンクは、埋め込みインデックス(「コンテキスト付き埋め込み」)とBM25キーワードインデックス(「コンテキスト付きBM25」)に登録します。クエリ時には両方のインデックスを検索し、ハイブリッド検索と同様に結果を統合します。その後、リランカーが上位150件の候補を採点し、最良の20チャンクをプロンプトに含めます。
例のチャンクをコンテキストあり・なしで埋め込み、ベクトル検索への影響を確認します。
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
# Anthropic's example chunk and the context an LLM wrote for it from the full filing
chunk = "The company's revenue grew by 3% over the previous quarter."
context = "This chunk is from an SEC filing on ACME corp's performance in Q2 2023; the previous quarter's revenue was $314 million."
other = "Globex Corporation reported that Q2 2023 revenue fell 2% on weaker demand."
query = "How did ACME's revenue change in Q2 2023?"
candidates = {"plain chunk": chunk, "contextual chunk": f"{context} {chunk}", "Globex chunk": other}
# Cosine similarity of the query to each indexed text
scores = model.similarity(model.encode(query), model.encode(list(candidates.values())))[0]
for name, score in zip(candidates, scores):
print(f"{name}: {score:.2f}")コンテキストのないチャンクは質問とのスコアが0.49で、別の会社に関するチャンクと同じです。コンテキストを先頭に追加するとスコアは0.83になり、大差をつけて1位になります。
コンテキスト検索と関連技術の比較#
- Late chunking: 埋め込みモデルのアテンションを通じて各チャンクの埋め込みに文書のコンテキストを反映し、チャンクごとのLLM呼び出しは行いません。保存されたチャンクのテキストは変更されないため、キーワード検索の改善にはつながりません。
- Semantic chunking: チャンクの開始位置と終了位置を決めます。チャンクが明示していない情報を補うコンテキスト検索と組み合わせて使えます。
- タイトルと見出しのプレフィックス: 同じ文書タイトルやセクション見出しをすべてのチャンクの先頭に付ける、より安価で従来からある手法です。コンテキスト検索ではチャンクごとに異なる注記を作成します。
- コンテキストエンジニアリング: 推論時にモデルのコンテキストウィンドウへ何を含めるかを決める、より広範な取り組みです。コンテキスト検索はその1段階前、インデックス化する内容に作用します。
測定された効果#
Anthropicは、上位20件の結果から関連チャンクが欠落していたクエリの割合を示す1から再現率@20を、検索失敗率として測定しました。ベースラインのパイプラインでは、クエリの5.7%で失敗しました。コンテキスト埋め込みにより3.7%となり、35%減少しました。さらにコンテキストBM25を追加すると2.9%となり、49%減少しました。結果を組み合わせて再ランク付けすると失敗率は1.9%となり、ベースラインから67%減少しました。










