より良い RAG を作るための Vector DB 基礎

こんにちは。エンジニアの浅見です。

今回は久しぶりに、社内のナレッジを公開いたします。 フレクトでは社内のナレッジを蓄積・共有するために「Fラボ」というツールを運用しており、以前にも「15分でわかる!Agentforce」や「15分でわかる!Salesforce で「生成AI」」を特別公開しております。

本記事では、社内のエンジニア向けに作成した AI 基礎トレーニング資料の中から「Vector Database(ベクトルデータベース)」の章を抜粋して公開します。 RAG システムを構築する上で欠かせない Vector DB の仕組みや実運用上の課題について、簡単な実験とともに解説したものとなっております。

なお本内容は社内入門者向けの教育コンテンツとなっておりますのでご了承ください。 また、記事執筆時点での内容を記載しておりますので、そちらも併せてご留意くださいますようお願いいたします。

以降、本編となります。


より良い RAG を作るための Vector DB 基礎

生成 AI の活用が進む中、RAG (Retrieval-Augmented Generation) システムの構築需要が急増しています。 RAG とは、LLM(大規模言語モデル)が持っていない知識を外部から補い、より業務に適した回答を生成させるための手法です。 私たち人間も、頭の中にない情報が必要になれば社内マニュアルを開いたり、過去の議事録を探したりします。LLM にも同じように、必要な情報を都度検索・取得して「参考資料」として渡すのが RAG の考え方です。

つまり、RAG を実現するために必要なのは、情報を保存しておくデータベースと、そこから必要な情報を適切に検索する仕組みです。その名前の通り、検索(Retrieval)によって拡張(Augmented)された生成(Generation)を行うわけですが、この「検索」のプロセスでよく使われる技術の一つが Vector Database(ベクトルデータベース) です。RAG の検索手段は Vector Database に限られるわけではありませんが、「意味の近さ」で検索できるという特性から、多くの RAG システムで中心的な役割を果たしています。

ここで、「検索なら既存の SQL(LIKE検索)や全文検索エンジンではダメなのか?」という疑問が浮かぶかもしれません。 結論から言えば、従来の検索技術だけでは不十分なケースが多く存在します。なぜなら、LLM を活用するシステムにおいては、単純な「キーワードの一致」ではなく、「意味」や「文脈」に基づいた検索が求められるからです。

本資料では、社内で実施したいくつかの技術検証(実験)の例も交えながら、Vector Database の「基礎理論」「直面する課題」「実践的な解決策」を、理想と現実のギャップを踏まえて解説します。


1. Embedding(埋め込み)の仕組みと配置の特性

1-1. キーワード検索から意味検索へ

私たちが普段業務でよく使う RDB(リレーショナルデータベース)などにおけるデータ検索は、基本的に 「キーワードの一致」 に基づいています。

例えば、社内のヘルプデスクに対して「パソコンが急に真っ暗になって動かない」という問い合わせがあったとします。 このとき、解決策が記載されたマニュアルのタイトルが「PCの画面がブラックアウトしてフリーズした場合の対処法」だった場合、RDB で LIKE '%パソコン%真っ暗%' のようなキーワード検索をしても、目的のドキュメントはヒットしません。 人間なら同じ状況を指していると分かりますが、「パソコン/PC」「真っ暗/ブラックアウト」「動かない/フリーズ」といったように使われている単語が異なる(表記ゆれ・同義語)ためです。

しかし、RAG のような LLM を活用したシステムでは、ユーザーの曖昧な質問に対しても適切な回答素材(カンニングペーパー)を探し出す必要があります。 そのためには、単なるキーワードの一致ではなく、「言葉の意味」や「文脈」を解釈し、「意味が似ているもの」を探す仕組み(意味検索) が必要になります。

それを実現するための第一歩が、テキストデータをベクトル(数値の列)に変換することであり、そのベクトルを保存し、意味検索を行うためのシステムが Vector Database なのです。

1-2. 言葉を「ベクトル(≒ 数値の配列)」として表現する

では、コンピュータはどうやって「意味」を取り扱うのでしょうか? その答えが Embedding(埋め込み表現) です。

Embedding とは、テキストデータを 多数の特徴を表す数値の列(ベクトル) に変換する技術です。

例えば、「犬」「猫」「車」という言葉を Embedding モデルに通すと、以下のような数値のリストが出力されます。 ※ 以下はあくまでも参考であり、実際の値ではないことに注意してください。

  • 「犬」: [0.12, -0.45, 0.89, -0.01, ...]
  • 「猫」: [0.10, -0.42, 0.85, -0.05, ...]
  • 「車」: [-0.88, 0.21, -0.15, 0.66, ...]

一つ一つの数値を見比べてみてください。「犬」と「猫」は、1番目の値が 0.120.10、2番目が -0.45-0.42——というように、どの位置を見ても近い数値が並んでいます。一方「車」は、1番目からして -0.88 と全く異なる値です。

ただし、「0.12」や「-0.45」といった個々の数値が人間にとって何を意味するのかは分からない という点に注意してください。「生き物らしさ」や「乗り物らしさ」といった分かりやすいパラメータが直接割り当てられているわけではありません。

それでも、数値の並び(パターン)全体で見れば、「犬」と「猫」が似ていて「車」とは全く違うことがはっきり読み取れます。これはモデルが膨大なデータから「犬と猫は同じような文脈で使われやすい」という関係性を学習し、それを数値のパターンとして表現しているからです。 このように、「意味や文脈が似ている言葉は、変換された数値のパターン全体も似てくる」 という性質を持たせることで、コンピュータが「言葉の意味」を計算可能なデータとして扱えるようになります。

そして、この数値の列は、数学的には多次元空間上の「座標」として扱うことができます。データを空間の座標に配置することから、「空間への埋め込み(Embedding)」と呼ばれています。実際のモデルでは、数百〜数千次元という人間には想像できない高次元空間でこれを表現しています。

1-3. 実際に言葉をベクトル化し、「言葉の配置」を可視化する

理屈だけではイメージしづらいかと思いますので、実際にテキストをベクトル化した結果を見てみましょう。

実際のベクトルは人間には想像できない高次元の座標ですが、ここでは私たちが視覚的に理解できるように2次元のグラフ上に無理やり押し込んで可視化してみます。 可視化することで、まずは「埋め込み」というものがどういうものかをイメージしてみましょう。 その上で、いくつかのパターンでの挙動を観察し、「埋め込み」の特性を簡単に見てみます。

実験1:動物名と色名の埋め込みプロット(意味のまとまり)

まず、様々な「色」と「動物」の名前をベクトル化して配置してみました。

動物名と色名の2次元プロット

グラフ上の点がそれぞれ一つの単語に対応しています。実際には高次元空間に埋め込まれたベクトルを、2次元に圧縮して表示したものです。

図を見ると、大きく「色(青丸)」のグループと「動物(赤丸)」のグループに分かれて配置されているのがわかります。これが「意味が似ているものは近くに配置される」という基本的な性質です。

一方で、同じ動物(赤丸)の中でも、「漢字」で書かれた動物(右下)と「カタカナ」で書かれた動物(左側)のグループがあるように見えます。このように、単語は必ずしも直感的な分類(色か動物か)だけで分かれているわけではなく、カタカナや漢字といった表記による傾向も持っているようです。

ここで注意が必要なのは、このグラフがあくまでも 高次元のベクトルから情報を削ぎ落として2次元に投影したもの であるという点です。 実際には、ここには描ききれない高次元の情報が多分に含まれており、モデルは単語をより多角的に捉えています。 逆に言えば、この2次元のグラフ上では「表記のグループ」に埋もれて区別がつかないように見える単語であっても、高次元の空間においては、別の意味的な軸によって明確に区別されている(高次元に情報が埋もれているだけである)可能性があるのです。

実験2:同一動物名の表記違いプロット(表記のクラスタリング)

先ほどの図でも「漢字」と「カタカナ」の違いが見られましたが、この傾向をもう少し詳しく見るために、同じ動物の名前を「漢字」「ひらがな」「カタカナ」「英語」の4種類の表記でベクトル化して配置してみました。

動物の名前(表記別)のプロット

図を見ると、見事に表記ごとにグループ(クラスタ)が形成されていることがわかります。 英語のグループが離れているのはある程度納得できますが、同じ日本語であるにもかかわらず、「漢字」「ひらがな」「カタカナ」でもそれぞれが明確に別の群れを作っています。

これは、Embedding モデルが「意味」だけでなく、「どのように表記されているか」という情報も一つの特徴として捉えていることを示しています。 実際に私たちが普段使う日本語においても、あえて「漢字」で書くか「ひらがな」で書くかで、文章の硬さや微妙なニュアンス、使われる文脈が異なることがあります。モデルが膨大なデータからそういった文脈の違いまで学習していると解釈することもでき、興味深い結果です。 ただ、同じ意味でも複数の表記が自然に混在する日本語のドキュメントを検索する上では、この特性が「検索漏れ(表記ゆれによるスコア低下)」の要因になり得るため、注意が必要です。

ちなみに、今回のような検証用の Python コードは、Cursor などの AI エディタに「〇〇をベクトル化して2次元にプロットするコードを書いて」と指示するだけで簡単に作成してくれます。興味がある方は、ぜひご自身の好きな単語で試して、言葉が空間に配置される感覚を味わってみてください。


2. 意味検索の仕組み

2-1. 空間上の「近さ」を「類似度」として計算する

前章で見たように、Embedding モデルは言葉を空間上に配置し、「意味が近いものは座標も近くなる」という性質を持っています。 Vector Database では、この空間上の「近さ」を計算することで、データ同士がどれくらい似ているかを数値化します。これを 「類似度(Similarity)」 と呼びます。

ベクトル化されたデータ同士の類似度を計算する際、最も一般的に使われる指標が コサイン類似度(Cosine Similarity) です。

数学的な言葉を使えば「ベクトルの内積をノルムで割ったもの(=なす角の余弦)」となるのですが、これでは少し難しく聞こえてしまうかもしれません。 もっと直感的にイメージしてみましょう。

空間の原点(中心)から、それぞれの単語の座標に向かって矢印(ベクトル)を引いたと想像してください。 コサイン類似度は、この 「2つの矢印がどれくらい同じ方向を向いているか(=角度の狭さ)」 を数値化したものです。

  • 矢印が全く同じ方向を向いている(角度が0度): スコアは 1.0(最も似ている)
  • 矢印が直角に向いている(角度が90度): スコアは 0.0(類似性が見られない)
  • 矢印が真逆の方向を向いている(角度が180度): スコアは -1.0(最もかけ離れている)

これはあくまでコサイン類似度の数学的な定義範囲です。実際の Embedding モデルでは、後述する空間の偏り(異方性)の影響もあり、スコアが 0 付近や負の値を取ることはほとんどありません。また、「好き」と「嫌い」のような意味的に反対の言葉であっても、使われる文脈が似ているためスコアが高く出る傾向があるなど、「スコアが低い=意味が反対」という単純な対応にはなりません。

データの絶対的な「数値の大きさ(矢印の長さ)」は無視して、純粋に「空間上のどの方向を向いているか(意味の方向性)」だけで近さを判定できるため、テキストの意味検索において非常に相性が良く、広く使われています。

2-2. 類似度の可視化

ここで、前章でプロットした単語群を使って、実際にどの程度の「類似度」として計算されるのかを見てみましょう。 以下の図は、単語同士のコサイン類似度を総当たりで計算し、色が赤いほどスコアが高い(似ている)ことを示すヒートマップです。

実験3:動物名と色名の類似度ヒートマップ

まずは「動物」と「色」のグループです。

動物と色の類似度ヒートマップ

図の左上のブロック(動物同士)と、右下のブロック(色同士)が赤くなっていることがわかります。 例えば、「ライオン」と「カバ」の類似度は 0.92 と高いですが、「ライオン」と「赤」では 0.87 と相対的に低くなっています。 このように、ベクトルの近さをコサイン類似度で計算することで、「意味が似ているかどうか」を定量的に判別できることがわかります。

実験4:同一動物名の表記違いによる類似度ヒートマップ

次に、日本語(漢字)と英語における動物名の比較です。

動物名の表記違いによる類似度ヒートマップ

「犬」と「猫」という全く違う動物の類似度が 0.94 であるのに対し、同じ意味であるはずの「犬」と「Dog」の類似度は 0.91 に留まっています。

これも前章で見た「表記によるクラスタリング」が数値として表れた結果です。意味は全く同じでも、表記(言語)が異なるだけでスコアが下がってしまうため、実務において多言語が混ざるドキュメントを検索する際には、「犬で検索したのにDogのドキュメントが上位に出てこない(猫の方が上に来てしまう)」といった事態が起こり得ることを示唆しています。

[コラム] なぜ類似度がすべて 0.8 以上と高く出るのか?

ヒートマップを見ると、関係のない「ライオン」と「茶色」でも 0.85 という比較的高いスコアが出ています。これは深層学習ベースの Embedding モデル特有の「ベクトル空間の異方性(Anisotropy)」と呼ばれる現象です。

理想的にはデータが空間全体にまんべんなく散らばってほしいのですが、実際のモデルは「すべてのデータが特定の狭い方向(空間の一部)に偏って配置される」という強い癖を持っています。例えるなら、地球上のすべての都市が北極点の周辺だけに密集しているような状態です。このため、中心から見るとどの単語も「大体同じ方向」を向いているように判定され、ベースとなるスコアが底上げされてしまうのです。

これは、実務において「大正解の文書(0.92)」と「ギリギリ不正解のノイズ文書(0.88)」のスコア差がわずか 0.04 しか開かないといった「スコアの分解能の低さ」に直結し、検索結果にノイズが混入する大きな原因となります。

[コラム] なぜ「ユークリッド距離」ではなく「コサイン類似度」なのか?

2つのベクトルの近さを測る方法は、コサイン類似度だけではありません。直線距離で測る「ユークリッド距離」も一般的な手法です。では、なぜ意味検索ではコサイン類似度が好まれるのでしょうか。

ユークリッド距離はベクトルの「長さ(ノルム)」の影響を直接受けます。高次元空間では、ノルムが小さいベクトルが他のあらゆるベクトルから「距離が近い」と判定されやすくなる Hubness(ハブネス)現象 が知られており、特定のデータが検索上位を独占してしまう原因になります。

一方、コサイン類似度はベクトルの長さを正規化し、純粋に「方向」だけを比較します。同じ内容でも文章の長短によってノルムが変わり得る意味検索において、長さの影響を排除できる点が大きな利点です。

2-3. 「単語」から「文章」の埋め込みへ

ここまでの内容を振り返ってみましょう。

  • 言葉を数値の配列(ベクトル)として表現し、意味的に近いものが空間上でも近くに配置されることを確認しました
  • コサイン類似度を使って「近さ」を数値化し、キーワードの完全一致に頼らない「意味検索」の仕組みを見てきました

従来のキーワード検索とはまったく異なるアプローチであり、その有用性は感じていただけたのではないかと思います。

一方で、限界も見えてきました。同じ意味の単語でも表記が異なると類似度が下がる傾向があること、ベクトル空間の異方性によってスコアの分解能が低くなること——こうした課題は、実用上無視できないものです。

そして重要なのは、ここまでの話はあくまで 「単語」レベル だったということです。 実際の RAG システムで私たちがベクトル化して検索したいのは、単語ではなく、複数の単語からなる 「文章(ドキュメント)」 です。単語レベルですらこれだけの複雑さがあるなかで、文章を一つのベクトルにまとめて、同じように意味検索ができるのでしょうか?

次の章では、この問いに向き合っていきます。


3. 文章の埋め込みと実践的な意味検索

3-1. 文章のベクトル化の仕組み

前章の最後に、「文章を一つのベクトルにまとめて意味検索ができるのか?」という問いを立てました。 では、複数の単語からなる文章は、どのようにして一つのベクトルに変換されるのでしょうか。

多くの Embedding モデルでは、おおまかに以下のような流れで文章をベクトル化しています。

  1. 入力された文章を 「トークン」 と呼ばれる単位に分割する
  2. 各トークンに対して、前後の文脈を考慮したベクトルを生成する
  3. 得られた全トークンのベクトルを統合(Pooling)し、一つの「文章ベクトル」にまとめる

例えば「私はペンを持っている」という文章であれば、「私」「は」「ペン」「を」「持っ」「ている」といったトークンごとにベクトルが生成され、最終的にそれらが一つの文章ベクトルに集約されます。

では、実際の RAG システムではどのようなテキストがベクトル化されるのでしょうか。1章のヘルプデスクの例で考えてみましょう。

保存する側(ドキュメント) には、社内マニュアルや FAQ 記事、手順書などのテキストが入ります。 ただし、長いドキュメントをそのまま丸ごとベクトル化するわけではありません。Embedding モデルには入力可能なトークン数に上限がありますし、文章が長くなるほど平均化によって情報が薄まり、検索精度が落ちてしまいます。そのため、ドキュメントをあらかじめ適切な長さの断片に分割してからベクトル化します。この分割処理を チャンク化(Chunking) と呼び、RAG システムの検索精度を左右する重要な前処理工程の一つです。

最もシンプルな構成では、社内マニュアルの1セクションをそのままチャンクとして保存します。

「PCの画面がブラックアウトしてフリーズした場合は、まず電源ボタンを10秒間長押しして強制シャットダウンを行い、30秒待ってから再起動してください。それでも改善しない場合は、ヘルプデスク(内線 1234)までご連絡ください。」

検索する側(クエリ) には、ユーザーの質問がそのまま入ります。

「パソコンが急に真っ暗になって動かない」

この両者がそれぞれ同じ仕組みで一つのベクトルに変換され、コサイン類似度によってマッチングされます。キーワードが一つも一致していなくても、意味的に近ければヒットする——これが意味検索の全体像です。

ステップ3の Pooling にはいくつかの方式がありますが、最も一般的なのが全トークンのベクトルを単純に平均する Mean Pooling です。 では、この仕組みで文章をベクトル化した場合、文脈はどの程度考慮されるのでしょうか。

実験5. 文章にすると文脈が考慮される

2章では、単語レベルでは表記(文字の共通性)に引っ張られやすいことを確認しました。 文章になった場合、前後の文脈が加わることで、同じ文字を含んでいても意味の違いを区別できるようになるのでしょうか?

ここでは、同じ 「象」 という文字を含みながら意味が異なる文章群を用意し、類似度を比較してみました。

同形異義語と文脈の類似度ヒートマップ

左上のブロックに注目してください。「象が走る」「象が泳ぐ」「象が飛ぶ」はいずれも動物の「象」を主語とした文章であり、互いの類似度は 0.95〜0.98 と非常に高くなっています。

一方、右下のブロックの「対象となる」「現象が起きる」「印象に残る」は、同じ「象」の字を含んでいますが、ここでの「象」は動物ではなく抽象的な概念の一部です。このグループ内の類似度は 0.88〜0.89 で、動物の「象」グループとの間(0.85〜0.88)には明確な差が見てとれます。

これは、Embedding モデルがステップ2で各トークンのベクトルを生成する際に、前後のトークンの情報を反映させているためです。同じ「象」という文字であっても、「〜が走る」という文脈で使われた場合と「対〜となる」という文脈で使われた場合とでは、生成されるベクトルが異なります。

文章レベルの Embedding は単語の単純な寄せ集めではなく、文脈を踏まえた表現になっていることが確認できました。

3-3. 実験6. 文章が長くなると意味が希釈される

3-2 では、短い文章であれば文脈によって意味の違いを区別できることを確認しました。 では、文章が長くなった場合はどうでしょうか?

実際の社内ナレッジベースには、免責事項や「本件については〜」のような定型フレーズ、「DX推進」「コンプライアンス」といったどの文書にも現れる語彙が多く含まれています。Mean Pooling は全トークンのベクトルを等しく平均するため、こうした定型的な成分が文書の本来の主題を圧迫してしまう可能性があります。

これを確認するため、3-2 と同じ「象が走る」「対象となる」をベースに、業務文書でよく見かける定型文を段階的に付け足していき、類似度がどう変化するかを観察してみましょう。

定型文の追加による意味の希釈

まず、左上と右下の対角ブロックに注目してください。「象が走る」系(左上)と「対象となる」系(右下)は、それぞれのグループ内で高い類似度を示しています。ここまでは 3-2 と同様です。

問題は、定型文を追加するにつれて グループ間の境界が曖昧になっていく 点です。

ベースの「象が走る」と「対象となる」の類似度は 0.87 でした。ところが、両方に同じ定型文を1段階追加すると 0.94、2段階追加しても 0.94 と、本来別の意味の文同士が大幅に接近しています。

さらに注目すべきは、逆転現象 が起きていることです。

  • 「象が走る(+定型文)」と「対象となる(+定型文)」の類似度: 0.94
  • 「象が走る(+定型文)」と自分自身の原義「象が走る」の類似度: 0.89

つまり、定型文が付いた「象が走る」にとって、意味的には全く異なる「対象となる(+定型文)」の方が、自分自身の原義よりも「近い」と判定されてしまっています。定型文×2 ではこの差は 0.940.87 とさらに開きます。

これが Mean Pooling の「平均化」による情報の希釈です。全トークンを等しく平均するため、文章が長くなるほど定型文のベクトル成分が支配的になり、本来の主題の成分が埋もれていきます。

3-4. ベクトル検索だけでは足りない

ここまでの実験を整理しましょう。

  • 文脈は考慮される(3-2): 短い文章であれば、同じ文字を含んでいても文脈から意味の違いを区別できる
  • しかし、情報は希釈される(3-3): 文章が長くなると Mean Pooling による平均化で主題が埋もれ、定型文やノイズに支配されてしまう

ベクトル検索は「意味の近さで検索できる」という従来にない能力を持つ一方、単体での運用には明確な限界があります。では、これらの課題に対して実務ではどのような対策が取られているのでしょうか。


4. 実用的な課題と対応策

ここでは、RAG システムのパイプラインに沿って「データを入れる段階」「検索する段階」「結果を精査する段階」の3つに分けて整理します。

4-1. データの入れ方を工夫する

検索精度は、検索アルゴリズムだけでなく 「どのようなデータを入れるか」 に大きく左右されます。

チャンク化戦略

3章で触れた通り、ドキュメントは適切な長さに分割(チャンク化)してからベクトル化する必要があります。文章が長くなるほど Mean Pooling による情報の希釈が進むため、チャンクの粒度は検索精度に直結します。

例えば、社内マニュアルの1ページに「VPN 接続手順」と「メール設定手順」が両方含まれている場合、そのままベクトル化すると「VPN もメールもそこそこ近い」という中途半端なベクトルになります。トピックごとにチャンクを分けておけば、「VPN がつながらない」という問い合わせに対して VPN の手順だけが的確にヒットしやすくなります。

分割が細かすぎると文脈が失われ、粗すぎると希釈が進む——このバランスは扱うデータの性質によって異なるため、実際に試しながら調整していくことになります。

LLM による正規化・要約

2章で確認した「表記ゆれ」の問題に対しては、データを入れる段階での工夫が有効です。 例えば、障害報告が「サーバが落ちた」「本番環境ダウン」「production で 503 出てる」と書き手によってバラバラだと、どのキーワードで問い合わせが来るかによってヒットしたりしなかったりします。これらを LLM で「本番サーバーの障害(HTTP 503)」のように統一した表現に書き直してからベクトル化すれば、表記ゆれに強いデータベースになります。

4-2. 検索の仕組みを工夫する

ベクトル検索は「意味の近さ」に強い一方で、型番や固有名詞などの「完全一致」が求められるケースには不向きです。 そこで、従来のキーワード検索(BM25 等)とベクトル検索を組み合わせる ハイブリッド検索 が、現代の RAG システムでは標準的なアプローチとなっています。

例えば、ヘルプデスクへの問い合わせに「エラーコード E-4012」が含まれていた場合、意味検索だけでは正確にヒットしない可能性がありますが、キーワード検索と組み合わせることで確実に捉えることができます。

4-3. 検索結果を精査する

ベクトル検索は大量のドキュメントから高速に候補を絞り込むのが得意ですが、2章で見た異方性によるスコアの分解能の低さや、3章で見た情報の希釈の影響で、微妙なニュアンスの判定は苦手です。そこで、検索結果を別の仕組みで精査する リランキング(Re-ranking) というアプローチが使われます。

リランキングモデルによる再評価

ベクトル検索で取得した上位の候補に対して、より高精度な別のモデルを使い、クエリとドキュメントを一対一でじっくり比較して並び替える手法です。全件に適用するには遅すぎるため、「まずベクトル検索で候補を絞り、次にリランキングモデルで精査する」という2段構えにすることで、速度と精度を両立させます。

LLM による検索結果のフィルタリング

上位10件程度の候補を LLM に渡し、「このクエリに対して本当に関連のあるドキュメントはどれか?」を判定させるアプローチも有効です。LLM は文章の意味を深く理解できるため、ベクトル検索では区別しきれなかった微妙な違いを捉えることが期待できます。

例えば、「パスワードを変更したい」というクエリに対して、ベクトル検索の段階では「パスワード変更手順」と「パスワード定期変更の廃止について」が近いスコアで並んでしまうかもしれません。ここに LLM を挟めば、ユーザーの意図は「変更の仕方を知りたい」であると解釈し、「変更手順」の方を優先的に提示する判断が可能になります。


まとめ

  • 1章(Embedding): テキストを数値のパターン(ベクトル)に変換し、意味が近いものを空間上で近くに配置する。ただし、表記の違いにも影響を受ける。
  • 2章(類似度): コサイン類似度で「近さ」を数値化することで意味検索が可能になる。ただし、異方性によるスコアの分解能の低さという構造的な課題がある。
  • 3章(文章の埋め込み): 文章レベルでは文脈が考慮されるが、Mean Pooling による情報の希釈が発生する。文章が長くなるほどこの傾向は強くなる。
  • 4章(対応策): データの前処理(チャンク化・正規化)、ハイブリッド検索、リランキングを組み合わせることで、初めて実用的な検索システムとなる。

RAG の構築は、データベースをセットアップして終わりではありません。 データの特性を見極め、適切な前処理と検索アーキテクチャを設計する、エンジニアリングが求められる領域です。


本編は以上となります。最後までお読みいただき、ありがとうございました。