AI News HubLIVE
サイト内リライト3 分で読了

PythonでLLM埋め込みとメタデータを使ったコンテキスト認識検索の構築

この記事では、埋め込みベースの類似性と構造化メタデータフィルタリングを組み合わせたコンテキスト認識セマンティック検索エンジンの構築方法を、埋め込みの生成からインデックスの永続化まで解説します。

ソースMachine Learning Mastery著者: Bala Priya C

ユーザーが入力した内容がドキュメントに文字通り含まれていない場合、キーワード検索は機能しなくなります。例えば、サポートエンジニアが「ログインが失敗し続ける」と検索しても、「OAuth2トークンリフレッシュの競合状態」というタイトルのチケットは見つかりません。これこそが、コンテキスト認識セマンティック検索が解決しようとする核心的な問題です。

セマンティック検索は、テキストを埋め込みと呼ばれる密なベクトル表現に変換することでこの問題を解決します。この表現では、正確な単語の一致ではなく意味によって近さが決まります。その上に、日付、ステータス、チーム、優先度による構造化メタデータフィルタを重ねることで、誰かの問い合わせを理解しつつ、文脈上の制約も尊重するシステムが得られます。

この記事では、そのようなシステムをエンドツーエンドで構築する方法を説明します。ローカルの事前学習モデルからの埋め込み生成、メタデータ認識インデックス、コサイン類似度によるランク付け、そして再起動後も再エンコード不要で再読み込みできる永続化インデックスを扱います。

セマンティック検索の仕組み

文埋め込みモデルは、文字列を受け取り固定長の浮動小数点ベクトルを返します。モデルは、意味が似ている文が高次元空間で近い方向を向くように訓練されています。コサイン類似度は2つのベクトル間の角度を測定します:cosine_similarity(A, B) = (A·B) / (||A|| ||B||)。ベクトルが単位正規化されている場合(長さが1.0)、類似度は単純にドット積になります。スコアは-1(逆)から1(同一)の範囲です。実際には、無関係な文書は0.1〜0.25程度で、強い一致は0.6以上です。

では、なぜメタデータフィルタリングが重要なのでしょうか?埋め込みモデルは意味内容をエンコードしますが、誰が書いたか、どのチームが所有するか、いつ作成されたかはエンコードしません。これらの属性はテキストの外部にあり、個別に処理する必要があります。セマンティックスコアとメタデータ制約の両方を組み合わせることで、実際のシステムで検索が有用になります。

データセットの準備

3つのチーム(インフラストラクチャ、バックエンド、フロントエンド)、4つの優先度、2つのステータス、2か月の日付ウィンドウにわたる20のエンジニアリングサポートチケットを使用します。各チケットは単純な辞書で、textフィールドが埋め込み対象、残りはフィルタリング用のメタデータです。

ステップ1:埋め込みの生成

all-MiniLM-L6-v2モデルは、任意の文を384次元ベクトルにマッピングします。CPU上で完全に動作し、Hugging Faceから一度ダウンロード(約22MB)され、その後はローカルにキャッシュされ、APIキーは不要です。normalize_embeddings=Trueを設定すると、各出力ベクトルのL2ノルムが正確に1.0になり、クエリ時のコサイン類似度がドット積に簡略化されます。

ステップ2:インデックスの構築

インデックスは埋め込み行列と関連するメタデータを格納し、各メタデータフィールドのオプションのキーワード引数を受け入れるsearchメソッドを公開します。重要な設計上の決定は、スコアリングの前にフィルタリングを行うことです。後からフィルタリングすると、破棄するドキュメントにドット積計算を無駄に消費します。先にフィルタリングすることで、min_scoreがノイズの多い低信頼度のマッチを除外できるようになります。

ステップ3:クエリの実行

記事では3種類のクエリを示しています。フィルタなしの純粋なセマンティック検索、ステータスと日付でフィルタリングした検索、優先度フィルタでチーム横断的な検索です。例えば「リソース枯渇とメモリプレッシャー」をクエリし、ステータスをopen、優先度をhighでフィルタすると、チームをまたいだ関連チケットが返されます。

この記事を通じて、実用的なコンテキスト認識検索システムを構築し、自分のプロジェクトに応用できるようになります。