RAGとは ― RAGにおける検索の考え方(ベクトル検索とは)
はじめに
前回はRAGの概念と、なぜ必要かを説明しました。
「質問に答える前に、関連する情報を手元の資料から探してきて、AIに渡す」
今回はその「探してきて渡す」部分を深掘りします。RAGの処理フローを一つずつ追いながら、ベクトル検索・チャンク・精度に効くパラメータの3つを理解することがゴールです。
RAGの処理フロー(全体像)
RAGの処理は大きく2つのフェーズ(段階)に分かれます。
フェーズ1:インデックス構築(事前準備)
インデックス構築とは?
RAGの検索システム構築においてインデックス構築が生命線です。ここの精度が高くないとフェーズ2のクエリ実行でどんなに工夫をしても期待した回答が返ってきません。
この処理は、最初に一度だけ行います。資料を追加・更新するたびに再実行します。
フェーズ2:クエリ実行(質問への回答)
実際の運用フェーズです。フェーズ1で生成したベクトルDBなどをもとに回答を得ます。
ベクトル検索とは
テキストを「数値の羅列」に変換する
「ベクトル検索」という言葉を聞くと難しそうに感じますが、やっていることは意外とシンプルです。
テキストを数値の羅列(ベクトル)に変換して、数学的な「距離」で類似度を測る
これだけです。
ベクトルとは?
数学用語ですが、ここでは「テキストの意味を表す数値のリスト」と思ってください。例えば[0.82, 0.41, 0.67, ...]のような数百個の数字の並びで、テキスト1つを表現します。意味が似ているテキストほど、数値のパターンも似てきます。
たとえば「犬」「猫」「飛行機」というテキストがあったとします。「犬」と「猫」は意味的に近く、「飛行機」は遠い。ベクトル検索では、この「意味の近さ」を数値として扱います。
「犬」 → [0.82, 0.41, 0.67, ...] ← 数百〜数千個の数値
「猫」 → [0.79, 0.38, 0.71, ...] ← 「犬」と似た値
「飛行機」→ [0.12, 0.95, 0.04, ...] ← 離れた値
テキストをベクトルに変換する専用のAIモデルをエンベディングモデル(Embedding Model) と呼びます。ChatGPTのような「回答を生成するモデル」とは別物で、「意味を数値化することに特化したモデル」です。
キーワード検索との違い
従来の全文検索は、「同じ単語が含まれているか」でマッチングします。
| 検索方法 | 仕組み | 得意・不得意 |
|---|---|---|
| キーワード検索(BM25) | 単語の一致で探す | 表記ゆれ・同義語に弱い |
| ベクトル検索 | 意味の近さで探す | 多少の言い換えにも対応できる |
たとえば「会議の予定を変更したい」という質問で「スケジュール調整の手順」というドキュメントを見つけるのは、キーワード検索では難しい。「会議」と「スケジュール」、「変更」と「調整」という同義語が一致しないからです。しかしベクトル検索なら「会議の予定変更≒スケジュール調整」という意味の近さを捉えられます。
チャンクとは
チャンク(chunk)とは?
英語で「かたまり」という意味です。RAGでは、長い文書を小さな意味のまとまりに切り分けたものをチャンクと呼びます。
なぜドキュメントを分割するのか
分割する理由は主に3つです。
① LLMのコンテキスト長に制限がある
LLMが一度に受け取れるテキスト量には上限があります。巨大なPDFをまるごと渡すことはできません。
コンテキスト長とは?
AIが「一度に読める文章の長さ」の上限です。人間でいえば「ワーキングメモリ(作業記憶)」のようなもので、これを超えると古い情報を忘れてしまいます。
② 関連性の高い部分だけを渡した方が精度が上がる
100ページの資料があっても、質問に関係するのは1〜2ページかもしれません。無関係な情報を渡すと、回答の焦点がぼやけます。
③ 検索コストを下げられる
小さな単位でベクトル化・比較した方が、計算時間が短くなります。
チャンク分割のイメージ
【元のドキュメント】
第1章 はじめに............(300文字)
第2章 インストール方法....(800文字)
第3章 設定ファイルの解説..(1200文字)
...
【チャンク分割後】
チャンク1: 第1章全文(300文字)
チャンク2: 第2章前半(400文字)
チャンク3: 第2章後半(400文字)
チャンク4: 第3章前半(400文字)
...
検索精度に効くパラメータ
チャンク分割にはいくつかの設定値があり、これが検索精度に直結します。これが適切でないと回答精度が出ません。入力する文書によってこれらのパラメータの最適値が違うようで、システムが完成した後も、ずっとこれらの調整を続けています。私もまだ、最適解には至っていません・・
1. チャンクサイズ(chunk_size)
一つのチャンクに含める文字数(またはトークン数)の上限です。これが検索精度に非常に大きく影響します。
トークンとは?
AIがテキストを処理するときの「最小単位」です。日本語では大まかに「1〜2文字=1トークン」くらいのイメージで考えると近いです。
| サイズ | 特徴 |
|---|---|
| 小さい(100〜300文字) | ピンポイントな情報を返せる。文脈が切れやすい |
| 大きい(500〜1000文字) | 文脈を保ちやすい。ノイズも含まれやすい |
ノイズとは?
ここでは「質問と関係のない余分な情報」のことです。ノイズが多いと、AIが本当に必要な情報を見つけにくくなり、回答の質が下がります。
チャンクはJSONというフォーマットで出力されます。ファイルを開くと、ドキュメントの種類によってはノイズが入り込むことが分かります。
ノイズの例:
- ヘッダー・フッター・ページ番号
- 目次・索引
- 図表番号(図はチャンク対象外のため、番号だけあっても意味がない)
これらを除去しないと精度の高い回答は得られません。
目安: 技術ドキュメントや手順書は300〜500文字、FAQや短い文書は100〜200文字が出発点になることが多いようです。
2. オーバーラップ(chunk_overlap)
隣り合うチャンク間で「重複させる文字数」です。
チャンクサイズ = 400文字、オーバーラップ = 50文字 の場合
チャンク1: [ 0〜400文字 ]
チャンク2: [350〜750文字 ] ← 前のチャンクと50文字重複
チャンク3: [700〜1100文字]
重複を設けることで、チャンクの境界で文章が途切れる問題を緩和できます。大事な情報がちょうど境界線に落ちてしまうと、どのチャンクにも完全には含まれない、という事態を防ぐためです。
目安: チャンクサイズの10〜20%程度を重複させるのが一般的です。
3. Top-K
検索時に「上位何件のチャンクを取得するか」の設定です。
Top-Kとは?
「K番目まで取ってくる」という意味です。検索結果の上位K件をLLMに渡します。K=3なら「一番似ているチャンクを3つ持ってくる」ということです。
Top-K = 3 の場合
→ 質問と最も意味が近いチャンクを3件取得してLLMに渡す
| K値 | 特徴 |
|---|---|
| 小さい(1〜3) | 高精度な情報だけ渡せる。見落としが出る可能性 |
| 大きい(5〜10) | 網羅性が上がる。ノイズも増え、コストも上がる |
目安: まずはTop-3から始めて、回答の質を見ながら調整するのが無難です。
パラメータの相互作用
この3つは独立していません。たとえば「チャンクサイズを大きくした場合、Top-Kを小さくしても十分な情報量が確保できる」といった関係があります。
チャンクサイズ大 × Top-K小 → 文脈豊富・ノイズ少
チャンクサイズ小 × Top-K大 → ピンポイント複数件・ノイズ多め
正解の設定はデータとユースケース次第です。第3回・第4回では実際のコードで試しながら調整する方法も紹介します。
まとめ
今回のポイントを整理します。
- RAGの処理は「インデックス構築(事前)」と「クエリ実行(質問&回答)」の2フェーズ
- ベクトル検索は「意味の近さ」で文書を探す仕組み。キーワード検索より表現の揺れに強い
- チャンクは「LLMに渡すテキストの単位」。分割の仕方が精度に直結する
- 精度を左右するパラメータは チャンクサイズ・オーバーラップ・Top-K の3つ
次回予告
次回は、簡易サンプルで実際に動かしたいと思います。