15
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RAG ってそもそも何なのか — indexもchunkもretrieveも知らない人のための、ゼロから順番に積み上げるRAG入門

15
Last updated at Posted at 2026-05-26

1. RAG って最近あんまり聞かなくなったような・・・

「RAG」という言葉、ちょっと前まではあちこちで聞いたのに、最近めっきり目にしなくなった、と感じていませんか?

実はこれ、RAG が廃れたわけではなくて、「当たり前」すぎて話題にならなくなった だけなんです。

社内チャットボット、検索 UI、ドキュメント Q&A、AI コーディング支援、サポート bot、…。2026 年現在、まともな AI プロダクトの多くには、何らかの形で RAG が組み込まれています。話題にならなくなったのは「もう前提」になったからであって、消えたからではありません。

そうすると逆に困るのが、「RAG ってフワッと聞いたことあるけど、中身はちゃんと分かっていない」 という状態の人です。流行りのトピックなら誰かが入門記事を書いてくれますが、「当たり前」になったものは、改めて誰も解説してくれなくなります。

  • 「RAG って単語は知ってる、でも index とか chunk とか言われると分からない」
  • 「ChatGPT 使ってるけど、その裏で何が動いてるのか説明できない」
  • 「最新の AI 設計を学ぼうとすると、RAG が前提知識として要求されて困る」

この記事は、まさにそういう人のために書きました。

2. 大前提:「AI」と「AI が知らないこと」

2.1 LLM ってまず何

LLM は Large Language Model(大規模言語モデル)の略です。ChatGPT や Claude や Gemini の中身に入っているのがこれです。

LLM がやっていることを乱暴に言うと、「次に来そうな単語を当て続けるゲームを、めちゃくちゃ膨大な文章で練習したやつ」 です。インターネット上の文章を大量に読ませて、続きを書く練習を延々やらせると、文法的に正しいだけでなく、知識まで持っているように見える応答が返ってきます。

2.2 LLM が知らないこと、四つ

ただ、LLM は 練習に使った文章の中にあった情報しか知りません。具体的には次の四つで困ります。

  1. 嘘をそれっぽく言う(hallucination, ハルシネーション): 知らないことを「もっともらしく」生成してしまいます。完全に存在しない論文を引用したり、ありそうで無い人名を出したりします。
  2. 新しい情報を知らない(knowledge cutoff): 「学習を終えた日」より後のニュースや改訂された法律は知りません。
  3. あなたの会社の中の文書を知らない: 社内マニュアルも、自分の会社のレシピ集も、当然学習データに入っていません。
  4. 「なぜそう答えたか」の根拠を示せない: 「あなたの会社のマニュアルの p.42 に書いてある」みたいな出典付きで答える機能は持っていません。

RAG はこの四つを「同じ仕組みで」解決するための道具立て です。これだけ覚えておけば、以下を読む準備はできています。

3. RAG をひとことで

RAG は Retrieval-Augmented Generation の略で、日本語にすると「検索を組み合わせた生成」です。

イメージで言うとこんな感じです。

あなたが料理本の編集者で、新人ライターが「ハンバーグの作り方」の原稿を書いているとします。
新人ライターは料理の知識はあるけど、「うちの社で出している料理本シリーズ」がどんなレシピを推奨しているかは知りません
そこで、原稿を書く前に、編集者が 「うちの社のシリーズから関係しそうなページを 3 つ抜き出して、ライターに渡す」 ことにします。
ライターは渡された 3 ページを横目で見ながら、その中身に沿って原稿を書きます。

LLM がライター、「検索する仕組み」が編集者、「シリーズの本」が外部の文書ベース、というわけです。

3.1 公式の定義

RAG はもともと、2020 年に Facebook AI Research(現 Meta AI)の Patrick Lewis らが発表した論文 "Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks" (NeurIPS 2020) で名前が付いた手法です。

論文の核心はこう書かれています。

parametric memorynon-parametric memory を組み合わせる。

難しい言葉が二つ出てきました。

  • parametric memory(パラメトリック記憶) = モデルの中に焼き付いた知識。「LLM が練習中に覚えたこと」のことで、書き換えにくいものです。
  • non-parametric memory(ノンパラメトリック記憶) = モデルの外側に置いた、いつでも書き換えられる文書集 のことです。

つまり RAG の本質は、「AI の頭の中の知識」と「外に置いた書き換え可能な文書集」を組み合わせる仕組み、というだけのことなんです。

4. RAG の全体像:二つのフェーズ

RAG の仕組みは、「準備するフェーズ」「使うフェーズ」 の二つに分かれます。

4.1 準備フェーズ(Indexing)

文書を最初に一回だけ、AI が検索できる形に整理して保存しておく作業です。

Load(読み込み)→ Split(分割)→ Embed(数値化)→ Store(保存)

これが順番です。

「一回だけ」って?

ここで言う「一回だけ」というのは、ユーザーから質問が来るたびに毎回走らせる必要はない、という意味です。

後で出てくる「使うフェーズ」のほうは、質問が来るたびに毎回走る処理です。

いつ走る?
準備フェーズ(Indexing) 最初の構築時に 1 回。その後は 文書が増えたり更新されたりしたとき だけ追加で走る
使うフェーズ(Retrieval & Generation) 質問が来るたびに毎回

イメージで言うと、図書館で新しい本が入荷したときに、館員さんがやる仕事が準備フェーズに似ています。

  • 本を受け取って、整理番号を貼って、どの棚に置くか決めて、検索データベースに登録する
  • これは 本が入荷したときだけ やればよくて、利用者が本を借りに来るたびに毎回やり直す作業ではないですよね

一方、「使うフェーズ」のほうは、利用者がやって来たときの図書館員の応対に近いです。

  • 利用者の「○○について書かれた本はありますか?」を聞いて、検索データベースで該当しそうな本を引いて、棚から取ってきて手渡す
  • これは 利用者が来るたびに毎回 やる作業です

RAG の Indexing も同じで、文書を受け入れて整理しておく一連の準備作業を指していて、ユーザーの質問とは独立に走らせます。

文書の更新頻度が低いほど、準備フェーズのコスト(embedding 生成の API 料金など)は無視できる量になります。逆に、ニュースサイトのように毎時間文書が増えるシステムでは、「新しく追加された分だけ embedding を作って index に足す」という差分更新の仕組みが必要になります。

4.2 使うフェーズ(Retrieval and Generation)

ユーザーから質問が来るたびに、その都度走る処理です。

Retrieve(関連箇所を取り出す)→ Generate(その箇所を見ながら AI が答える)

これだけです。

ここから、各ステップを順番に、専門用語をすべて説明しながら見ていきます。

5. 準備フェーズを噛み砕く

5.1 Load — 文書を「テキスト」にする

PDF・Word・Web ページ・データベース、なんでもいいです。とにかく 「読み込んで、生のテキスト(文字の連続)に変換する」 工程です。

例えば PDF の本なら、ページ単位で文字を抜き出してきます。
画像になっている文字(スキャンした紙の本など)には、OCR(画像から文字を読み取る技術)が必要になります。

ここで失敗すると、あとで何をやっても復活しません。「表の中の数字が抜けていた」みたいなことが起きると、その情報は二度と検索結果に出てこなくなります。

5.2 Split — 文書を細かく切る(これが Chunk)

ここで初めて chunk(チャンク) という言葉が出てきます。

Chunk とは何か

英語で chunk は「塊」「ひとかたまり」という意味です。RAG の文脈では、長い文書を扱いやすいサイズに分割した、ひとつひとつの小さなテキスト塊 を指します。

一冊の本(500 ページ)
↓ 分割
500 個くらいの「段落〜数段落くらいの塊」=「chunk」

ピザを切り分けるイメージです。一枚のまま持っていても食べづらいので、ピース単位に切ります。

なぜ切るのか

理由は二つあります。

  1. AI に渡せる文章の長さに上限がある(後で詳しく書きますが、AI には一度に読める文字数の限界があります)
  2. 後で「数値に変える」工程に、入力サイズの上限がある(こちらも後述します)

どれくらいの大きさで切る?

LangChain の公式チュートリアルでは 「1000 文字、200 文字のオーバーラップ」 が例として出てきます。「オーバーラップ」というのは、隣り合う chunk が一部重なる という意味です。

[----- chunk 1 (1000字) -----]
                  [----- chunk 2 (1000字) -----]
                                    [----- chunk 3 (1000字) -----]
↑この重なり 200 字

なぜ重ねるかというと、境界ちょうどで意味が切れてしまうのを防ぐため です。
「血液中のヘモグロビンは」で chunk が終わってしまうと、続きの「酸素を運ぶ」が次の chunk に行ってしまい、検索したときに片方しかヒットしないと意味が分からなくなってしまいます。

chunk のサイズ問題

  • 大きすぎる: 一つの chunk に複数のトピックが混ざります。検索精度が落ちます。
  • 小さすぎる: 意味のまとまりが壊れます。「これは〜です。」みたいな短い chunk だけ取れても意味不明です。

「だいたい段落 1〜数段落分」を目安にして、ドメイン(料理本なら 1 レシピ単位、技術書なら 1 節単位、など)に合わせて調整する、というのが現実的なルールになります。

5.3 Embed — テキストを「数の並び」に変える

ここが RAG で一番抽象的な部分なので、丁寧にいきます。

Embedding とは何か

Embedding(エンベディング) とは、文章を「ベクトル」に変換すること、またはその変換結果のベクトル自体 のことです。

「ハンバーグの作り方は牛ひき肉と豚ひき肉を混ぜて…」
↓ embedding モデル(変換する AI)に通す
[0.124, -0.873, 0.456, ..., 0.211] ← 1024 個の数字の並び(ベクトル)

ベクトルって何

ここで言う ベクトル(vector) は、「数字を並べたもの」 と思って構いません。高校で習う矢印のベクトルと数学的には同じですが、ここでは「数値が並んでいる」ことだけ覚えれば十分です。

ベクトル = [0.12, -0.87, 0.45, ..., 0.21]
            ↑こういうのが 1024 個並んでいる、というだけ

なぜわざわざ数字にする?

embedding を作るモデルは、「意味が近い文章どうしは、ベクトルとしても近くなる」 ように訓練されています。

これが embedding の核です。「近い」というのは、計算で機械的に測れる距離(後述のコサイン類似度など)のことです。

例えば次のような感じになります。

文章 A 文章 B ベクトル空間での距離
ハンバーグの作り方 ミートボールの作り方 近い(料理として似てる)
ハンバーグの作り方 クリスマスの飾り付け 遠い(無関係)
大谷翔平の打率 エンゼルス時代の成績 近い(同じ話題)

人間にとっての「意味が近い」を、機械にとっての「数字の距離」に変換する装置、これが embedding モデルです。

公式の例:Cohere の embed モデル

実例として、Cohere という会社の embed-multilingual-v3 という有名なモデルを見てみます。公式ドキュメントによると、

  • 出力する数の個数(dimensions, 次元数): 1024 個
  • 一度に入れられるテキスト長: 最大 512 トークン(トークンの説明はすぐ後にします)
  • 対応言語: 100 言語以上
  • 距離の測り方: cosine(コサイン)類似度・dot product(内積)・ユークリッド距離

「100 言語以上」というのが効いていて、日本語で書いた文章と英語で書いた文章を 同じ意味なら近くなる ように変換してくれます。

どうして 1024 個なの?

ここでよく出る疑問が、「なぜ 1024 個という中途半端な数字なの?」というものです。これは三つの観点から答えられます。

1. これは「このモデルがそう設計されている」から

1024 という数字は、Cohere の embed-multilingual-v3 というモデル固有の値で、embedding モデルの設計者が学習時に決めた数 です。
他のモデルだと、別の数字が出ます。

2. 多ければ多いほど、細かい意味を表現できる(ただしトレードオフあり)

次元数は「意味を入れる箱の数」みたいなものです。

  • 多い(3072 個など): 細かい意味の違いを表現しやすい。検索精度が上がりやすい
  • 少ない(384 個など): 表現できる細かさは落ちるが、保存容量も計算コストも軽くなる

「じゃあ多いほどいいか」というとそうでもなくて、

  • ベクトルが大きいぶん Vector DB のストレージが膨らむ(1 chunk あたり 3072 個 × 4 バイト = 12KB を 100 万 chunk 保存すると 12GB に届く、というオーダー)
  • 検索のたびの計算が重くなり、応答が遅くなる
  • 場合によっては過剰になって、精度がむしろ落ちる ケースもある

そのため「ちょうどよい中間」として 1024 や 1536 あたりが採用されることが多い、というわけです。

トークン (token) って何

embedding モデルの入力には「最大 512 トークン」のように上限があります。トークン というのは、AI が文章を扱うときの 最小単位 のことです。

  • 英語だと、だいたい「単語 1 個 ≒ 1 トークン」ですが、長い単語は分割されます
  • 日本語だと、「1 文字 ≒ 1〜2 トークン」くらいが目安です(モデルによります)

例: "running" → "run" + "ning" の 2 トークン、みたいに切られます。

これも RAG ではあちこちで出てくる単位なので、覚えておいてください。

ここまでで学んだこと

  • 文章を「数の並び(ベクトル)」に変える=embedding
  • 意味が近い文章は、ベクトルとしても近い
  • 1 つの chunk ごとに、1 つのベクトル(例: 1024 個の数字)を作る

5.4 Store — ベクトルを保存する場所=Vector Database

chunk をベクトルにしたら、それを どこかに保存する 必要があります。

ここで出てくるのが Vector Database(Vector DB) です。

Vector DB とは

普通のデータベース(MySQL とか)は「文字列で検索」「数値で範囲指定」みたいなことが得意です。
Vector DB は「このベクトルに近いベクトル top 5 を探して」みたいなクエリが得意な、特殊なデータベース になります。

代表的なものに ChromaPineconeWeaviateQdrant などがあります。Chroma の公式ドキュメントから引用すると、

Chroma is the open-source data infrastructure for AI.
Store documents and metadata. / Dense, sparse, and hybrid search. / Filter results at query time by metadata conditions.

要するに「文書とメタデータを保存し、ベクトルで検索でき、検索時にメタデータでフィルタもできる」というのが Vector DB の基本機能になります。

メタデータ(metadata)って何

メタデータ = 「データ自体ではなく、データに付ける付加情報」 のことです。

ベクトル DB に chunk を保存するときに、ベクトルだけでなく次のような情報も一緒に保存します。

chunk_id book_name chapter page (ベクトル)
0001 家庭料理大全 3章 肉料理 42 [0.12, ...]
0002 家庭料理大全 3章 肉料理 43 [0.05, ...]
0003 スイーツの本 1章 ケーキ 18 [-0.33, ...]

メタデータがあると、後で 「家庭料理大全の中だけ検索する」 みたいな絞り込みができるようになります。これがあるかどうかで RAG の精度はガラッと変わります(後述します)。

ここまでで学んだこと

  • chunk のベクトルは Vector DB に保存する
  • Vector DB は「ベクトルが近いやつ」を高速に探せる
  • ベクトルだけでなくメタデータ(出典・章・ページ など)も一緒に保存する

これで「準備フェーズ」は終わりです。文書が、ベクトル+メタデータ付きで Vector DB に並んでいる状態が完成しました。これを インデックス が貼られた状態、と呼びます。

5.5 ここで Index という言葉を整理する

「index(インデックス)」は 本の巻末に付いている索引 のあれ、と同じ言葉です。

ふつうの本でも「血液 → p.42, 87, 153」みたいな索引が後ろに付いていると、「血液」というキーワードから関連ページに飛べます。

RAG での index は、「文書を、後で検索しやすい形に整理して保存した状態」 のことです。Vector DB の中に chunk のベクトルとメタデータが入っている状態が、「インデックスが構築された」状態になります。

Indexing という動詞は、その状態を作る作業=準備フェーズ全体(Load → Split → Embed → Store)のことです。

6. 使うフェーズを噛み砕く

ユーザーから質問が来るところから始めます。

6.1 Retrieve — 質問に関連する chunk を取り出す

Retrieve は英語で「取ってくる」「回収する」という意味です。RAG では 「ユーザーの質問に関連しそうな chunk を、Vector DB から取り出す」 工程を指します。

具体的な流れはこうなります。

  1. ユーザーの質問テキスト(例: 「ハンバーグに玉ねぎを入れるタイミングは?」)を、同じ embedding モデル でベクトルに変換する
  2. そのベクトルと、Vector DB の中の全 chunk のベクトルとの 距離(類似度) を計算する
  3. 距離が近い順に上位 k 個 を取り出す(k=3 とか k=5 が一般的です)

この「上位 k 個」を top-k と呼びます。日本語にすれば「上位 k 件」です。

Cosine similarity(コサイン類似度)

二つのベクトルの「近さ」を測る代表的な方法です。中身は中学・高校で習う cosθ で、

  • 完全に同じ方向 → 1.0
  • 直角(無関係) → 0
  • 反対方向 → -1.0

になります。実装上は LangChain や Chroma が裏で計算してくれるので、自分で式を書くことはまずありません。「数字が大きいほど近い」とだけ覚えておけば足ります。

コードで言うと一行

実際に Chroma で検索する処理は、ライブラリを使えば本当に一行で書けます。

results = store.similarity_search_with_score(
    query="ハンバーグに玉ねぎを入れるタイミングは?",
    k=3,
)

これで「質問に近い chunk が、近い順に 3 個」返ってきます。

6.2 メタデータでフィルタするという「事前の絞り込み」

ここで重要なテクニックを一つ紹介します。

ベクトル検索は本質的に 「確率的」 です。「意味が近い chunk が上位に来てほしい」というのは、機械の判断に賭けています。賭けは外れることがあります。

賭けに頼る範囲を 最小化する ためのテクニックが、メタデータでの事前フィルタ です。

例えば、ユーザーが「カレーの作り方」を聞いてきたとします。
「料理本シリーズに絞って検索する」 ことが先に決まっているなら、ベクトル検索を走らせる前に book_category = "料理" でフィルタしておけばよいのです。

results = store.similarity_search_with_score(
    query="カレーの作り方",
    k=3,
    filter={"book_category": "料理"},  # ← この一行が重要
)

これだけで、検索対象が 100 万 chunk から 1 万 chunk に絞られたりします。
ノイズが大きく減り、精度もコストも同時に良くなります。

「ベクトル検索の前に絞れるものは絞れ」というのは、地味だけど超効く設計指針です。

6.3 Generate — 取り出した chunk を AI に渡して答えを書かせる

ここまでで、ユーザーの質問と「関連 chunk top-3」が手元にあります。これを AI(LLM)に渡して、答えを書かせる のが最後の工程です。

ユーザーが打つのは、たった一行

ユーザーがチャット欄に打ち込むのは、こんなシンプルな質問の一行だけです。

ハンバーグに玉ねぎを入れるタイミングは?

でも、AI に届くプロンプトはこれ

実際に LLM に届くプロンプト(AI への入力テキスト)は、もっとずっと長いものになっています。RAG アプリが裏側で、ユーザーの質問に「指示文」と「参考文献」をくっつけて、一つの大きな文字列に合体させてから LLM に渡します。

あなたは料理本のアシスタントです。
以下の参考文献を見て、ユーザーの質問に答えてください。

--- 参考 1 (出典: 家庭料理大全 第3章 p.42) ---
ハンバーグを作るときは、まず玉ねぎを…

--- 参考 2 (出典: 家庭料理大全 第3章 p.43) ---
肉を捏ねる前に冷やしておくと…

--- 参考 3 (出典: 料理の科学 第1章 p.18) ---
玉ねぎの甘みを引き出すには…

ユーザーの質問: ハンバーグに玉ねぎを入れるタイミングは?

回答は、上の参考文献に基づいて答え、どの参考を見たかも示してください。

これを受け取った LLM が、参考文献を踏まえて答えを返します。

大事なポイント:プロンプトを「組み立てる」のは LLM ではなく、RAG アプリ

ここはとても誤解されやすいので、はっきりさせておきます。

「LLM が必要に応じて検索してきて、自分でプロンプトを組み立てる」わけではありません。
基本的な RAG では、プロンプトを組み立てるのは RAG アプリ(プログラム側)の仕事 で、LLM は組み立てられた文字列を「読んで答える」だけ、というシンプルな役割分担になっています。

時系列でいうと、こんな流れです。

[ユーザー] チャット欄に「ハンバーグに玉ねぎを入れるタイミングは?」と入力 → 送信
   ↓
[RAG アプリ] ① 質問をベクトル化
[RAG アプリ] ② Vector DB から関連 chunk を 3 個取り出す
[RAG アプリ] ③ 「あなたは料理本のアシスタント…」+ 参考 1〜3 + 質問 を全部つなげて、
              一つの大きなプロンプト文字列を組み立てる
[RAG アプリ] ④ そのプロンプトを LLM の API に送信
   ↓
[LLM] 答えを返す
   ↓
[RAG アプリ] ⑤ LLM の答えだけを取り出してユーザーに表示
   ↓
[ユーザー] 画面に答えが表示される

ユーザーから見えるのは 「自分が打った一行の質問」と「返ってきた答え」だけ。途中の「参考 1 はこの chunk、参考 2 はあの chunk、…」は、すべて プログラムの内部で起きている舞台裏の段取り です。

ChatGPT を普通に使うときをイメージすると分かりやすいです。あなたが入力欄に質問を打ち込むだけで、システムプロンプトや裏側の設定が、ユーザーから見えないところで AI に渡されていますよね。あれと同じことが、RAG では 「Vector DB で検索した chunk を毎回プロンプトに差し込む」 という形で行われている、というわけです。

6.4 ここまでで学んだこと

  • ユーザーの質問もベクトルに変える
  • Vector DB から「近い chunk」を上位 k 個取り出す(retrieve)
  • メタデータで事前に絞ると、精度もコストも上がる
  • 取り出した chunk を「参考文献」として AI に渡して、答えを書かせる(generate)

7. RAG パイプライン全体の流れ(おさらい)

ここまでを一枚の図にすると、こんな感じになります。

─── 準備フェーズ(一回だけ走る)───
[元の文書 (PDF, Web, ...)]
   ↓ Load
[テキスト]
   ↓ Split
[chunk たち(小さな塊)]
   ↓ Embed
[chunk のベクトル + メタデータ]
   ↓ Store
[Vector DB(インデックスが完成した状態)]

─── 使うフェーズ(質問が来るたびに走る)───
[ユーザーの質問]
   ↓ Embed(同じモデルで)
[質問のベクトル]
   ↓ Retrieve(Vector DB から近い順 top-k)
[関連 chunk]
   ↓ AI に「参考文献」として渡す
[LLM が答えを書く]
   ↓
[出典付きの回答]

これが RAG の基本形です。

8. Context Window が 1M トークンに達した今、RAG は要るのか?

8.1 まず Context Window とは何か

Context Window(コンテキストウィンドウ) は、AI が一度に読める文章の長さ のことです。トークン数で測ります。

2023 年頃までは「数千〜数万トークン」が普通でしたが、2024-2026 にかけて爆発的に伸びて、

  • Claude Opus 4.7: 1M(100 万)トークン
  • Gemini 3.5 Flash 1M トークン

というレベルに達しました。日本語の長編小説 1〜2 冊や、技術書数冊が 丸ごと一度に読み込ませられる 規模です。

8.2 「全部入れちゃえばよくない?」という問い

ここで自然に出てくる疑問があります。

1M トークン入るなら、関連文書を全部 context に詰めて投げれば、検索なんて要らないんじゃ?

実際、SNS では「RAG is dead(RAG は終わった)」みたいな煽り記事が定期的に流れます。

しかし、結論から言うと RAG は消えません。理由を四つに分けて説明していきます。

8.3 理由 ①:Lost in the Middle(中央読み落とし問題)

2023 年に Stanford の Liu らが発表した論文 "Lost in the Middle: How Language Models Use Long Contexts" (arXiv:2307.03172) が指摘した現象です。論文の主張はこうです。

"Performance is often highest when relevant information occurs at the beginning or end of the input context, and significantly degrades when models must access relevant information in the middle of long contexts."

訳: 「長い文脈の中で、関連情報が最初か最後にあるときは AI の性能が高く、真ん中にあるときは大きく性能が落ちる」

性能をグラフにすると U 字 になります。両端は高く、中央が凹みます。

これは最新のモデルでも完全には解決されていません。Gemini 1.5 Pro が「解決した」と話題になりましたが、その後の独立評価で「やはり中央は弱い」と再確認されています。

つまり、「1M トークン入る」と「1M トークン全部を均等に使える」はイコールではない、ということになります。

8.4 理由 ②:コスト

context にトークンを詰めれば詰めるほど、お金がかかります。

雑な計算をしてみます。Claude Opus クラスのモデルで 1M トークン × 1 リクエスト = 数ドル規模。質問が 10 万件来たら、それだけで数十万ドルになります。

RAG で top-3 の chunk(合計 3000 トークンくらい)だけ送れば、コストは数百分の一に下がります。

「Prompt Cache」(同じ context を 2 回目以降は安く扱う仕組み)でだいぶ緩和されますが、それでも RAG のほうが安いのは変わりません。

8.5 理由 ③:レイテンシ(応答速度)

1M トークンのプロンプトを処理させると、AI が最初の単語を返してくるまでに 数秒〜十数秒 かかります。
チャット UI に乗せて「ユーザーが待てる速度」かというと、無理なケースが多くなりがちです。

RAG で送るトークン数を絞れば、応答速度は劇的に上がります。

8.6 理由 ④:引用可能性(attribution)

これがあまり語られないですが、重要なポイントです。

RAG では「どの chunk を引いて答えたか」が 構造的に分かります。chunk_id・出典・ページを渡し、AI に「どれを使ったか出力して」と指示すれば、回答の根拠が辿れます。

一方、全文をぶち込んで答えさせると、「回答のどこが、参考のどのページに対応するか」が 原理的に追跡できません

医療・法務・教育のように「なぜそう書いた?」に答えられないと困る領域では、これは決定的な差になります。

8.7 最新研究の結論:「RAG vs Long Context」ではなく「RAG + Long Context」

2025 年に arXiv:2501.01880 で発表された比較研究 "Long Context vs. RAG for LLMs: An Evaluation and Revisits" の結論を要約すると、

  • QA(質問応答)では Long Context が RAG を上回る傾向 がある(Wikipedia 系で顕著)
  • ただし 対話ベース・一般的な質問では RAG に利点 がある
  • chunk ベースの素朴な RAG は劣りますが、要約ベースの検索は long context と同等

つまり、「全部入れる」より「良いものを選んで入れる」ほうがしばしば強い ということになります。これは直感に反しますが、考えれば自然です。ノイズが多いほど AI はそれに気を取られてしまうので、retrieval は「容量制約への妥協」ではなく、「ノイズを除いてシグナルを濃くする」フィルタ としても機能している、というわけです。

8.8 現実的な使い分け

先端的なチームが採用している構図は、「どちらか」ではなく 「ルーティング」 になります。

  • 単純・局所的なクエリ → RAG(「この材料の代用品は?」「この用語の意味は?」)
  • 複雑・横断的なクエリ → Long Context(「この資料全体を読んで方針をまとめて」)

8.9 まとめ:1M context が来ても RAG は要る

「Long Context が来たから RAG 不要」は、

  • 文書集が小さい(1M 以内)
  • 引用・出典が要らない
  • コストもレイテンシも気にしない

三つが全部揃ったときだけ正しい ということになります。実プロダクトでこの三拍子が揃うことは、むしろ稀です。

9. 【おまけ】RAGの色々な派生の流れ

RAGは2024年から派生で覆い尽くされています。ざっくり説明していきます。

9.1 Contextual Retrieval(Anthropic, 2024)

Claude を作っている Anthropic 社が 2024 年に発表した改善手法です。

問題意識: ふつうの chunk は「文脈」を失います。

例えば「この会社の売上は 3% 増加した」だけの chunk があっても、どの会社のどの四半期の話か が分からず、検索の精度が下がります。

解決策: embedding を作る前に、chunk の前に「この chunk は何の話か」を一文添える というものです。

(オリジナル chunk)
「売上は 3% 増加した」

(contextual な chunk)
「これは ACME 社の 2023 年 Q2 の業績についての記述。前の段落では原価率の悪化を述べていた。
売上は 3% 増加した」

公式の評価結果はこうなっています。

  • Contextual Embeddings 単独: 検索失敗率 35% 削減(5.7% → 3.7%)
    • Contextual BM25(キーワード検索)併用: 49% 削減(5.7% → 2.9%)
    • Reranking 追加: 67% 削減(5.7% → 1.9%)

「全 chunk に文脈を付けるのって AI を全 chunk に走らせるんでしょ、高くない?」という疑問には、Prompt Cache を使えば $1.02 / 1M document tokens まで下がる という Anthropic の試算があります。

9.2 GraphRAG(Microsoft, 2024)

Microsoft Research が提案した 「知識グラフ」を使う RAG です。

公式の表現はこうです。

"GraphRAG is a structured, hierarchical approach to Retrieval Augmented Generation."

ふつうの RAG は「散らばった chunk から関連箇所を集める」のが基本ですが、

  • 「この本全体のテーマは?」
  • 「複数の章を横断する関係性は?」

みたいな 「点と点を繋ぐ」「全体俯瞰」 が苦手です。Microsoft の公式ページでもこの弱点を "struggles to connect the dots" と表現しています。

GraphRAG はインデックスの段階で、

  1. テキストを細かく分割する
  2. AI で 「人物・場所・概念などのエンティティ」と「それらの関係」 を抽出する
  3. Leiden アルゴリズム という手法でエンティティをクラスタにまとめる
  4. 各クラスタの要約を生成する

を行い、クエリ時に「ローカルな質問(一つのエンティティから派生)」と「グローバルな質問(クラスタの要約を使って全体俯瞰)」を使い分けます。

9.3 Self-RAG(2023)

「AI 自身が、いま retrieve すべきか、retrieve した結果を使うべきか、を判断する」 スタイルです。

訓練時に特殊なトークン(Retrieve するか、結果が IsRel(関連あり)か、IsSup(裏付けあり)か、IsUse(有用)か)を AI に出力させ、retrieve が要らない一般質問では呼ばないようにします。

9.4 Corrective RAG / CRAG(2024)

「retrieve 結果が悪かったら、軌道修正する」 RAG です。

  • retrieve 結果が良い → そのまま使う
  • 微妙 → 質問を書き直して再度 retrieve
  • ダメ → Web 検索など外部にフォールバック

「変な chunk が引かれたまま、それを真に受けて答える」リスクを下げます。

9.5 Agentic RAG(2024-2026)

AI が retrieve を「自分の道具のひとつ」として、必要に応じて何度でも呼ぶ スタイルです。

ふつうの RAG は「一発検索 → 一発生成」ですが、Agentic RAG は

質問 → AI が考える → 検索 1 → 結果を見て考える → 検索 2 → … → 回答

のように、AI が能動的に検索を呼び出すループになります。

9.6 retriever(検索器)の定番ラインナップ + Reranker

retriever(検索器) のバリエーションを整理しておきます。「retriever」というのは、RAG の中で 「ユーザーのクエリから関連 chunk を引いてくる」役割の総称 で、実装には大きく 3 系統があります。

① Sparse Retriever(キーワードベース)

字面の一致」で引く古典派です。

名前 ひとこと
BM25 現代の事実上の標準。TF-IDF を改良したもので、「珍しい単語ほど重く、長い文書ほど割引」みたいな考え方でスコアを付ける
TF-IDF BM25 の前身。ほぼ歴史的な存在
  • 強い: 固有名詞・型番・略語・コード名・人名("GPT-4o"、"ISO-9001" のように字面一致が必要なもの)
  • 弱い: 言い換え(「車」と「自動車」が別物扱いになる)

② Dense Retriever(意味ベクトルベース)

この記事のメインで紹介してきた、embedding を使う 系です。

名前 ひとこと
DPR (Dense Passage Retriever) RAG 原論文で使われた、BERT 系の bi-encoder
Sentence-BERT / SBERT 文章を直接 embedding する古典
Cohere embed-multilingual-v3 商用、多言語に強い
OpenAI text-embedding-3 商用、汎用
Voyage embed 商用、医療・法務などの専門コーパスに強い
E5 / BGE / GTE オープンソースで高性能、人気
  • 強い: 言い換え、パラフレーズ、概念的に近いもの
  • 弱い: 字面一致が必要なケース(固有名詞・型番)

③ Hybrid Retriever(混合)

①と②を 両方走らせて、スコアを統合する 系です。

  • スコアを単純加重平均する(データごとに重要度が異なる場合に、その重要度を加味して算出する平均値)
  • RRF(Reciprocal Rank Fusion, 逆順位融合): 順位ベースで統合する有名アルゴリズム
  • Pinecone / Weaviate / Elasticsearch / Vespa などが標準でサポート

「キーワード命中も、意味的近さも、両方拾える」両取り戦略 です。プロダクションで一番安定するので、近年は実質これがデファクトになっています。

そして上に乗せる Reranker(再ランク付け)

①②③のどれを使うにしても、その上に乗せる 「精度をもう一段上げる」定番テクニックReranker(再ランク付け) です。

仕組みはシンプルで、

  • retriever が top-k を 一旦広めに 取る(例えば top-20)
  • そのあと、別のモデル(cross-encoder)が「クエリと chunk のペア」を一個ずつ精密にスコアリング して、本物の top-3 を選ぶ

という「広く拾って、丁寧に絞る」二段構えになります。Cohere Rerank、Voyage Rerank、bge-reranker などのモデルがあり、精度向上のコスパが一番良い ので、まず最初に検討する打ち手として広く採用されています。

ざっくりの選び方

  • まず始める: ②Dense 単体(例: Chroma + Cohere embed)
  • キーワード命中も必要な業務(固有名詞・型番が多い): ③Hybrid に切り替える
  • 精度をもう一段上げたい: 上に Reranker を載せる

実プロダクションで使われる構成は、たいてい 「Hybrid + Reranker」が土台 になっていて、必要に応じて Multi-Query Retriever / HyDE / Self-Querying Retriever のような賢い retriever を足す、というレシピが王道です。

9.7 流れの整理

ざっくり時系列で並べると、こうなります。

  • 2020-2023: 「RAG = ベクトル検索 + 生成」というシンプルな形
  • 2024: Contextual Retrieval、GraphRAG、Reranker などの 「retrieval の質を上げる」 派生が広がる
  • 2025-2026: Long Context が一般化し、「RAG vs Long Context」論争を経て、ルーティングが主流に。Agentic RAG として 「AI 自身が検索を呼ぶ」 が標準パターン化

RAG はもう「一個の手法」ではなく、「検索 × 生成 × 推論を組み合わせる設計領域」になっている、というのが現在地の総括になります。

10. 【おまけ】LangChainについて

10.1 そもそも LangChain とは何か

LangChain は、LLM を使ったアプリを作るためのライブラリ/フレームワークです。Python 版が主流(JavaScript 版もあります)です。

何ができるかというと、

  • 各 LLM サービス(OpenAI / Anthropic / Bedrock など)を 同じインターフェース で叩ける
  • 文書の読み込み・分割・embedding・Vector DB 連携が 既製品の部品 として揃っている
  • それらを つなげてパイプラインを作る ための仕掛けがある

要するに 「LLM 周りの "配線" を全部抽象化したい」 という野心的なフレームワークになります。

10.2 受けている批判

2024-2026 にかけて、LangChain には強い批判が集まっています。

  • 抽象化が厚すぎて、デバッグが内部に潜る: バグを追うと、自分のコードじゃなく LangChain の内部実装を読まされることになりがちです
  • バージョンの非互換が頻発する: 0.0.x → 0.1 → 0.2 …で、書き直しを強いられます
  • 型安全性が弱い: dict ベースで流れているデータが多く、IDE 補完が効きません
  • **「動くけどなぜ動くか分からない」 **: 製品として安定運用するときに blocker になりがちです

これは個人の感想ではなく、2025 年時点で 業界で広く共有された不満 で、結果として代替フレームワークが大量に生まれています。

10.3 Anthropic 公式の立場:「フレームワークより API 直叩き」

ここが面白いポイントで、Claude を作っている Anthropic 自身が、2024 年末の研究記事 "Building effective agents"フレームワークに距離を置いています

公式の表現はこうです。

"We suggest that developers start by using LLM APIs directly: many patterns can be implemented in a few lines of code."

訳: 「開発者はまず LLM の API を直接叩くことから始めることを推奨する。多くのパターンは数行のコードで実装できる」。

フレームワーク全般については、こう書いてあります。

"They often create extra layers of abstraction that can obscure the underlying prompts and responses, making them harder to debug."
"They can also make it tempting to add complexity when a simpler setup would suffice."

訳: 「フレームワークはしばしば追加の抽象化レイヤを作り、内側のプロンプトや応答を見えにくくし、デバッグを難しくする」「シンプルな構成で済むのに、複雑さを足したくなる誘惑を生む」。

そして、

"If you do use a framework, ensure you understand the underlying code."

訳: 「フレームワークを使うなら、その内側のコードを理解した上で使え」。

これは LangChain を名指しで否定しているわけではないですが、「最小から始めて、抽象化が明らかにメリットを生むときだけ複雑性を足せ」 という強いメッセージになっています。

10.4 代替候補(2025-2026)

ツール 立ち位置
生の SDK を直叩きanthropic, openai パッケージ) Anthropic 公式が一番に推す出発点。シンプル、依存最小、抽象化なし
LlamaIndex もともと RAG 特化。データの取り込み・検索の表現力に強み
Pydantic AI 2025 年に v1.0 リリース。型安全・構造化出力に振った代替
LangGraph LangChain 同チームの後継。状態を持つ複雑な agent 向け
DSPy プロンプトを「最適化対象」として扱う学術寄りのフレームワーク
Claude Agent SDK Anthropic 公式の agent 構築 SDK

10.5 結論:LangChain の「便利な部分」だけ薄く使う

便利な部分を局所的に使うのは良いですが、プロジェクトの「中心」(プロンプト・評価・コスト計算・ドメインのルール)は LangChain に乗せない のが良さそうです。乗せた瞬間、フレームワークのバージョンアップや縛りが、自分のプロダクトの足を引っ張り始めます。これは結局、Anthropic の「フレームワークを使うなら内側を理解した上で」という助言を、コードで体現することと同じです。

11. まとめ — 用語と論点のおさらい

この記事で出てきた用語

用語 ひとことで言うと
LLM ChatGPT / Claude / Gemini の中身、大規模言語モデル
Hallucination AI がもっともらしく嘘を言う現象
RAG 外の文書を検索 → AI に渡して答えさせる仕組み
Chunk 長い文書を分割した、小さなテキスト塊
Embedding 文章を「数の並び(ベクトル)」に変換すること
Vector / ベクトル 数字を一列に並べたもの。意味の近さを距離で測れる
Vector DB ベクトルを保存・近いものを検索できる特殊な DB
Metadata データに付ける付加情報(書籍名・章・ページなど)
Index / Indexing 検索しやすい形に整理する作業、またはその状態
Retrieve / Retrieval 関連 chunk を取り出す検索工程
top-k 上位 k 件(よく k=3 や k=5)
Cosine similarity ベクトル同士の近さを測る代表的な計算
Token / トークン AI が文章を扱う最小単位
Context Window AI が一度に読める文章の長さ
Prompt AI に渡す入力テキスト
Citation 引用、出典の明示

結論

  1. 1M context が来ても RAG は要るのか?
    → 要ります。Lost in the Middle・コスト・レイテンシ・引用可能性の四点で、retrieval は依然合理的です。実務的には RAG と Long Context のルーティングが主流になっています。

  2. RAG の現在地は?
    → シンプルな「ベクトル検索 + 生成」から、Contextual Retrieval / GraphRAG / Self-RAG / Corrective RAG / Agentic RAG / Reranker と派生が爆発。「検索 × 生成 × 推論を組み合わせる設計領域」 に拡張されました。

  3. LangChain は要るのか?
    → 「全部使う」のはアンチパターンです。Anthropic 公式も「API 直叩きから始めろ」と言っています。便利な部分だけ Adapter として薄く採用し、プロジェクトの中心は自前で持つのが現実解になります。

最後に

RAG は「魔法」ではありません。データの 読み込み・分割・ベクトル化・検索・プロンプト という、それぞれが独立に既存技術として枯れている要素を、目的のために繋ぎ直すフレームワークです。

逆に言えば、各層を独立に評価・差し替えできる構造で組むこと ができれば、最新の派生手法(Contextual Retrieval、GraphRAG、Reranker、Agentic …)はすべて、後から薄く乗せられるようになります。

「RAG は終わった」も「LangChain で全部解決」も、どちらも極端な物言いです。
現場の判断は常に、層ごとの細かい意思決定の積み重ね でしかありません。

この記事が、その意思決定の入り口になれば嬉しいです。

参考文献

15
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?