整合 Milvus 與 WhyHow
本指南展示了如何使用 whyhow.ai 和 Milvus Lite 進行基於規則的檢索。
概述
WhyHow是一個平台,提供開發人員所需的建構塊,讓他們可以組織、內容化並可靠地擷取非結構化的資料,以執行複雜的RAG。Rule-based Retrieval 套件是由 WhyHow 所開發的 Python 套件,可讓人們建立與管理具有進階過濾功能的 Retrieval Augmented Generation (RAG) 應用程式。
安裝
在開始之前,請先安裝所有必要的 python 套件,以便日後使用。
pip install --upgrade pymilvus, whyhow_rbr
接下來,我們需要初始化 Milvus 客戶端,以使用 Milvus Lite 來實現基於規則的檢索。
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 資料庫之前,我們需要先定義資料欄位,在這裡稱為 schema。透過建立物件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
)。在whyhow_rbr
中透過 Milvus Lite,這可以透過調整搜尋參數來達成。
規則可控制下列元資料屬性
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,透過在這個分區中搜尋,我們可以得到最直接的資訊。此外,我們應用頁碼作為過濾器,以指定我們想要搜尋的精確頁面。請記住,filer 參數必須遵循布林規則。
清理
最後,在執行所有指令之後,您可以呼叫drop_collection()
來清理資料庫。
# Clean up
milvus_client.drop_collection(
collection_name=COLLECTION_NAME
)