RAG と知識検索
RAG(Retrieval-Augmented Generation、検索拡張生成)は、現在最も主流な LLM 実装アーキテクチャの一つです。
RAG の核となる考え方は:LLM が質問に答える際、まず外部知識ベースから関連内容を検索し、その検索結果に基づいて回答を生成させるのであって、モデルがトレーニング時に記憶した知識だけに依存するのではありません。
これにより、LLM の二つの核心的な課題が解決されます:知識のカットオフ日(モデルはトレーニング後に起きたことを知らない)と幻覚問題(モデルが不確かなときに答えをでっち上げること)です。
RAGの基本原理
完全な RAG システムは、2つのパイプラインで構成されます:オフライン索引パイプライン(ドキュメントを前処理してベクトルデータベースに格納する)とオンライン検索パイプライン(ユーザーの質問を受け取り、検索し、生成する)。
オフライン段階では、元のドキュメントを小さなチャンクに分割し、Embedding モデルでベクトルに変換して、ベクトルデータベースに格納します。
オンライン段階では、ユーザーの質問も同様にベクトルに変換し、データベースから最も類似したドキュメントチャンクを見つけ、コンテキストとして連結して LLM に渡し、回答を生成させます。
次の図は RAG の完全なリクエストフローを示しています:
データ前処理とドキュメント分割(Chunking)
前段の課題:複雑なドキュメント解析
分割を行う前に、RAG はしばしば直面するのはフォーマット解析という課題です。特に PDF、Word、スキャン文書内の表、画像、多段組みでは、通常のテキスト抽出では意味が大きく乱れやすくなります。
現在、業界の主流な解決策は、ドキュメント解析エンジン(LlamaParse、Unstructured など)またはマルチモーダル大規模モデルを導入し、複雑な画像やテキストを構造化された Markdown に変換して、後続の高品質な分割の基盤を築くことです。
ドキュメント分割戦略
ドキュメント分割は RAG の効果の基盤であり、分割の粒度は検索品質に直接影響します。チャンクが大きすぎるとノイズが入り、小さすぎるとコンテキストが失われます。一般的な戦略は以下の通りです:
| 分割戦略 | 適用シーン | 長所 | 短所 |
|---|---|---|---|
| 固定サイズ分割 | 一般的なテキスト | 実装が簡単、高速 | 意味的に完全な文を途中で切る可能性がある |
| 再帰的文字分割 | 構造化テキスト(Markdown、コード) | 段落や文などの意味的な境界を優先して分割 | 実装がやや複雑で、適切な区切り文字リストの設定が必要 |
| セマンティック分割(Semantic) | 長文ドキュメント、書籍 | Embedding を用いて隣接文の類似度を計算し、意味の転換点を自動的に見つけて分割 | 計算コストが高く、前処理速度が遅い |
| 親子ドキュメント検索 (Small-to-Big) |
あらゆるシーンをカバー | 「小さなチャンク」で高精度なベクトル検索を行い、ヒット後に対応する「大きなチャンク」(親ドキュメント)を LLM に返すことで、検索精度とコンテキストの完全性を両立します。 | データベースの設計・保守コストが2倍になる |
実践では、分割時にオーバーラップ(overlap)を加えることがよくあります。つまり、隣接するチャンク間でいくつかの文字を共有させ、重要な情報が境界で途切れるのを防ぎます。典型的な設定:チャンクサイズ 512 tokens、オーバーラップ 50〜100 tokens。
実例:LangChain を使った再帰的分割
splitter = RecursiveCharacterTextSplitter(
chunk_size=512, # 各チャンクの最大トークン数
chunk_overlap=50, # 隣接チャンクのオーバーラップトークン数。境界で情報が失われるのを防ぐ
separators=["\n\n", "\n", "。", ".", " ", ""] # 段落や文を優先して分割
)
chunks = splitter.split_text(document_text)
print(f"{len(chunks)} 個のドキュメントチャンクに分割しました")
ベクトル検索
Embedding モデル
Embedding モデルは、テキストを稠密ベクトル(通常は 768 次元または 1536 次元の浮動小数点数配列)に変換する役割を持ちます。意味的に近いテキストはベクトル空間内で距離が近くなり、これが類似度検索の数学的基盤です。
一般的な Embedding モデルの比較:
| モデル | 次元 | 対応言語 | 特徴 |
|---|---|---|---|
text-embedding-3-small(OpenAI) |
1536 | 多言語 | コストパフォーマンスが高く、大規模な索引に適している |
text-embedding-3-large(OpenAI) |
3072 | 多言語 | 精度が最も高く、コストが比較的高い |
BAAI/bge-m3 |
1024 | 中国語と英語 | オープンソース、中国語の性能が優秀、多言語対応 |
sentence-transformers/all-MiniLM-L6-v2 |
384 | 英語 | サイズが小さく、高速、ローカルでの超軽量デプロイに適している |
類似度計算と ANN アルゴリズム
検索の核心は距離の測定です。最も一般的に使われるのはコサイン類似度(Cosine Similarity)、これは2つのベクトルのなす角のコサイン値を計算し、値域は [-1, 1] で、1 に近いほど類似しています。他にもドット積(Dot Product)やユークリッド距離(L2 Distance)があります。
100万レベルのベクトルでミリ秒単位の検索を実現するため、データベースは通常近似最近傍(ANN)アルゴリズム(例:HNSWHNSW、IVF)。HNSW は現在最も主流なアルゴリズムで、多層スキップグラフネットワークを構築することで、わずかな精度を犠牲にして桁違いの検索速度向上を実現します。
Advanced RAG(高度なアーキテクチャ)
基本アーキテクチャ(Naive RAG)は、検索の不正確さや冗長な情報が多いことによる「コンテキストの埋没」などの問題に直面することがよくあります。Advanced RAG は、検索前最適化 → 検索融合 → 検索後最適化という三段階のアーキテクチャでこれを解決します。
1、検索前処理:クエリ最適化
ユーザーの元の質問は、表現が十分に正確でないことがよくあります:
- クエリ書き換え(Query Rewriting):LLM を使って口語的な質問を規範化された検索語に書き換えます。
- HyDE(Hypothetical Document Embedding):LLM にまず「当て推量」で仮の回答を生成させます。生成された回答は通常、元の質問よりも多くの業界用語を含むため、この仮回答のベクトルを使って検索すると、より高品質なドキュメントを再取得できることが多いです。
2、ハイブリッド検索(Hybrid Search)
将ベクトル検索(意味を理解し、エラー耐性が高い)とキーワード検索(BM25、マッチング精度が高い)の結果を重み付けで融合します。これは固有名詞、製品型番、コード断片を扱う際に特に重要です。従来のベクトル検索は特定の固有名詞で「失敗」しやすいからです。
3、検索後最適化:リランキング(Reranking)
これは粗いランキング → 精密なランキングという二段階設計です。ベクトル検索は高速ですが、スコアリングが十分に正確ではありません。リランキング(Reranking)では、Cross-Encoder モデルを導入します。(例:`bge-reranker`)、「質問」と「ドキュメント」をペアでモデルに入力し、共同推論でスコアリングを行います。計算量が大きいため、Top-20 から Top-5 への精選のみを担当します。
実例:リランキング処理の擬似コード
reranker = CrossEncoder("BAAI/bge-reranker-v2-m3")
# 1. 粗選別:ベクトル検索で超高速に Top-50 をリコール
candidates = vector_store.similarity_search(query, k=50)
# 2. 精選:「問題、ドキュメント」のペアを構築して正確にスコアリング
pairs = [[query, doc.page_content] for doc in candidates]
scores = reranker.predict(pairs)
# 3. 最終的に LLM に渡す Top-5 をフィルタリング
ranked_docs = sorted(zip(scores, candidates), reverse=True)
final_docs = [doc for _, doc in ranked_docs[:5]]
4、Self-RAG と CRAG(修正型 RAG)
自己反省メカニズムを追加します。例えば CRAG(Corrective RAG)は、検索結果を取得した後、まず LLM が「審査員」としてスコアリングします。ローカル知識ベースに対象の文書が存在しない、または品質が極めて低い場合、システムは自動的に Web Search(Google API など)をトリガーして補完し、幻覚(ハルシネーション)を大幅に低減します。
GraphRAG:知識グラフ + 検索融合
従来の RAG は知識ベースを独立したテキスト断片として扱うため、「現 CEO が創業し、かつ時価総額が千億を超える企業をすべて見つける」のような、ドキュメント横断・多段階推論(マルチホップ推論)を必要とする複雑な問題には答えられません。GraphRAG知識グラフ(Knowledge Graph)を導入し、エンティティと関係を明示的にモデル化します。
GraphRAG の中核ステップ
- 知識構築:オフライン段階で LLM を使用してドキュメントからトリプル(主語、述語、目的語)を抽出し、Neo4j などのグラフデータベースに書き込みます。
- 二経路検索:質問内のエンティティに対して、従来のベクトル検索を行うだけでなく、グラフ内でグラフトラバーサル(Graph Traversal)をトリガーし、多段階の関係チェーンを抽出します。
- テキストとグラフの融合生成:ベクトル検索で取得した「断片」とグラフ検索で取得した「パス構造」を Prompt に組み込むことで、LLM がグローバルな視点と具体的な詳細の両方を備えるようにします。
GraphRAG 参考コンテンツ:https://www.example.com/ai-agent/graphrag-usage.html
技術とデータベース選定の推奨
| データベース/ツールの選定 | タイプ | 推奨される導入シナリオ |
|---|---|---|
| Pinecone / Zilliz Cloud | フルマネージドクラウドサービス | すぐに使え、インフラを維持管理する必要がありません。Cohere Rerank + GPT-4o と組み合わせるのが最速で商用化できる方法です。 |
| Qdrant | オープンソース + マネージド | Rust で記述されており、メモリ管理に優れ、性能が極めて高い。エンタープライズ向けのプライベートデプロイに適しています。 |
| Weaviate / Elasticsearch | オープンソース + マネージド | 非常に成熟した BM25 + ベクトルハイブリッド検索(Hybrid Search)を内蔵しており、固有名詞が多いシナリオで最優先の選択肢です。 |
| Milvus | オープンソース分散型 | 10億〜100億レベルの超大規模エンタープライズ検索プラットフォームに適しています。 |
| Chroma / FAISS | ローカルライブラリ/組み込み型 | 非常に軽量で、独立したサービスのデプロイが不要。ローカル開発や個人知識ベースプロジェクトの検証に非常に適しています。 |
RAG 評価指標(RAGAS フレームワーク)
RAG システムの評価は直感だけに頼ることはできず、主流ではRAGASフレームワークを使用し、「検索」と「生成」の 2 つの側面から自動化された定量的テストを行います:
- Context Recall(検索リコール率):正解中の情報がどの程度の割合で検索できるか。
- Context Precision(検索適合率):検索されたドキュメントのうち、どの程度の割合が実際に関連しているか。
- Faithfulness(忠実度/幻覚指標):生成された回答が、検索されたドキュメントによってすべて裏付けられているか。
- Answer Relevance(回答関連性):生成された回答がユーザーの質問に本当に答えているか。的外れな回答を避ける。