第19章. RAG / embedding / vector DB
この章の目的
この章では、大規模言語モデル(LLM)が単体では解決できない情報検索や最新情報の利用といった課題を克服するための周辺技術について学びます。特に、外部知識をLLMに提供する「Retrieval-Augmented Generation (RAG)」の概念と、それを支える主要なコンポーネントである「embedding」「vector DB」「reranker」などを深く理解することを目的とします。
この章で覚えるべきこと
- RAGがLLMの限界をどのように補うのか
- embeddingがテキスト情報をどのように数値化し、意味を捉えるのか
- vector DBがembeddingを効率的に保存・検索する仕組み
- chunking、retrieval、rerankerがRAGパイプラインで果たす役割
- hybrid searchが検索精度を向上させる方法
導入
LLMは驚くべき能力を持っていますが、いくつかの制約も抱えています。例えば、学習データに含まれない最新の情報や、特定の企業内部のドキュメントについては回答できません。また、学習データに偏りがある場合、誤った情報を生成する「ハルシネーション」と呼ばれる現象も発生します。
これらの課題を解決し、LLMの能力を最大限に活用するための強力なアプローチが「Retrieval-Augmented Generation (RAG)」です。RAGは、LLMが回答を生成する前に、関連する情報を外部の知識ベースから検索(Retrieval)し、その情報を参照しながら回答を生成(Generation)する手法です。これにより、LLMは最新かつ正確な情報に基づいた、より信頼性の高い回答を提供できるようになります。
本章では、RAGの全体像を理解し、その中核をなす技術であるembedding、vector DB、そして検索精度を高めるためのrerankerやhybrid searchといった要素について詳しく見ていきます。
基本概念
RAG (Retrieval-Augmented Generation)
ひとことで言うと: LLMが外部の知識を参照して回答を生成するフレームワーク。 何のカテゴリか: LLMアプリケーションアーキテクチャ、情報検索と生成の融合。 何に使うのか: LLMのハルシネーション抑制、最新情報や専門知識の利用、情報源の提示。 代表例: 企業内ドキュメントからのQ&Aシステム、最新ニュースに基づく要約。 よく混同される用語: SFT (Supervised Fine-Tuning) 初心者向け注意点: RAGはLLM自体を学習し直すものではなく、LLMに与えるプロンプトに外部情報を追加する手法です。
RAGは、LLMの知識を拡張し、より正確で信頼性の高い応答を生成するための強力なパラダイムです。従来のLLMは、学習データに含まれる情報のみに基づいて応答を生成するため、学習データにない情報や最新の出来事については回答できませんでした。また、学習データに誤りや偏りがある場合、ハルシネーション(事実に基づかない情報を生成すること)を引き起こす可能性もありました。
RAGは、この問題を解決するために、以下の2つの主要なステップを組み合わせています。
- Retrieval (検索): ユーザーの質問やプロンプトに関連する情報を、外部の知識ベース(ドキュメント、データベース、ウェブなど)から検索します。このステップでは、質問と知識ベース内の情報を比較し、最も関連性の高い情報を特定します。
- Augmentation & Generation (拡張と生成): 検索された情報をLLMへのプロンプトに含めて(拡張)、その情報に基づいてLLMに回答を生成させます。これにより、LLMは自身の内部知識だけでなく、提供された外部情報も考慮して応答を生成できるようになります。
RAGのメリット
- ハルシネーションの抑制: 外部の信頼できる情報源を参照することで、LLMが事実に基づかない情報を生成するリスクを低減します。
- 最新情報の利用: LLMの学習データが古くても、RAGは最新の外部情報源から情報を取得できるため、常に最新の知識に基づいた回答が可能です。
- 専門知識の活用: 特定のドメイン(企業内部資料、専門論文など)の知識をLLMに提供できます。
- 情報源の提示: 検索された情報源をユーザーに提示することで、回答の信頼性を高め、ユーザーが情報を検証できるようにします。
RAGの基本的な流れ (Mermaid図)
graph TD
A[ユーザーの質問] --> B{関連情報検索}
B --> C[外部知識ベース]
C --> D[関連情報]
D --> E["プロンプト構築 (質問 + 関連情報)"]
E --> F[LLM]
F --> G[回答生成]
G --> H[ユーザーへの回答]
subgraph "RAGパイプライン"
B
embedding
C
vector
DB
D
reranker
end
この図は、ユーザーの質問がRAGパイプラインに入力され、外部知識ベースから関連情報が検索され、それがLLMへのプロンプトに組み込まれて回答が生成される一連の流れを示しています。
embedding
ひとことで言うと: テキストの意味を捉えた数値ベクトル表現。
何のカテゴリか: 自然言語処理、機械学習。
何に使うのか: テキスト間の類似度計算、検索、分類、クラスタリング。
代表例: OpenAIのtext-embedding-ada-002、Sentence-BERT、Word2Vec。
よく混同される用語: One-hotエンコーディング、トークンID。
初心者向け注意点: embeddingは単なる数値の羅列ではなく、意味的に近いテキストはベクトル空間上で近くに配置されるという特性を持ちます。
embeddingは、単語や文章といったテキスト情報を多次元の数値ベクトル(数値の並び)に変換する技術です。この変換は、単語や文章の意味的な関係性をベクトル空間上に反映させるように行われます。つまり、意味的に似ている単語や文章は、ベクトル空間上でも互いに近い位置に配置されるようになります。
例えば、「猫」と「犬」のembeddingベクトルは、「車」のembeddingベクトルよりも互いに近い位置にあります。これにより、テキスト情報を直接扱うのではなく、数値ベクトルとして扱うことで、コンピュータがテキストの意味を理解し、様々な計算(類似度計算など)を行えるようになります。
embeddingの生成
embeddingは、通常、Transformerベースのニューラルネットワーク(例: BERT, GPTなどの一部)によって生成されます。これらのモデルは、大量のテキストデータで学習されており、単語や文章の文脈を理解し、その意味を捉えたベクトルを生成する能力を持っています。
コサイン類似度
embeddingベクトル間の類似度を測る一般的な方法として「コサイン類似度」があります。これは、2つのベクトルのなす角度のコサイン値を計算するもので、値が1に近いほど類似度が高く、-1に近いほど類似度が低いことを示します。
$$ \text{similarity}(\mathbf{A}, \mathbf{B}) = \frac{\mathbf{A} \cdot \mathbf{B}}{|\mathbf{A}| |\mathbf{B}|} $$
ここで、$\mathbf{A}$ と $\mathbf{B}$ は2つのembeddingベクトル、$\cdot$ は内積、$|\cdot|$ はベクトルのノルム(長さ)を表します。コサイン類似度は、ベクトルの方向がどれだけ似ているかを示し、ベクトルの長さ(大きさ)には影響されません。
vector DB (Vector Database)
ひとことで言うと: embeddingベクトルを効率的に保存・検索するためのデータベース。 何のカテゴリか: データベース、情報検索。 何に使うのか: 類似度検索(Nearest Neighbor Search)、RAGシステム、レコメンデーション。 代表例: Pinecone, Weaviate, Milvus, Chroma, Qdrant。 よく混同される用語: リレーショナルデータベース、NoSQLデータベース。 初心者向け注意点: vector DBは、従来のデータベースとは異なり、主にベクトル間の類似度検索に特化しています。
vector DBは、embeddingベクトルを保存し、高速かつ効率的に類似度検索を実行するために設計された特殊なデータベースです。RAGシステムにおいて、ユーザーの質問のembeddingベクトルと、知識ベース内のドキュメントのembeddingベクトルを比較し、最も類似性の高いドキュメント(またはその一部)を迅速に特定する役割を担います。
vector DBの主な機能
- ベクトルインデックス: 大量のベクトルデータの中から、クエリベクトルに最も近いベクトルを高速に検索するためのインデックス構造(例: HNSW, IVFなど)を持っています。
- メタデータ管理: ベクトルだけでなく、そのベクトルが表現する元のテキストやその他の関連情報(作成日時、カテゴリなど)をメタデータとして保存し、フィルタリングや検索条件に利用できます。
- スケーラビリティ: 大規模なデータセットや高負荷なクエリに対応できるよう、分散処理や水平スケーリングが可能です。
RAGにおけるVector DBの役割 (Mermaid図)
graph TD
A[ドキュメント] --> B[チャンク化]
B --> C[Embeddingモデル]
C --> D[Embeddingベクトル]
D --> E["Vector DB (インデックス作成)"]
F[ユーザーの質問] --> G[Embeddingモデル]
G --> H[クエリベクトル]
H --> I{Vector DBで類似検索}
I --> J[類似チャンク]
subgraph "データ取り込み (オフライン)"
A
B
C
D
end
subgraph "検索 (オンライン)"
F
G
H
I
end
この図は、ドキュメントがチャンク化され、embeddingベクトルに変換されてVector DBに保存される「データ取り込み」プロセスと、ユーザーの質問がクエリベクトルに変換され、Vector DBで類似チャンクが検索される「検索」プロセスを示しています。
chunking
ひとことで言うと: 長いテキストを意味のある小さな塊に分割するプロセス。 何のカテゴリか: 自然言語処理、データ前処理。 何に使うのか: RAGシステムでの情報検索、LLMの入力トークン制限への対応。 代表例: 固定長分割、文区切り、セマンティック分割。 よく混同される用語: トークナイゼーション。 初心者向け注意点: チャンクのサイズや分割方法は、RAGの検索精度に大きく影響します。
LLMは入力できるテキストの長さに制限(コンテキストウィンドウ)があります。また、RAGで関連情報を検索する際、非常に長いドキュメント全体をembedding化して検索すると、特定の質問に対する関連情報が埋もれてしまったり、検索精度が低下したりする可能性があります。
chunkingは、このような問題を解決するために、長いドキュメントを意味のある小さな「チャンク(塊)」に分割するプロセスです。各チャンクは独立してembedding化され、vector DBに保存されます。
chunkingの考慮事項
- チャンクサイズ: チャンクが小さすぎると文脈が失われ、大きすぎると関連情報が埋もれる可能性があります。適切なサイズはアプリケーションやデータによって異なります。
- オーバーラップ: チャンク間に一部重複を持たせることで、文脈の連続性を保ち、重要な情報がチャンクの境界で分断されるのを防ぎます。
- 分割戦略:
- 固定長分割: 単純に一定の文字数やトークン数で分割します。
- 文区切り分割: 文の区切り(句読点など)で分割します。
- セマンティック分割: 段落、セクション、または意味的なまとまりで分割します。より高度な手法では、テキストの意味的な変化点を検出して分割します。
retrieval
ひとことで言うと: ユーザーの質問に関連する情報を知識ベースから探し出すプロセス。 何のカテゴリか: 情報検索、RAGの主要ステップ。 何に使うのか: RAGシステムでの関連文書取得、検索エンジンのバックエンド。 代表例: ベクトル類似度検索、キーワード検索。 よく混同される用語: 生成(Generation)。 初心者向け注意点: retrievalの精度がRAG全体の性能を大きく左右します。
retrievalは、RAGパイプラインの最初の重要なステップであり、ユーザーの質問(クエリ)に対して、外部の知識ベースから最も関連性の高い情報を取得するプロセスです。このプロセスは、主に以下の方法で行われます。
- クエリのembedding化: ユーザーの質問をembeddingモデルに入力し、質問のembeddingベクトルを生成します。
- 類似度検索: 生成された質問のembeddingベクトルと、vector DBに保存されている知識ベースの各チャンクのembeddingベクトルとの類似度を計算します。
- 上位N件の取得: 計算された類似度に基づいて、最も類似度の高い上位N件のチャンク(ドキュメントの一部)を取得します。
reranker
ひとことで言うと: 検索された情報の関連性を再評価し、順位を付け直すモデル。 何のカテゴリか: 自然言語処理、情報検索。 何に使うのか: RAGシステムでの検索精度向上、検索結果の最適化。 代表例: Cross-encoderモデル(例: BERTベースの再ランキングモデル)。 よく混同される用語: embeddingモデル。 初心者向け注意点: rerankerは検索結果の数を減らすのではなく、順序を最適化するものです。
retrievalステップで取得された上位N件のチャンクは、必ずしも質問に対して最も関連性の高い順に並んでいるとは限りません。embeddingモデルは、一般的に「意味的な類似性」を捉えるのが得意ですが、質問とチャンクの間の「直接的な関連性」や「回答に役立つ度合い」を正確に評価するのは難しい場合があります。
rerankerは、この問題を解決するために導入されます。rerankerは、取得されたチャンクと元の質問のペアを入力として受け取り、それぞれのペアがどれだけ関連性が高いかをより詳細に評価し、そのスコアに基づいてチャンクの順位を付け直します。これにより、LLMに渡される情報がより精度の高いものとなり、最終的な回答の品質が向上します。
rerankerの仕組み
rerankerは、通常、質問とチャンクの両方を同時に考慮する「Cross-encoder」と呼ばれるモデルアーキテクチャを使用します。これにより、両者の間の相互作用を深く理解し、より正確な関連性スコアを算出できます。
hybrid search
ひとことで言うと: ベクトル検索とキーワード検索(全文検索)を組み合わせて検索精度を高める手法。 何のカテゴリか: 情報検索。 何に使うのか: RAGシステムでの検索精度向上、複雑なクエリへの対応。 代表例: ベクトル検索 + BM25、ベクトル検索 + TF-IDF。 よく混同される用語: 単一の検索手法。 初心者向け注意点: それぞれの検索手法の長所を組み合わせることで、より堅牢な検索システムを構築できます。
ベクトル検索(セマンティック検索)は、テキストの意味的な類似性を捉えるのに優れていますが、特定のキーワードが厳密に含まれるドキュメントを見つけ出すのが苦手な場合があります。例えば、「Apple社の最新のiPhoneモデルは何ですか?」という質問に対して、ベクトル検索は「スマートフォン」や「新製品」といった意味的に近い情報を取得するかもしれませんが、「iPhone」というキーワードが必ずしも含まれるとは限りません。
一方、キーワード検索(全文検索、例: BM25, TF-IDF)は、特定のキーワードがテキストに存在するかどうかを高速に判断するのに優れていますが、キーワードの表面的な一致に依存するため、意味的な関連性を見落とすことがあります。
hybrid searchは、これら二つの検索手法の長所を組み合わせることで、検索精度を向上させるアプローチです。
hybrid searchの一般的なアプローチ
- ベクトル検索の実行: ユーザーの質問をembedding化し、vector DBで類似するチャンクを検索します。
- キーワード検索の実行: ユーザーの質問からキーワードを抽出し、従来の全文検索エンジン(例: Elasticsearch, Solr)で関連するチャンクを検索します。
- 結果の統合: 両方の検索結果を統合し、それぞれのスコアを重み付けして最終的なランキングを決定します。この際、rerankerを適用して最終的な順位を調整することもあります。
Hybrid Searchの処理フロー (Mermaid図)
graph TD
A[ユーザーの質問] --> B[キーワード抽出]
A --> C[Embeddingモデル]
B --> D["キーワード検索 (BM25/TF-IDF)"]
C --> E[クエリベクトル]
E --> F["ベクトル検索 (Vector DB)"]
D --> G[キーワード検索結果]
F --> H[ベクトル検索結果]
G --> I{"結果統合 & スコアリング"}
H --> I{"結果統合 & スコアリング"}
I --> J["最終検索結果 (reranker適用可)"]
この図は、ユーザーの質問がキーワード検索とベクトル検索の2つのパスに分岐し、それぞれの結果が統合されて最終的な検索結果が生成されるHybrid Searchの処理フローを示しています。
具体例
ここでは、RAGシステムがどのように動作するかを、具体的なシナリオで見ていきましょう。
シナリオ: 企業の人事部門が、従業員からの「育児休暇の申請方法について教えてください」という質問に答えるQ&Aシステムを構築する。
データ準備 (オフラインプロセス)
- 知識ベースの構築: 企業内の人事規定、育児休暇に関するFAQ、申請書テンプレートなどのドキュメントを収集します。
- chunking: これらのドキュメントを、意味のある小さなチャンクに分割します。例えば、「育児休暇の対象者」「申請期間」「必要書類」「給付金」といったセクションごとに分割し、各チャンクに元のドキュメントのタイトルやページ番号などのメタデータを付与します。
- embedding: 各チャンクをembeddingモデル(例: OpenAIの
text-embedding-ada-002)に入力し、それぞれのチャンクに対応するembeddingベクトルを生成します。 - vector DBへの保存: 生成されたembeddingベクトルと、元のチャンクテキスト、およびメタデータをvector DB(例: Pinecone)に保存します。
ユーザーからの質問 (オンラインプロセス)
- ユーザーの質問: 従業員が「育児休暇の申請方法について教えてください」とシステムに入力します。
- 質問のembedding化: この質問を、知識ベースのチャンクをembedding化したのと同じembeddingモデルに入力し、質問のembeddingベクトルを生成します。
- retrieval (検索):
- ベクトル検索: 生成された質問のembeddingベクトルを使って、vector DB内で最も類似性の高い上位10件のチャンクを検索します。
- キーワード検索 (hybrid searchの場合): 質問から「育児休暇」「申請方法」といったキーワードを抽出し、全文検索エンジンで関連するチャンクを検索します。
- 結果の統合: ベクトル検索とキーワード検索の結果を統合し、上位20件程度のチャンク候補を選出します。
- reranker (オプション): 取得された20件のチャンク候補と元の質問のペアをrerankerモデルに入力し、質問に対する関連性の高い順に上位5件のチャンクを選び直します。
- プロンプト構築: ユーザーの質問と、rerankerによって選ばれた上位5件のチャンクの内容を組み合わせて、LLMへのプロンプトを作成します。
以下の情報に基づいて、育児休暇の申請方法について具体的に説明してください。 --- 情報1: [チャンク1の内容: 育児休暇の申請期間は、原則として休暇開始日の1ヶ月前までです。] 情報2: [チャンク2の内容: 育児休暇の申請には、育児休暇申請書、母子手帳のコピー、住民票が必要です。] 情報3: [チャンク3の内容: 申請書は人事部のウェブサイトからダウンロードできます。] --- 質問: 育児休暇の申請方法について教えてください。 - LLMによる回答生成: 構築されたプロンプトをLLM(例: GPT-4)に入力し、回答を生成させます。
- 回答の提示: LLMが生成した回答「育児休暇の申請は、休暇開始日の1ヶ月前までに、人事部のウェブサイトからダウンロードした申請書に必要事項を記入し、母子手帳のコピーと住民票を添えて提出してください。」をユーザーに提示します。
このように、RAGは外部の知識を動的に参照することで、LLMがより正確で具体的な回答を生成することを可能にします。
よく混同される用語との比較
RAGはLLMの能力を拡張する強力な手法ですが、LLMの学習プロセス自体を変更するものではありません。ここでは、RAGと混同されやすい他の概念との違いを明確にします。
| 特徴/手法 | RAG (Retrieval-Augmented Generation) | SFT (Supervised Fine-Tuning) | 事前学習 (Pre-training) |
|---|---|---|---|
| 目的 | LLMに外部知識を提供し、ハルシネーション抑制、最新情報/専門知識の利用、情報源の提示 | 特定タスクの性能向上、特定のスタイル/トーンへの適応、特定の知識の強化 | 大量のテキストデータから汎用的な言語理解能力を獲得 |
| 対象 | 既存のLLMモデル | 既存のLLMモデル | ゼロからモデルを構築 |
| 方法 | 外部知識ベースから情報を検索し、LLMへのプロンプトに含める | 特定のタスクに特化したラベル付きデータセットでLLMの重みを更新 | 大規模なテキストコーパスで自己教師あり学習 |
| 知識源 | 外部の動的な知識ベース(ドキュメント、DBなど) | ファインチューニングデータセット内の知識 | 事前学習コーパス内の知識 |
| 更新頻度 | 知識ベースを更新すれば即座に反映可能 | モデルの再学習が必要 | モデルの再学習が必要 |
| ハルシネーション | 外部情報源を参照することで抑制 | ファインチューニングデータに依存、抑制効果は限定的 | 発生しやすい |
| コスト | 比較的低コスト(検索インフラとプロンプト構築) | 計算リソースとデータ準備にコストがかかる | 非常に高コスト |
| 例 | 企業内Q&A、最新ニュースに基づく要約 | 特定の業界用語への適応、チャットボットの応答スタイル調整 | GPT-3, Llama 2などの基盤モデルの構築 |
RAG vs SFT: RAGは、LLMの重みを変更することなく、外部情報をプロンプトとして与えることで、LLMの知識を「拡張」します。一方、SFT(Supervised Fine-Tuning)は、特定のタスクやデータセットに合わせてLLMの重みを「調整」し、モデル自体の振る舞いを変更します。RAGは動的な情報への対応に優れ、SFTは特定のタスクにおけるモデルの性能やスタイルを最適化するのに適しています。両者は排他的なものではなく、SFTされたモデルにRAGを組み合わせることで、さらに強力なシステムを構築することも可能です。
実務での位置づけ
RAGは、LLMを実世界のアプリケーションに導入する上で、非常に重要な役割を担っています。特に、以下のようなシナリオでその価値を発揮します。
- 企業内知識Q&Aシステム: 企業の膨大なドキュメント(規定、マニュアル、報告書など)から、従業員の質問に正確に答えるシステム。ハルシネーションのリスクを低減し、情報源を明示できるため、信頼性が高いです。
- カスタマーサポート: 顧客からの問い合わせに対し、製品マニュアルやFAQ、過去のサポート履歴を参照して、パーソナライズされた回答を生成します。
- 研究・開発支援: 最新の論文や技術文書から関連情報を抽出し、研究者の情報収集を支援します。
- 法務・医療分野: 専門性の高いドキュメントから、特定のケースに関する情報を検索し、専門家の意思決定を支援します。
- リアルタイム情報への対応: 株価情報、最新ニュース、天気予報など、頻繁に更新される情報をLLMに提供し、常に最新の状況に基づいた回答を生成させます。
RAGは、LLMの「知っていること」と「知っているべきこと」のギャップを埋めるためのブリッジとして機能します。これにより、LLMは単なる言語生成ツールから、信頼できる情報アシスタントへと進化し、ビジネスや研究の様々な領域でその応用範囲を広げています。
まとめ
3行まとめ
- RAGは、LLMが外部知識を参照して回答を生成するフレームワークで、ハルシネーション抑制と最新情報利用を可能にする。
- embeddingはテキストを意味のある数値ベクトルに変換し、vector DBはそれを効率的に保存・検索する。
- chunking、retrieval、reranker、hybrid searchはRAGの検索精度を高めるための重要なコンポーネントである。
混同しやすい用語
- RAGとSFT: RAGは外部知識の参照、SFTはモデルの重み調整。
- embeddingとOne-hotエンコーディング: embeddingは意味を捉えた密なベクトル、One-hotは単語の存在を示す疎なベクトル。
- vector DBとリレーショナルDB: vector DBはベクトル検索に特化、リレーショナルDBは構造化データ管理に特化。
次に読むべき章
- 第20章: プロンプトエンジニアリングの基礎
- 第21章: エージェントとツール利用
- 第22章: LLMアプリケーション開発フレームワーク (LangChain, LlamaIndex)