MilvusとWhyHowの連携
本ガイドでは、whyhow.aiとMilvus Liteを利用してルールベース検索を行う方法をご紹介します。
概要
WhyHowは、複雑なRAGを実行するために非構造化データを整理、文脈化、そして確実に取得するために必要なビルディングブロックを開発者に提供するプラットフォームです。ルールベース検索パッケージは、高度なフィルタリング機能を備えたRAG(Retrieval Augmented Generation)アプリケーションの作成と管理を可能にする、WhyHowが開発したPythonパッケージです。
インストール
始める前に、後で使用するために必要なすべてのPythonパッケージをインストールしてください。
pip install --upgrade pymilvus, whyhow_rbr
次に、Milvus Liteを使用してルールベース検索を実装するためにMilvusクライアントを初期化する必要があります。
from pymilvus import MilvusClient
# Milvus Lite local path
path="./milvus_demo.db" # random name for local milvus lite db path
# Initialize the ClientMilvus
milvus_client = ClientMilvus(path)
Milvus Cloudを使用してMilvusクライアントを初期化することもできます。
from pymilvus import MilvusClient
# Milvus Cloud credentials
YOUR_MILVUS_CLOUD_END_POINT = "YOUR_MILVUS_CLOUD_END_POINT"
YOUR_MILVUS_CLOUD_TOKEN = "YOUR_MILVUS_CLOUD_TOKEN"
# Initialize the ClientMilvus
milvus_client = ClientMilvus(
milvus_uri=YOUR_MILVUS_CLOUD_END_POINT,
milvus_token=YOUR_MILVUS_CLOUD_TOKEN,
)
コレクションの作成
必要な変数の定義
# Define collection name
COLLECTION_NAME="YOUR_COLLECTION_NAME" # take your own collection name
# Define vector dimension size
DIMENSION=1536 # decide by the model you use
スキーマの追加
Milvus Liteのデータベースにデータを挿入する前に、まずデータフィールドを定義する必要があります。オブジェクトの作成CollectionSchema
、データフィールドの追加add_field()
。このステップはMilvusにデータを挿入する前に必須です。
schema = milvus_client.create_schema(auto_id=True) # Enable id matching
schema = milvus_client.add_field(schema=schema, field_name="id", datatype=DataType.INT64, is_primary=True)
schema = milvus_client.add_field(schema=schema, field_name="embedding", datatype=DataType.FLOAT_VECTOR, dim=DIMENSION)
インデックスの作成
各スキーマにはインデックスを作成した方が、クエリがより効率的になります。インデックスを作成するには、まずindex_params
が必要で、後でこのIndexParams
オブジェクトにインデックスデータを追加します。
# Start to indexing data field
index_params = milvus_client.prepare_index_params()
index_params = milvus_client.add_index(
index_params=index_params, # pass in index_params object
field_name="embedding",
index_type="AUTOINDEX", # use autoindex instead of other complex indexing method
metric_type="COSINE", # L2, COSINE, or IP
)
このメソッドはMilvusの公式実装(公式ドキュメント)の薄いラッパーです。
コレクションの作成
すべてのデータフィールドを定義し、インデックスを作成したら、今度はデータベースコレクションを作成し、素早く正確にデータにアクセスできるようにする必要があります。特筆すべきは、enable_dynamic_field
を true に初期化し、自由にデータをアップロードできるようにしたことである。その代償として、データ照会が非効率的になるかもしれない。
# Create Collection
milvus_client.create_collection(
collection_name=COLLECTION_NAME,
schema=schema,
index_params=index_params
)
ドキュメントのアップロード
コレクションを作成した後、ドキュメントを入力する準備ができた。whyhow_rbr
では、これはMilvusClient
のupload_documents
メソッドを使用して行われる:
- 前処理:提供されたPDFファイルを読み込み、チャンクに分割する。
- 埋め込み:OpenAIモデルを使用して、すべてのチャンクを埋め込みます。
- 挿入:埋め込みとメタデータの両方をMilvus Liteにアップロードする。
# get pdfs
pdfs = ["harry-potter.pdf", "game-of-thrones.pdf"] # replace to your pdfs path
# Uploading the PDF document
milvus_client.upload_documents(
collection_name=COLLECTION_NAME,
documents=pdfs
)
質問応答
これでようやく検索拡張生成に移ることができる。
# Search data and implement RAG!
res = milvus_client.search(
question='What food does Harry Potter like to eat?',
collection_name=COLLECTION_NAME,
anns_field='embedding',
output_fields='text'
)
print(res['answer'])
print(res['matches'])
ルール
先ほどの例では、インデックスに含まれる全ての文書を対象とした。しかし、あらかじめ定義された条件を満たす文書のみを検索することが有益な場合もある(例:filename=harry-potter.pdf
)。Milvus Liteを通したwhyhow_rbr
、検索パラメータを調整することでこれを行うことができます。
ルールは以下のメタデータ属性を制御することができます。
filename
ファイル名page_numbers
ページ番号に対応する整数のリスト (0 インデックス)id
チャンクの一意識別子(これは最も "極端な "フィルターです。)- ブール式に基づくその他のルール
# RULES(search on book harry-potter on page 8):
PARTITION_NAME='harry-potter' # search on books
page_number='page_number == 8'
# first create a partitions to store the book and later search on this specific partition:
milvus_client.crate_partition(
collection_name=COLLECTION_NAME,
partition_name=PARTITION_NAME # separate base on your pdfs type
)
# search with rules
res = milvus_client.search(
question='Tell me about the greedy method',
collection_name=COLLECTION_NAME,
partition_names=PARTITION_NAME,
filter=page_number, # append any rules follow the Boolean Expression Rule
anns_field='embedding',
output_fields='text'
)
print(res['answer'])
print(res['matches'])
この例では、まずハリー・ポッター関連のpdfを格納するパーティションを作成し、このパーティション内で検索することで、最も直接的な情報を得ることができます。また、検索したいページを正確に指定するために、フィルタとしてページ番号を適用しています。ファイラー・パラメーターはブーリアン・ルールに従う必要があることを忘れないでください。
クリーンアップ
最後に、すべての命令を実行した後、drop_collection()
を呼び出してデータベースをクリーンアップすることができる。
# Clean up
milvus_client.drop_collection(
collection_name=COLLECTION_NAME
)