社内文書を検索できるAIを作ると、面白いことが起きます。「有給の申請方法」と打ったのに、「休暇取得の手続きについて」という題の文書が出てくる。
言葉はひとつも一致していません。それでも見つかる。この仕組みがエンベディングとベクトル検索です。
文章を数値の並びに変える
エンベディングは、文章を数百から数千個の数値の並びに変換する処理のこと。この並びをベクトルと呼びます。
変換の規則は、意味が近い文章ほど数値としても近い位置に来るように作られています。「犬」と「猫」は近く、「犬」と「四半期決算」は遠い。
近いかどうかは、2つのベクトルのあいだの距離で測ります。距離が計算できるので、機械が扱えるようになる。
この考え方を検索に持ち込んだのが、RAGの原論文でした。Wikipediaを密なベクトルの索引にして、学習済みの検索器から引く形になっています。
検索の手順
| 段階 | やること | いつ走るか |
|---|---|---|
| 変換 | 文書を適当な長さに切り、それぞれをベクトルに変える | 文書を追加したときだけ |
| 保存 | ベクトルを索引に入れる | 同上 |
| 照合 | 質問も同じ方法でベクトルに変え、近いものを探す | 質問のたび |
大事なのは、質問と文書を同じ変換規則で処理することです。別の規則で作ったベクトル同士は比べられません。文書を入れ直さずに変換モデルだけ差し替えると、検索が壊れます。
キーワード検索との違い
どちらが優れているという話ではなく、得意な場面が違います。
| ベクトル検索 | キーワード検索 | |
|---|---|---|
| 言い換え | 強い | 弱い |
| 型番・品番 | 弱い | 強い |
| 人名・固有名詞 | やや弱い | 強い |
| 「〜ではない」の否定 | 苦手 | — |
型番に弱いのは意外に思われるところ。「AB-3021」と「AB-3012」は文字列としてよく似ていて、意味の空間でもほぼ同じ場所に来てしまいます。人間なら別物だと分かるのに。
否定も苦手です。「返品できない条件」を探したいのに、「返品できる条件」の文書が同じくらい近くに来る。否定は意味の向きを反転させますが、ベクトルの距離はそこを区別しません。
実務でつまずくところ
組んでみると、精度が出ない原因はだいたい同じ場所にあります。
文書の切り方が粗いか細かすぎるか。粗いと関係ない内容が混ざって位置がぼやけ、細かすぎると前後の文脈が失われます。見出しの区切りに合わせるのが無難でしょう。
表の扱いも難しい。単純にテキストに直すと行と列の対応が壊れ、意味を持たない数字の羅列になります。
そして、似た内容の古い版が大量に入っていること。改訂前の規程と改訂後の規程は、意味の空間ではほぼ同じ場所にあります。どちらが引かれるかは運です。
両方を混ぜる構成
得意な場面が違うので、実際には併用する形が多くなります。
キーワード検索とベクトル検索の両方を走らせ、それぞれの上位を混ぜてから、最終的な並び替えをかける。型番はキーワード側が拾い、言い換えはベクトル側が拾う。取りこぼしが減ります。
並び替えの段階に、別のモデルを挟むこともあります。質問と候補の文書を1件ずつ突き合わせて、本当に関係があるかを判定させる方式です。精度は上がりますが、候補の数だけ処理が走るので費用と時間はかかる。
最初から全部を組む必要はありません。ベクトル検索だけで始めて、引けない種類の質問が見えてきたら足す。その順番のほうが、何が効いたか分かります。
どのくらいの規模から必要になるか
文書が数十件なら、仕組みを組むより全部渡したほうが早い場合があります。
最近のモデルは一度に受け取れる量が増えたので、A4で数十ページ程度なら丸ごと入ります。検索の仕組みを作る手間と、毎回全部渡す費用を比べて決めることになる。
目安としては、文書が数百件を超えたあたり、あるいは同じ質問が繰り返し来るようになったあたりでしょう。渡す量が減れば費用も待ち時間も下がります。
確かめ方
答えの質を議論する前に、検索が何を引いてきたかを見ます。
正しい文書が引けているのに答えがおかしいなら、原因は生成側。そもそも関係ない文書が引かれているなら、原因は検索側です。この切り分けをせずに指示文をいじっても、時間が溶けるだけ。
なお、OWASPはLLMアプリケーションの危険の一覧に「ベクトルとエンベディングの弱点」という項目を設けています。索引に何を入れたかがそのまま出力に影響する以上、入れる中身の管理も設計のうちに入ります。
出典
密なベクトル索引を用いた検索の記述は下記の論文、危険の分類は下記の一覧に基づきます。

