LangChainとQdrantを使用してベクトルの高度な検索を活用する
Published on
Qdrantの紹介: LangChain向けのベクトル類似検索エンジン
言語モデリングやテキストベースのアプリケーションの世界では、効率的に類似ベクトルを検索して取得する能力が重要です。関連するドキュメントを見つけること、ユーザーのクエリと一致させること、意味に基づいたマッチングを行うことなど、強力で便利なベクトル類似検索エンジンはアプリケーションの機能を大幅に向上させることができます。それがQdrantの役割です。
Qdrantは、ベクトル類似検索エンジンであり、格納、検索、ベクトルの管理に便利なAPIを提供する本番用のサービスを提供します。大規模なベクトル検索を効率的に処理し、高度なマッチングニーズに対応できる豊富なフィルタリング機能を提供します。Qdrantは、ニューラルネットワークや意味に基づいたマッチング、ファセット検索などを必要とするアプリケーションに特に便利です。
記事の要約
- Qdrantは、付加的なペイロードやベクトルの格納、検索、管理に便利なAPIを提供するベクトル類似検索エンジンです。
- 高度なマッチングニーズに対応できる豊富なフィルタリング機能を提供します。
- Qdrantは、LangChainのリトリーバーとして、コサイン類似度の検索や最大マージナル関連性(MMR)の検索に使用することができます。
<AdComponent />
QdrantクライアントのインストールとOpenAI APIキーの設定
LangChainでQdrantを使用するための最初のステップは、「qdrant-client」パッケージのインストールです。これは、Qdrantとのインタラクションに必要なクライアントライブラリを提供します。次のコマンドを使用してインストールできます。
%pip install --upgrade --quiet qdrant-client
次に、OpenAIのAPIキーを設定する必要があります。このAPIキーは、OpenAIのエンベディングを使用して類似検索を実行するために必要です。Pythonの「getpass」と「os」モジュールを使用してAPIキーを設定することができます。
import getpass
import os
os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API Key:")
LangChainでのドキュメントの読み込みと分割
Qdrantクライアントがインストールされ、OpenAI APIキーが設定されたら、LangChainでドキュメントを読み込み、分割することができます。これには、LangChainコミュニティモジュールが提供する「TextLoader」というクラスを使用することができます。
from langchain_community.document_loaders import TextLoader
loader = TextLoader("/path/to/your/documents.txt")
documents = loader.load()
ドキュメントを読み込んだ後、「CharacterTextSplitter」というクラスを使用してドキュメントをより小さなチャンクに分割することができます。これは、大きなドキュメントに対処する場合や、テキストの特定の部分で検索を実行したい場合に便利です。
from langchain_text_splitters import CharacterTextSplitter
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)
異なるモードでのQdrantへの接続
ドキュメントが読み込まれて分割されたら、展開のニーズに応じてさまざまなモードでQdrantに接続することができます。Qdrantは、ローカルモード、オンプレミスサーバーデプロイメント、Qdrantクラウドなど、複数の展開オプションをサポートしています。
ローカルモードによるメモリ内ストレージ
ローカルモードでは、サーバーなしでQdrantを実行し、データをメモリ内のみに保持することができます。このモードは、簡易な実験やテストに便利です。ローカルモードでメモリ内ストレージを使用してQdrantに接続するには、「Qdrant.from_documents」メソッドを使用し、「location」パラメーターを「:memory:」と指定します。
from langchain_community.vectorstores import Qdrant
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
qdrant = Qdrant.from_documents(docs, embeddings, location=":memory:", collection_name="my_documents")
ローカルモードによるディスクストレージ
ローカルモードでデータをディスクに保存する場合は、Qdrantデータが保存されるパスを指定します。これは、大規模なデータセットを扱う場合やデータをセッション間で保持する必要がある場合に便利です。「Qdrant.from_documents」メソッドを使用し、「path」パラメーターを指定してローカルモードでディスクストレージに接続することができます。
qdrant = Qdrant.from_documents(docs, embeddings, path="/tmp/local_qdrant", collection_name="my_documents")
オンプレミスサーバーデプロイメント
大規模な展開では、DockerコンテナやKubernetesデプロイメントを使用してローカル環境で実行されているQdrantインスタンスに接続することができます。オンプレミスサーバーデプロイメントでQdrantに接続するには、QdrantインスタンスのURLを指定し、「prefer_grpc」パラメーターを「True」に設定します。
url = "<---qdrant url here --->"
qdrant = Qdrant.from_documents(docs, embeddings, url=url, prefer_grpc=True, collection_name="my_documents")
Qdrantクラウド
完全に管理されたQdrantクラスターを使用する場合は、Qdrant Cloudアカウントを設定し、提供されたURLとAPIキーを使用してクラスターに接続することができます。このオプションは、Qdrantの展開に対してスケーラブルで安全なソリューションを提供します。Qdrant Cloudに接続するには、「Qdrant.from_documents」メソッドでURLとAPIキーを指定する必要があります。
url = "<---qdrant cloud cluster url here --->"
api_key = "<---api key here--->"
qdrant = Qdrant.from_documents(docs, embeddings, url=url, prefer_grpc=True, api_key=api_key, collection_name="my_documents")
次のセクションでは、Qdrantコレクション上で類似検索を実行し、検索結果の類似スコアを取得する方法について説明します。
続く...
異なるモードでのQdrantへの接続
使用する要件に応じて、Qdrantは異なる接続モードを提供します。Qdrantをローカルで実行したり、オンプレミス環境やクラウド環境に展開したりすることができます。
ローカルモードによるメモリ内ストレージ
ローカルモードでは、Qdrantサーバーを必要としませんでローカルでQdrantを実行することができます。これは、テストやデバッグを目的とした場合や、ベクトルの保管量が少ない場合に便利です。このモードでは、埋め込みデータは完全にメモリ上に保持され、クライアントが破棄されると失われます。
Qdrantをローカルモードでメモリ内ストレージを使用して接続するには、次のコードを使用します:
from langchain.vectorstores import Qdrant
from langchain.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2")
qdrant = Qdrant.from_documents(
documents, embeddings, location=":memory:", collection_name="my_collection"
)
ローカルモードによるディスクストレージ
ローカルモードでベクトルをディスクに永続化する場合は、ベクトルを保存するパスを指定します。これにより、起動ごとにベクトルを再利用し、毎回ゼロから始める必要がなくなります。
ローカルモードでディスクストレージを使用してQdrantに接続するには、次のコードを使用します:
from langchain.vectorstores import Qdrant
from langchain.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2")
qdrant = Qdrant.from_documents(
documents, embeddings, path="/path/to/storage", collection_name="my_collection"
)
オンプレミスサーバーデプロイメント
オンプレミス環境においてDockerコンテナや公式Helmチャートを使用してQdrantを展開する場合は、QdrantサービスのURLを指定する必要があります。
オンプレミスサーバーデプロイメントでQdrantに接続するには、次のコードを使用します:
import qdrant_client
from langchain.vectorstores import Qdrant
from langchain.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2")
client = qdrant_client.QdrantClient("<qdrant-url>", api_key="<qdrant-api-key>")
qdrant = Qdrant(client=client, collection_name="my_collection", embeddings=embeddings)
Qdrant Cloud
完全に管理されたQdrantクラスターを使用する場合は、クラスターへの接続に必要なURLとAPIキーを指定してQdrant Cloudに接続することができます。
Qdrant Cloudに接続するには、次のコードを使用します:
from langchain.vectorstores import Qdrant
from langchain.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2")
qdrant = Qdrant.from_documents(
documents, embeddings, url="<qdrant-url>", api_key="<qdrant-api-key>", collection_name="my_collection"
)
これらの異なる接続モードを使用することで、LangChainアプリケーションに簡単にQdrantを統合し、その強力なベクトル類似検索機能を活用することができます。
Qdrantコレクションでの類似検索の実行
Qdrantコレクションに接続した後、コレクションに格納されているベクトルに対して類似検索を実行することができます。これにより、与えられたクエリベクトルと類似したベクトルを見つけることができます。
類似検索を実行するには、クエリベクトルと取得する最近傍ベクトルの数を指定する必要があります。Qdrantは、最近傍ベクトルとその類似度スコアを返します。
以下は、Qdrantを使用して類似検索を実行する例です:
# クエリベクトル
query_vector = [0.1, 0.2, 0.3, 0.4, 0.5]
# 取得する最近傍ベクトルの数
k = 5
# 類似検索の実行
results = qdrant.search(query_vector, k)
「results」オブジェクトには、最近傍ベクトルとその類似度スコアが含まれます。この情報を使用して、結果をさらに処理および分析することができます。
Qdrantの豊富なフィルタリング機能の活用
Qdrantは、特定の条件を指定してベクトル属性やペイロード属性にフィルタリングするなど、豊富なフィルタリング機能を提供しています。
LangChainでQdrantのフィルタリング機能を使用するいくつかの例を以下に示します。
ベクトル属性でのフィルタリング
# 特定の属性値でフィルタリング
results = qdrant.search(query_vector, k, filter={"vector_attributes": {"attribute_name": "attribute_value"}})
# 属性値の範囲でフィルタリング
results = qdrant.search(query_vector, k, filter={"vector_attributes": {"attribute_name": {"gte": 10, "lte": 20}}})
ペイロード属性でのフィルタリング
# 特定のペイロード属性値でフィルタリング
results = qdrant.search(query_vector, k, filter={"payload_attributes": {"attribute_name": "attribute_value"}})
# ペイロード属性値の範囲でフィルタリング
results = qdrant.search(query_vector, k, filter={"payload_attributes": {"attribute_name": {"gte": 10, "lte": 20}}})
これらのフィルタリング機能を使用することで、簡単に検索結果を絞り込み、特定の基準を満たすベクトルを取得することができます。
最大マージナル関連性(MMR)検索による多様な結果の取得
類似検索の実行だけでなく、Qdrantは最大マージナル関連性(MMR)検索方法を使用して多様な結果を取得する機能も提供しています。MMR検索は、関連性と多様性の両方を提供するため、検索空間のより包括的な表現を提供します。
MMR検索を実行するには、クエリベクトル、取得する最近傍ベクトルの数、および関連性と多様性のバランスを制御する多様性パラメータを指定する必要があります。
以下は、Qdrantを使用してMMR検索を実行する例です:
# クエリベクトル
query_vector = [0.1, 0.2, 0.3, 0.4, 0.5]
# 取得する最近傍ベクトルの数
k = 5
# 多様性パラメータ
lambda_param = 0.5
# MMR検索の実行
results = qdrant.mmr_search(query_vector, k, lambda_param)
「results」オブジェクトには、多様なセットの最近傍ベクトルとその類似度スコアが含まれます。多様性パラメータを調整することで、検索結果の関連性と多様性のバランスを制御することができます。
LangChainでのQdrantリトリーバーの使用
Qdrantは、LangChainでのコサイン類似度の検索やMMR検索の両方でリトリーバーとして使用することができます。LangChainアプリケーションにQdrantを統合することで、強力なベクトル類似検索の機能を活用してリトリーバーのパフォーマンスと精度を向上させることができます。
コサイン類似度の検索にQdrantをリトリーバーとして使用するには、次のコードを使用します:
from langchain.retrievers import QdrantRetriever
retriever = QdrantRetriever(qdrant)
results = retriever.retrieve_cosine(query_vector, k)
MMR検索にQdrantをリトリーバーとして使用するには、次のコードを使用します:
from langchain.retrievers import QdrantRetriever
retriever = QdrantRetriever(qdrant)
results = retriever.retrieve_mmr(query_vector, k, lambda_param)
LangChainでQdrantをリトリーバーとして使用することで、ベクトル類似検索機能を簡単に言語モデルベースのアプリケーションに統合することができます。
結論
本記事では、様々な接続モードでQdrantに接続し、Qdrantコレクション上で類似検索を実行し、Qdrantの豊富なフィルタリング機能を活用し、MMR検索を使用して多様な結果を取得し、QdrantをLangChainのリトリーバーとして使用する方法を探りました。QdrantをLangChainアプリケーションに統合することで、強力なベクトル類似検索エンジンを活用してリトリーバーのパフォーマンスと精度を向上させることができます。