便利なAI検索 仕組みを解説

はじめに

AI検索にはさまざまな方法がありますが、この記事では文章をベクトルへ変換し、文章の意味や内容の近さをもとに情報を探す検索方法について説明します。

一般的なキーワード検索では、検索した文字列や単語がページやデータに含まれているかを中心に調べます。一方、AI検索では文章を数値の集まりに変換し、その数値同士を比較することで、異なる言葉で書かれていても意味が近い情報を見つけることができます。

例えば「パソコンが急に遅くなった」と検索した場合、通常のキーワード検索では「パソコン」「遅くなった」といった単語を含む記事が中心になります。AI検索では「PCの動作が重い」「Windowsの処理速度を改善する方法」のように、同じ単語を使っていなくても内容が近い記事を検索結果に含められます。

AI検索と普通の検索の違い
項目 普通の検索 AI検索
主な判定方法 文字列やキーワード 文章の意味の近さ
異なる表現への対応 苦手 比較的得意
比較するもの 文字列やキーワード 文章を変換したベクトル
主な用途 サイト内検索など 意味検索や関連記事など

AI検索の仕組み

AI検索で重要になるのが「エンベディング」です。エンベディングとは、文章の意味をコンピューターで比較できるように、文章を数値のベクトルへ変換する技術です。

例えば、この記事をエンベディングすると、次のような数値の配列になります。

[0.02278302423655986785888671875, 0.15485183894634246826171875, -0.014711166732013225555419921875, ...]

実際には数個ではなく、数百から数千個程度の数値が並びます。この数値のまとまりを「ベクトル」と呼びます。

検索するときは、あらかじめ記事のタイトルや本文をエンベディングしてデータベースなどへ保存しておきます。その後、ユーザーが入力した検索文についても同じモデルを使ってエンベディングします。

  1. 記事の文章をエンベディングする
  2. 生成されたベクトルを保存する
  3. ユーザーが検索文を入力する
  4. 検索文も同じモデルでエンベディングする
  5. 検索文と記事のベクトルを比較する
  6. 意味が近い記事から順番に表示する

コサイン類似度で文章の近さを計算する

ベクトル同士の近さを調べる方法の1つが「コサイン類似度」です。コサイン類似度では、2つのベクトルがどれくらい同じ方向を向いているかを計算します。

ベクトルAとベクトルBのコサイン類似度は、次の式で求められます。

cos(A, B) = (A・B) / (||A|| × ||B||)

A・Bは2つのベクトルの内積、||A||と||B||はそれぞれのベクトルの大きさを表します。2つのベクトルが同じ方向に近いほどコサイン類似度が高くなり、文章の内容も近いと判断できます。

例えば768次元のベクトルであれば、768個の数値を使って類似度を計算します。検索文と1つの記事を比較するだけであれば計算量はそれほど大きくありませんが、記事が増えると比較する回数も増えていきます。

データが増えると検索に時間がかかる

単純な方法では、検索文のベクトルと保存しているすべての記事のベクトルについてコサイン類似度を計算します。

記事が100件であれば100件と比較しますが、1万件なら1万件、100万件なら100万件との比較が必要です。1件ごとの計算が高速でも、対象となるベクトルが増えるほど検索全体に必要な計算量は大きくなります。

そのため、小規模なサイトでは全件を比較する方法でも十分ですが、大量のデータを扱うサービスでは、毎回すべてのベクトルを比較しないための仕組みが使われます。

ベクトルインデックスを使った検索

大量のベクトルを高速に検索する方法として、ベクトル検索に対応したデータベースやベクトルインデックスがあります。

単純な全件比較では、検索するたびに保存されているすべてのベクトルとの距離や類似度を計算します。一方、HNSWやIVFFlatなどのインデックスを利用すると、検索するベクトルに近そうな候補を効率的に探し、その候補を中心に比較できます。

例えばHNSWでは、ベクトル同士の近さをもとに作られたグラフ構造をたどりながら、検索するベクトルに近い候補を探します。すべてのベクトルを最初から最後まで1件ずつ比較する必要がないため、データ数が多くなった場合でも高速な検索が可能になります。

ただし、ベクトルインデックスを使うとコサイン類似度そのものが高速な別の計算式に変わるわけではありません。すべてのデータを計算対象にするのではなく、近い可能性が高いデータを効率よく探すことで検索を高速化します。

このような検索方法は近似最近傍検索と呼ばれます。全件を正確に比較する方法より高速になる一方で、設定や方式によっては本当に最も近いデータを取りこぼす可能性があります。そのため、検索速度と検索精度のバランスを考えて利用します。

記事数が少ないうちは単純な全件比較でも十分です。データ数が増えて検索速度が問題になった場合に、HNSWなどのベクトルインデックスを利用することで大量のデータにも対応できます。

文章をベクトル化する方法

文章をベクトル化することをエンベディング(Embedding)と言います。

文章をエンベディングする方法はいくつかあります。代表的なのは、OpenAIなどが提供するAPIを利用する方法と、Pythonのライブラリを使って自分のパソコンやサーバー上でモデルを動かす方法です。

OpenAIのAPIを利用する方法

OpenAI APIでは、文章をベクトルへ変換するためのEmbeddingモデルを利用できます。文章をAPIへ送信すると、エンベディングされた数値の配列を取得できます。

例えばtext-embedding-3-smallやtext-embedding-3-largeなどのEmbeddingモデルがあります。APIを利用するため、自分のサーバーにAIモデルを用意する必要がなく、比較的簡単に導入できます。

OpenAI APIは利用量に応じて料金が発生します。大量の記事を頻繁にエンベディングする場合は利用料金を考える必要がありますが、AIモデルを動かすための環境を自分で用意しなくてもよいというメリットがあります。

Pythonのライブラリを利用する方法

もう1つは、Pythonから公開されているエンベディングモデルを利用する方法です。代表的なライブラリとしてsentence-transformersがあり、Hugging Faceなどで公開されているモデルを読み込んで文章をエンベディングできます。

モデル自体を自分の環境で実行するため、使用するモデルのライセンス条件を満たしていれば、APIのように文章を変換するたびに利用料金が発生するわけではありません。

ただし、モデルのダウンロードや実行環境が必要になり、モデルによってはCPUでは処理に時間がかかることがあります。大量の文章を高速に変換する場合にはGPUを利用する方法もあります。

主なエンベディング方法の違い
方法 料金 特徴
OpenAI API 利用量に応じて料金が発生 環境構築が比較的簡単
Python+公開モデル モデルによって無料で利用可能 自分の環境で処理できる

このサイトで使用しているAI検索

このサイトでも、エンベディングを利用したAI検索を使用しています。使用しているモデルは、日本語向けの汎用テキストエンベディングモデルであるcl-nagoya/ruri-v3-310mです。

Ruri v3は日本語の文章をベクトルへ変換できるモデルで、ruri-v3-310mでは1つの文章が768次元のベクトルとして出力されます。

つまり、1つの記事や検索文を768個の数値で表現し、その数値同士を比較しています。このサイトでは、このベクトルを利用して文章同士の類似性を調べています。

Ruri v3はPythonのsentence-transformersから利用でき、このサイトではOpenAIのEmbedding APIではなく、cl-nagoya/ruri-v3-310mを使用して文章のベクトル化を行っています。

AI検索での利用

サイト内の記事をあらかじめcl-nagoya/ruri-v3-310mでエンベディングし、768次元のベクトルを保存しています。

Ruri v3を検索用途で使用する場合は、検索対象の記事には「検索文書: 」、ユーザーが入力した検索文には「検索クエリ: 」というプレフィックスを付けてエンベディングします。

ユーザーがAI検索へ文章を入力すると、その検索文を同じモデルで768次元のベクトルへ変換します。そして、保存されている記事のベクトルと検索文のベクトルを比較し、類似度が高い記事を検索結果として表示します。

この方法なら、記事に検索した単語が直接含まれていなくても、内容が似ていれば検索結果に表示できるため、一般的なキーワード検索とは異なる探し方ができます。

関連記事での利用

エンベディングは検索だけでなく、関連記事の判定にも使用できます。

検索文の代わりに現在表示している記事のベクトルと、ほかの記事のベクトルを比較します。類似度が高ければ内容も近いと判断できるため、関連性が高い記事を自動的に選ぶことができます。

そのため、AI検索と関連記事は別々の機能に見えますが、基本的にはどちらも「文章をエンベディングしてベクトルの近さを調べる」という同じ仕組みを利用しています。

エンベディングモデルが異なると生成されるベクトルも異なるため、比較する文章は同じモデルを使ってエンベディングする必要があります。また、モデルによって検索文や検索対象の文章に指定されたプレフィックスなどがある場合は、そのモデルの使用方法に従う必要があります。

まとめ

AI検索にはさまざまな方法がありますが、文章をエンベディングしてベクトル同士を比較することで、キーワードが一致していなくても意味の近い情報を探すことができます。

エンベディングにはOpenAIのAPIを利用する方法のほか、Pythonと公開モデルを使って自分の環境で処理する方法があります。それぞれ料金、導入のしやすさ、実行環境などに違いがあります。

ベクトル同士の近さはコサイン類似度などを使って計算できますが、データ数が増えるほど単純な全件比較では計算量も増えていきます。大量のデータを扱う場合には、HNSWなどのベクトルインデックスを使って検索対象を効率的に絞り込むことで高速化できます。

このサイトでは日本語向けモデルのRuri v3を使い、文章を768次元のベクトルへ変換しています。このベクトルを利用することで、AI検索だけでなく関連記事の選定にも同じ仕組みを活用しています。

AI検索という名前だけを見ると複雑な仕組みに感じますが、この記事で紹介した方法の基本となる考え方は「文章を数値に変換し、数値が近い文章を探す」というものです。エンベディングを利用することで、従来の文字列検索では見つけにくかった情報も検索できるようになります。

関連記事