第10部 データ・検索・エージェント第19章

RAG / embedding / vector DB

モデルが知らないことは、調べてから答えさせればいい。RAGを支えるチャンキング、embedding、ベクトルDB、ハイブリッド検索、リランカー、そして評価の方法までをひと続きで見ていきます。

約15分で読めます2026年10月改訂

このページの内容(11項目)
  1. RAGとは:調べてから答える
  2. チャンキング:資料をどう切るか
  3. embedding:意味を座標にする
  4. ベクトルDB:近い住所をすばやく探す
  5. ハイブリッド検索とBM25
  6. リランカー:最後に目利きが並べ直す
  7. 長いコンテキストがあればRAGは不要?
  8. 一歩進んだRAG:GraphRAGとエージェント型RAG
  9. RAGをどう評価するか
  10. さらに深く学ぶ
  11. 出典・参考

「うちの会社の経費精算の締め日は?」と聞くと、AIが自信満々に間違える。なぜ?

LLMは学習したデータの範囲でしか物事を知りません。社内規程や先週決まったことは、そもそも学習データに入っていません。それでも「それらしい答え」を作れてしまうのがLLMの怖いところです。では、答える前に社内の資料を調べさせたらどうでしょう。これがRAGの出発点です。

RAGとは:調べてから答える

ひとことで言うと

RAG(Retrieval-Augmented Generation、検索拡張生成)は、質問に関係しそうな文書を検索して取り出し、それをプロンプトに添えてからLLMに答えさせる仕組みです。モデル自体は学習し直しません。

RAGは「持ち込み可の試験」です。LLMは暗記に頼らず、図書館の司書(検索システム)が探してきた資料のページを見ながら答案を書きます。司書が的外れな本を持ってくれば、答案も外れます。RAGの品質の大半は、この司書の腕で決まります。

名前は2020年のLewisらの論文に由来します。現在では、論文の手法そのものよりも「検索結果を文脈として渡して生成させる」設計全般を指す言葉として使われています。

flowchart TD
  subgraph prep["事前準備"]
    D["社内文書など"] --> C["チャンクに分割"]
    C --> V["embeddingに変換"]
    V --> DB["ベクトルDBに保存"]
  end
  Q["ユーザーの質問"] --> S["検索"]
  DB --> S
  S --> P["質問と検索結果で
プロンプトを作る"] P --> L["LLMが回答"]
図: RAGの基本の流れ。事前準備(インデックス作成)と、質問のたびに行う検索・生成の2段階に分かれる

RAGの利点は、知識を「モデルの外」に置けることです。文書を差し替えればすぐ最新になり、回答に「どの文書を根拠にしたか」を示せます。アクセス権に応じて検索対象を絞る、といった制御もしやすくなります。LoRAなどの微調整(第13章)で知識を覚えさせるより、更新や削除がずっと簡単です。

チャンキング:資料をどう切るか

長い文書をそのまま検索対象にすると、「どこに答えがあるか」がぼやけます。そこで文書を数百トークン程度の断片(チャンク、chunk)に切ってから保存します。これを チャンキング(chunking) と呼びます。

  • 固定長で切る: 一定のトークン数ごとに切る、いちばん単純な方法。前後を少し重ねる(オーバーラップ)と、文の途中で切れて意味が失われるのを和らげられます。
  • 構造に沿って切る: 見出し・段落・表・コードの関数単位など、文書の構造で切る方法。人間が読む単位に近いので、多くの場合こちらが扱いやすくなります。
  • 文脈を足す: チャンクだけを読むと「この会社」「前述の条件」が何を指すかわからないことがあります。文書名や章見出しをチャンクの先頭に付けておくと、検索でも生成でも迷いが減ります。

最後の工夫を発展させたのが、Anthropicが紹介した Contextual Retrieval です。LLMに「このチャンクは文書全体の中でどんな位置づけか」という短い説明を書かせ、チャンクに付け加えてから索引を作ります。同社の実験では、検索失敗(上位20件に正解チャンクが入らない割合)が、後述のBM25との併用で49%、さらにリランキングを加えると67%減ったと報告されています。

ためしてみよう

チャンクの大きさに唯一の正解はありません。手元の文書と、実際に聞かれそうな質問を10〜20個用意し、チャンクの長さや切り方を変えて「正解の入ったチャンクが上位に来るか」を比べるのがいちばんの近道です。

embedding:意味を座標にする

ひとことで言うと

embedding(埋め込み)は、文章を数百〜数千個の数字の並び(ベクトル)に変えたものです。意味が近い文章ほど、ベクトル同士も近くなるように作られています。

たとえば「経費の締め日」と「精算の期限」は、使っている単語は違っても意味は近い。embeddingモデルはこの2つを近い位置に置きます。逆に「締め日」と「締め切りのサッカー試合」は離れた場所に置かれるはずです。

embeddingは「意味の地図の住所」です。似た話題の文章は同じ町内に住んでいて、質問の住所を調べれば、近所に住んでいる文書をすぐ見つけられます。

近さは、ベクトル同士の向きの近さ(コサイン類似度、cosine similarity)や内積で測るのが一般的です。押さえておきたい実務上の注意点は3つあります。

  • 文書と質問は同じembeddingモデルで変換する。モデルが違えば地図も違い、住所を比べられません。モデルを替えたら全文書を変換し直します。
  • モデルごとに得意不得意がある。日本語の文書なら、日本語を含む多言語の評価で確かめる。比較にはMTEB(Massive Text Embedding Benchmark)などのベンチマークが参考になります。
  • embeddingは「話題の近さ」には強い一方、型番・人名・エラーコードのような文字列の完全一致は苦手なことがある。これが次のハイブリッド検索の動機です。

ベクトルDB:近い住所をすばやく探す

文書が数百万チャンクあると、質問のたびに全部と距離を計算するのは大変です。そこで 近似最近傍探索(ANN、Approximate Nearest Neighbor) という索引を使い、「完全に正確ではないが、ほぼ正しい近所」を高速に見つけます。この索引を持ち、ベクトルの保存と検索を得意とするのがベクトルDB(vector database)です。

索引の方式仕組みのイメージ特徴
HNSW近いもの同士をつないだ多層のグラフをたどる検索が速く精度も高いが、構築が遅くメモリを食う
IVFFlat(IVF系)ベクトルをグループに分け、近いグループだけ調べる構築が速く省メモリだが、速さと精度のバランスはHNSWに劣る

専用のベクトルDB(Qdrant、Milvus、Weaviate、Pineconeなど)のほかに、既存のデータベースにベクトル検索を足す選択肢もあります。代表例が PostgreSQL の拡張機能 pgvector です。いつものテーブルにベクトル列を追加し、SQLで近い順に並べられます。HNSWとIVFFlatの両方の索引に対応し、PostgreSQLの全文検索と組み合わせたハイブリッド検索の例もREADMEに載っています(リリースは v0.8.7 2026年10月時点)。

CREATE EXTENSION vector;
CREATE TABLE chunks (id bigserial PRIMARY KEY, body text, embedding vector(1024));
CREATE INDEX ON chunks USING hnsw (embedding vector_cosine_ops);

-- 質問のベクトルに近い順に5件(<=> はコサイン距離)
SELECT body FROM chunks ORDER BY embedding <=> $1 LIMIT 5;

pgvectorの vector 型は、索引を張れる次元数が2,000までという制限があります(halfvec 型なら4,000まで)。次元の大きいembeddingモデルを使うときは事前に確認しましょう。社内の文書量が中規模までなら、「まずは使い慣れたPostgreSQLで」という判断は十分に現実的です。

ハイブリッド検索とBM25

embeddingによる検索(ベクトル検索、密な検索)は言い換えに強く、昔ながらのキーワード検索は完全一致に強い。両方の長所を取るのが ハイブリッド検索(hybrid search) です。

キーワード検索の定番が BM25 です。「質問の単語が文書に何回出てくるか」と「その単語がどれだけ珍しいか」をもとに点数を付けます。「の」「です」のようにどこにでもある語は軽く、「ERR-4031」のような珍しい語は重く扱われます。日本語では単語の区切りが空白でないので、形態素解析やn-gramで分割してから使うのが普通です。

2つの検索結果を1つの順位にまとめる方法としてよく使われるのが RRF(Reciprocal Rank Fusion) です。点数そのものではなく「何位だったか」だけを使い、各リストでの順位rに対して 1/(k+r) を足し合わせます(kは定数)。点数の尺度が違う検索同士でも、素直に混ぜられるのが利点です。

flowchart TD
  Q["質問"] --> A["ベクトル検索
意味が近い"] Q --> B["BM25
単語が一致"] A --> F["RRFで順位を統合"] B --> F F --> R["リランカーで
上位を並べ直す"] R --> L["上位数件を
LLMへ渡す"]
図: よく使われる検索パイプライン。広く集めてから、絞り込む

リランカー:最後に目利きが並べ直す

ベクトル検索では、質問と文書を別々にベクトルにしてから比べます(bi-encoder)。事前に文書を変換しておけるので速い反面、細かい関係は見落としがちです。

リランカー(reranker) は、質問と候補文書をペアでモデルに読ませ、「この文書はこの質問の答えになっているか」を直接採点します(cross-encoder)。精度は高いものの、候補ごとにモデルを動かすので遅く、全文書には使えません。そこで「速い検索で50〜100件を集め、リランカーで上位数件に絞る」という二段構えが定番になっています。

一次検索は「書庫から関係ありそうな本を台車で運んでくる係」、リランカーは「1冊ずつ中身を確かめて、本当に使える数冊を机に並べる係」です。

両者の中間として、トークン単位のベクトルを持っておき細かく照合するColBERTのような「後期相互作用(late interaction)」型の手法もあります。

長いコンテキストがあればRAGは不要?

最近のモデルは数十万〜100万トークンを一度に読めるものもあります(たとえばDeepSeek-V4は100万トークンのコンテキストに対応 2026年10月時点)。それなら全部プロンプトに入れればいいのでは、という疑問は自然です。

実際、資料が少ないなら全部入れるのは有力な選択肢です。Anthropicは、知識ベースが20万トークン(約500ページ)より小さければ、RAGを組まずにすべてプロンプトに含めてしまう方法も挙げています。プロンプトキャッシュ(第28章)を使えば、同じ資料を何度も読ませるコストも抑えられます。

一方で、RAGが有利な場面もはっきりあります。

  • 量: 社内文書全体のように、どんな長いコンテキストにも収まらない規模。
  • コストと速度: 入力トークンは課金と待ち時間に直結する。毎回100万トークン読ませるのは高くつく。
  • 埋もれ: 長い入力の途中にある情報は見落とされやすい、という報告があります(「Lost in the Middle」論文)。モデルの改良で改善は進んでいますが、無関係な文章を大量に混ぜないに越したことはありません。
  • 権限と鮮度: 利用者ごとに見てよい文書を絞り、更新をすぐ反映できる。

現実には「RAGで絞り込んでから、長いコンテキストにたっぷり渡す」という組み合わせが多く使われます。

一歩進んだRAG:GraphRAGとエージェント型RAG

普通のRAGは「質問に似たチャンクを数件持ってくる」のが基本なので、「この文書群全体で議論されている主要なテーマは?」のような全体を俯瞰する質問は苦手です。似たチャンクを数件読んでも全体像は見えません。

Microsoftの研究者らが提案した GraphRAG は、事前にLLMで文書から人物・組織・概念などの実体と関係を抜き出して知識グラフを作り、まとまりごとの要約まで用意しておく手法です。俯瞰的な質問に強くなる代わりに、索引作りにLLMを大量に使うのでコストがかかります。実装はMicrosoftがGitHubで公開しています。

もうひとつの流れが エージェント型RAG(agentic RAG) です。検索を1回で終わらせず、LLM自身が「まず規程を検索、足りなければ改定履歴も検索」と検索語を考え、結果を見て次の行動を決めます。検索をツールの1つとして使うエージェント(第20章)の一種と考えると整理しやすいでしょう。柔軟になる反面、手順が増える分だけ遅く、高く、挙動の確認も難しくなります。

RAGをどう評価するか

RAGがうまくいかないとき、原因は「検索が外れた」のか「検索は合っていたのに生成で間違えた」のかで、直す場所がまったく違います。だから評価も2段に分けます。

段階問うこと指標の例
検索正解の入ったチャンクを取ってこれたかRecall@k、MRR、Context Precision / Recall
生成取ってきた資料に忠実に答えたかFaithfulness(忠実性)、回答の関連性
全体利用者の役に立ったか正答率、引用の正しさ、人による評価

出発点として、実際の質問と「正解が書いてある文書の場所」の組を数十件作っておくと、チャンクの切り方やembeddingモデル、リランカーを変えたときの効果をすぐ比べられます。RAGASのように、LLMを採点者として使い忠実性などを自動で測るツールもあります。ただしLLM採点にも癖があるので、ときどき人の目で突き合わせることが大切です(評価全般は第30章)。

よくある誤解

RAGを入れればハルシネーションはなくなる

検索が外れれば外れた資料をもとに答えるし、資料を読み違えることもある。減らす手段であって、なくす手段ではない

RAGにはベクトルDBが必須

キーワード検索だけのRAGも、既存DB+pgvectorのRAGもある。必要なのは「よい資料を取ってくる仕組み」

RAGはモデルに知識を学習させる方法だ

モデルの重みは変わらない。毎回プロンプトに資料を添えているだけ

確認クイズ

Q1. 「ERR-4031の対処法」を探したいのに、ベクトル検索では似た別のエラーばかり出てくる。まず試すべきなのは?

  • embeddingの次元を増やす
  • BM25などのキーワード検索を併用する(ハイブリッド検索)
  • LLMの温度を下げる

型番やエラーコードのような完全一致はキーワード検索の得意分野です。RRFなどで順位を統合します。

Q2. リランカーを全文書に直接使わないのはなぜ?

質問と文書のペアごとにモデルを動かすため遅いからです。速い一次検索で候補を数十件に絞ってから使います。

Q3. embeddingモデルを新しいものに替えたら、何が必要?

保存済みの全チャンクを新しいモデルで変換し直すことです。モデルが違うとベクトルの「地図」が違うので、古いベクトルとは比べられません。

Q4. RAGの回答が間違っていた。最初に確かめるべきことは?

検索結果に正解の資料が入っていたかどうかです。入っていなければ検索側(チャンキング、embedding、ハイブリッド検索、リランカー)、入っていたなら生成側(プロンプトやモデル)を直します。

この章のまとめ

  • RAGは「検索してから答える」仕組み。モデルを学習し直さずに、最新の知識や社内の知識を使える。
  • 品質の大半は検索で決まる。チャンキング、embedding、ハイブリッド検索(BM25+ベクトル)、リランカーを組み合わせる。
  • ベクトルDBは近似最近傍探索で近いベクトルを速く探す。PostgreSQLならpgvectorで始められる。
  • 長いコンテキストとRAGは競合ではなく補完。量・コスト・権限で使い分ける。
  • 評価は「検索」と「生成」に分けて測ると、直す場所がわかる。

さらに深く学ぶ

この章の内容をもう一歩掘り下げるための原典です。

第19章の論文・資料をすべて見る →

出典・参考

  1. Lewis et al., Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks(arXiv:2005.11401)
  2. Anthropic: Introducing Contextual Retrieval — 検索失敗率49%・67%減、20万トークン未満なら全文投入の選択肢
  3. pgvector/pgvector(GitHub) — HNSW・IVFFlat、次元の上限、ハイブリッド検索、v0.8.7(2026年10月確認)
  4. Cormack et al., Reciprocal Rank Fusion outperforms Condorcet and individual Rank Learning Methods(SIGIR 2009, PDF)
  5. Muennighoff et al., MTEB: Massive Text Embedding Benchmark(arXiv:2210.07316)
  6. Khattab and Zaharia, ColBERT(arXiv:2004.12832)
  7. Liu et al., Lost in the Middle: How Language Models Use Long Contexts(arXiv:2307.03172)
  8. deepseek-ai/DeepSeek-V4-Pro(Hugging Face) — 100万トークンのコンテキスト(2026年10月確認)
  9. Edge et al., From Local to Global: A Graph RAG Approach to Query-Focused Summarization(arXiv:2404.16130)、microsoft/graphrag(GitHub)
  10. Es et al., Ragas: Automated Evaluation of Retrieval Augmented Generation(arXiv:2309.15217)、Ragas: Available metrics