**検索拡張生成(RAG)**は、システムが外部の文書インデックスから関連する文章を検索し、回答を生成する前にその文章を言語モデルへ渡す手法です。モデルは、学習時に固定された重みだけに頼らず、非公開情報、社内情報、最近更新された情報を使って回答できます。
通常の言語モデルが知っているのは、知識の締め切り日までの学習データに含まれる内容だけです。ユーザーが自社の社内返金ポリシー、新しく公開されたAPI仕様、五分前に更新されたアカウント記録について質問しても、基盤モデルは記憶だけから答えを知ることはできません。RAGは検索と生成を組み合わせ、まず関連する事実を取得し、その文章に基づいて回答を生成することで、この隔たりを埋めます。
検索拡張生成とは何か?
検索拡張生成とは、情報検索システムとテキスト生成モデルを組み合わせ、問い合わせ時に取得した外部文書を出力に反映させることです。ニューラルネットワークがすべての事実をパラメータに記憶することを期待する代わりに、RAGは外部テキストのインデックスを、モデルが回答前に参照できる本のように扱います。
大まかに言うと、すべてのRAGワークフローには次の二つの基本段階があります。
- 検索: ユーザーがプロンプトを送信すると、システムはその問い合わせを外部データストアへの検索要求に変換します。データストアにはベクトルデータベース、キーワード検索インデックス、または両者のハイブリッドなどがあり、最も関連性の高い文章を取得します。
- 生成: システムは取得した文章をユーザーの元の質問とともにモデルのコンテキストに挿入し、言語モデルが提示された文章に基づいて回答を生成します。
参照テキストはリクエストごとに動的に取得されるため、基盤モデルを再学習せずに、文書インデックスを更新するだけでシステムの知識を更新できます。そのためRAGは、サポートアシスタント、社内文書検索、専門分野の質問応答ツールを構築する際の標準的な手法の一つです。また、メディア制作にはAI Studio Videoのような専用ワークフローツールを使い、知識の検索にはテキストAPIを利用する創作アプリケーションでも使われます。
2020年のRAG論文は現在のRAG手法とどう違う?
「検索拡張生成」という用語は、Patrick Lewisらによる2020年の論文(arXiv:2005.11401)に由来します。この論文は事前学習済みの系列変換モデルとWikipediaの密ベクトルインデックスを組み合わせましたが、現在の開発者は通常、より単純なプロンプト構築パイプラインを指してこの言葉を使います。両方を理解すると、研究論文と技術文書で「RAG」の説明が少し異なる理由がわかります。
2020年のLewisらのアーキテクチャ
元の2020年の論文と、それに付随するMeta AIの研究記事で、著者らは言語モデルには二種類の記憶があると捉えました。
- パラメトリックメモリ: ニューラルネットワークの重みに保存された知識。具体的には、事前学習済みのBART系列変換モデルです。
- ノンパラメトリックメモリ: Wikipedia記事の外部密ベクトルインデックスに保存された知識。Dense Passage Retrieval(DPR)というニューラル検索器で検索します。
この研究では、検索器と生成器がエンドツーエンドで共同学習されました。論文は、検索された文章が生成に影響する仕組みとして二つの定式化を紹介しています。
- RAG-Sequence: モデルは同じ取得文章を使って出力系列全体を生成します。
- RAG-Token: モデルは生成するトークンごとに異なる取得文章を参照できます。
論文の表に記載されたオープンドメイン質問応答のベンチマーク(arXiv:2005.11401)では、RAG-SequenceはNatural Questionsで44.5 Exact Matchを達成し、研究で検証されたパラメトリック方式のみのseq2seqベースラインと検索・抽出型アーキテクチャの両方を上回りました。
現在の実装パターン
現在のアプリケーション開発では、検索器と生成器を共同学習することはまれです。代わりに「RAG」はほぼ常に、市販の埋め込みモデルと汎用LLM APIを中心に構築された推論時のパイプラインを指します。
- 文書を小さな文章単位(チャンク)に分割する。
- チャンクをベクトル埋め込みに変換し、インデックスに保存する。
- 問い合わせ時に、最も一致するチャンクを取得する。
- 必要に応じて結果を再順位付けし、関連性を高める。
- 取得したテキストチャンクをプロンプトに直接詰め込み、LLMに回答を求める。
2020年のエンドツーエンドのニューラルアーキテクチャも、現在のプロンプトに文章を詰め込むパイプラインもRAGと呼ばれます。日常のソフトウェア開発では、検索器とseq2seqモデルの学習に明示的に言及しない限り、現在のパイプラインを意味します。
現代のRAGパイプラインはどのように動く?
本番環境のRAGシステムは、処理を二つの独立したワークフローに分けます。文書を準備してインデックス化するオフラインの取り込みパイプラインと、ユーザーが質問するたびに実行されるオンラインの問い合わせパイプラインです。AWSの検索拡張生成ガイダンスやAWS Generative AI Innovation CenterのRAGガイドなどのアーキテクチャガイドでは、これらの段階を個別に調整できる構成要素に分解しています。
1. 取り込みパイプライン(データのインデックス化)
ユーザーがプロンプトを送信する前に、システムは元の文書を検索可能にする必要があります。
- 文書の読み込みとクレンジング: PDF、Wiki、データベース、Markdownファイルからプレーンテキストとメタデータ(タイトル、URL、タイムスタンプ、アクセス権限)を抽出し、崩れた書式や定型的なページ要素を取り除きます。
- チャンク分割: 長い文書を小さな区間に分け、マニュアル全体ではなく関連する文章だけを取得できるようにします。チャンクが小さすぎると周囲の文脈が失われ、内容が途中で切れます。大きすぎると無関係な情報が混ざり、トークン使用量が増えます。境界の文の意味が失われないよう、隣接するチャンクを少し重複させることがよくあります。
- 埋め込み: 各チャンクを埋め込みモデルに通し、テキストを意味を表す密な数値ベクトルに変換します。
- インデックス化: ベクトルを生のテキストやメタデータフィルターとともに、ベクトルデータベースまたはベクトル類似度とキーワード照合を組み合わせたハイブリッド検索エンジン(BM25など)に保存します。
2. 問い合わせパイプライン(質問への回答)
実行時にユーザーが質問すると、問い合わせパイプラインがプロンプトを組み立てます。
- 問い合わせの処理と埋め込み: ユーザーの入力を受け取り、必要に応じて明確になるよう書き換えたり拡張したりして、取り込み時とまったく同じ埋め込みモデルでベクトルに変換します。
- 検索: 問い合わせベクトルに最も近いベクトルを持つチャンクをインデックスから検索します。多くの場合、意味検索、キーワード照合、メタデータによるフィルタリングを組み合わせます。例えば、現在のユーザーに閲覧権限がある文書に結果を限定します。
- 任意の再順位付け: 初期候補のチャンクをクロスエンコーダー型の再順位付けモデルに通します。このモデルは各文章がその質問にどれだけ直接答えているかを評価し、最も適した候補に絞ります。
- プロンプトの組み立てと生成: 上位の文章をユーザーの質問とともに構造化されたプロンプトテンプレートに挿入し、まとめてLLMに送信して、生成された回答を返します。多くの場合、ソースのメタデータを示す引用も含まれます。
RAGと長いコンテキストウィンドウ、ファインチューニングの違いは?
RAG、長いコンテキストウィンドウ、ファインチューニングは、モデルのカスタマイズにおける異なる課題を解決します。本番システムでは、互いに排他的な選択肢として扱うよりも、組み合わせることがよくあります。適切な方法は、変化する事実、一回のセッションでの幅広い理解、モデルの振る舞いの変更のどれが必要かによって異なります。
| 比較項目 | 検索拡張生成(RAG) | 長いコンテキストウィンドウ | ファインチューニング |
|---|---|---|---|
| 主な目的 | 大規模または変化する文書群から問い合わせごとに関連する事実を提供する | 一回のリクエストで大量のテキストをモデルに読ませる | モデルの文体、語調、書式、専門タスクでの振る舞いを変える |
| 知識の更新方法 | 外部インデックスの文書を更新または差し替える | プロンプトに貼り付ける元文書を差し替える | 新たな学習例を集め、再び学習を実行する |
| リクエストごとのトークンへの影響 | 低〜中程度(取得したチャンクだけを送信) | 高い(すべての文書がプロンプトに残る) | 低い(知識や振る舞いがモデルの重みに組み込まれる) |
| 出典の明示 | 取得した特定のチャンクを容易に引用できる | 可能だが、大量の入力から特定するのは難しい | 難しい。重みは明示的な文書の引用を保持しない |
| アクセス制御 | インデックスのメタデータフィルターで問い合わせごとに適用 | プロンプトを組み立てる前にフィルタリングが必要 | 分離が難しく、重みの内容はどのユーザーにも漏れる可能性がある |
RAGと長いコンテキストウィンドウ
現代のモデルは大きなコンテキストウィンドウに対応しているため、検索を省いて知識ベース全体を毎回プロンプトに貼り付けたくなるかもしれません。短い文書が数件なら、それでも問題なく動きます。特にプロンプトキャッシュと、すでに内容が入ったKV cacheを組み合わせれば、繰り返される接頭部分を最初から再処理せずに済みます。
しかし、文書群が数千ファイルに増えると、すべてをプロンプトに入れる方法は二つの壁に直面します。
- コストと遅延: 毎回巨大なプロンプトを送るとAPI費用と最初のトークンが出るまでの時間が増えます。そのため、AI APIのコスト削減を考える際、選択的な検索は中心的な戦略の一つです。
- 注意力の低下: モデルは巨大なプロンプトのすべての部分に等しく注意を払えるわけではありません。無関係なテキストがウィンドウに増えると、精度が下がることがよくあります。これはコンテキスト劣化と呼ばれる現象です。RAGは現在の質問に重要な文章だけを取得し、プロンプトの焦点を保ちます。
RAGとファインチューニング
ファインチューニングは、選別された例を使ってモデルの重みを更新します。厳密な出力スキーマに従わせたい場合、特定のブランドの語調を採用させたい場合、専門分野の構文を学ばせたい場合に有効です。一方、急速に変化する事実をモデルに教える方法としては適していません。
2020年のLewisらの論文(arXiv:2005.11401)は、インデックスの「ホットスワップ」実験によって、変化する事実にノンパラメトリックメモリが重要な理由を示しました。著者らは、2016年十二月のWikipediaダンプと2018年十二月のWikipediaダンプを使い、その期間に交代した世界の指導者に関する質問でモデルをテストしました。
- 質問の年とインデックスの年が一致した場合、モデルは2016年のインデックスで2016年の指導者に関する質問の70%、2018年のインデックスで2018年の指導者に関する質問の**68%**に正解しました。
- インデックスが質問と一致しない場合、精度は12%(2018年のインデックスで2016年の指導者について質問)と4%(2016年のインデックスで2018年の指導者について質問)に低下しました。
外部インデックスを置き換えるだけで、モデルの重みを一つも再学習せずに、システムが持つ世界の事実に関する知識を更新できました。
RAGはどこで失敗する?
言語モデルに検索を加えると、非公開の話題や最近の話題についての推測は減りますが、AIのハルシネーションをなくしたり、正確な回答を保証したりすることはできません。RAGシステムには複数の構成要素があるため、検索段階でも生成段階でも失敗が起こり得ます。
- 検索漏れ: ユーザーが元文書と異なる用語で質問した場合や、チャンク分割で表と見出しが分離された場合、検索器が実際に答えを含む文章を見つけられないことがあります。正しいチャンクがプロンプトに届かなければ、モデルは手がかりなしに回答することになります。
- ノイズの多い文書や古い文書: インデックスの品質は保存されたファイルに左右されます。知識ベースに2023年版と2026年版のオンボーディングガイドがあり、廃止された版を明確に除外していなければ、検索器は古い手順をモデルに渡してしまいます。
- 過剰な検索: 「念のため」に25個のチャンクを取得すると、裏目に出ることがよくあります。関連性の低い文章をプロンプトに詰め込むと、本来の答えが埋もれ、遅延が増え、紛らわしい詳細にモデルが気を取られるコンテキスト劣化が起こる場合があります。
- 取得テキストを介した間接的なプロンプトインジェクション: インデックスが受信メール、公開ウェブページ、ユーザーが送信したチケットなど、信頼できない外部コンテンツを取り込む場合、攻撃者が文書内に悪意ある指示を仕込む可能性があります。その文書が検索されてプロンプトに入ると、モデルの振る舞いを乗っ取るプロンプトインジェクション攻撃が発生する場合があります。
- モデルによるコンテキストの無視や誤読: まさに正しい文章がプロンプトに入っていても、生成器は否定を誤解したり、別々の二つのチャンクを不正確に混ぜたり、取得文章が一般的な知識に反するときに事前学習で得た先入知識を提示テキストより優先したりすることがあります。
信頼できるRAGシステムを構築するためのチェックリスト
RAGの試作品を本番環境に移す際には、いくつかの規律ある開発上の習慣によって、よくある失敗を防げます。
- インデックスを最新に保ち、重複を除く: 削除された文書の除去、置き換えられた版のアーカイブ、各インデックス済みチャンクへの明確なタイムスタンプとソースURLの付与を行う自動パイプラインを構築します。
- 検索量を減らし、質を高める: 関連性の低い結果を何十件もプロンプトに詰め込む代わりに、ハイブリッド検索(ベクトル+キーワード)をメタデータフィルターと再順位付けモデルに組み合わせ、有益な少数の文章だけを生成器に渡します。
- 信頼できない取得テキストをシステム指示から明確に分離する: 取得したチャンクをXMLタグやラベル付き文書ブロックなどの明示的な構造区切りで囲み、それらを実行可能な命令ではなく、あくまで受動的な参照データとして扱うようシステムプロンプトで指示します。
- コンテキストがない場合は回答を控えるようモデルに指示する: 提供された文章に回答するための情報が十分にない場合は、その旨を明確に述べるよう指示します。プロンプトの指示はモデルが常に従うことを保証しませんが、検索が空振りした際に黙って推測するより明確な代替行動を示せます。
よくある質問
RAGには常にベクトルデータベースが必要ですか?
いいえ。検索拡張生成に必要なのは、モデルを呼び出す前に関連テキストを取得する方法だけです。意味的な類似性の検索にはベクトルデータベースがよく使われますが、多くの本番RAGシステムは従来のキーワード検索エンジン(ElasticsearchのBM25やPostgreSQLの全文検索など)、またはキーワード照合とベクトル照合を組み合わせたハイブリッド検索を使っています。
RAGはLLMのハルシネーションを完全に防げますか?
いいえ。RAGは参照テキストをプロンプトで直接モデルに渡すため、学習データの欠落や古さによるハルシネーションを減らします。しかし、モデルが文章を誤読したり、無関係な二つのチャンクの事実を誤って組み合わせたり、検索器が無関係な文書を取得した際に答えを推測したりする可能性はあります。
社内文書にはRAGとファインチューニングのどちらを使うべきですか?
時間とともに変わる社内文書についてモデルに質問へ答えさせたい場合は、RAGから始めましょう。RAGではインデックス内のファイルをすぐに追加、編集、削除でき、問い合わせ時にユーザーごとのアクセス権限を適用できます。一方、ファインチューニングは、一貫した書式、語調、タスクの進め方を学習させるのに適しています。
出典
- Patrick Lewis et al., Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks — arXiv:2005.11401
- Meta AI Research Blog — Retrieval-Augmented Generation: Streamlining the creation of intelligent natural language processing models
- AWS Prescriptive Guidance — Understanding LLMs and RAG
- AWS Machine Learning Blog — From RAG to fabric: Lessons learned from building real-world RAGs at GenAIIC – Part 1


