将 Milvus 与 WhyHow 集成
本指南演示了如何使用 whyhow.ai 和 Milvus Lite 进行基于规则的检索。
概述
WhyHow 是一个平台,为开发者提供组织、上下文化和可靠检索非结构化数据所需的构建块,以执行复杂的 RAG。基于规则的检索包是由 WhyHow 开发的 Python 包,使人们能够创建和管理具有高级过滤功能的检索增强生成 (RAG) 应用程序。
安装
在开始之前,请安装后续使用所需的所有必要 Python 包。
pip install --upgrade pymilvus, whyhow_rbr
接下来,我们需要初始化 Milvus 客户端以使用 Milvus Lite 实现基于规则的检索。
from pymilvus import MilvusClient
# Milvus Lite 本地路径
path="./milvus_demo.db" # 本地 milvus lite 数据库路径的随机名称
# 初始化 ClientMilvus
milvus_client = ClientMilvus(path)
您也可以通过 Milvus Cloud 初始化 Milvus 客户端
from pymilvus import MilvusClient
# Milvus Cloud 凭据
YOUR_MILVUS_CLOUD_END_POINT = "YOUR_MILVUS_CLOUD_END_POINT"
YOUR_MILVUS_CLOUD_TOKEN = "YOUR_MILVUS_CLOUD_TOKEN"
# 初始化 ClientMilvus
milvus_client = ClientMilvus(
milvus_uri=YOUR_MILVUS_CLOUD_END_POINT,
milvus_token=YOUR_MILVUS_CLOUD_TOKEN,
)
创建 Collection
定义必要的变量
# 定义 collection 名称
COLLECTION_NAME="YOUR_COLLECTION_NAME" # 使用您自己的 collection 名称
# 定义向量维度大小
DIMENSION=1536 # 由您使用的模型决定
添加模式
在向 Milvus Lite 数据库插入任何数据之前,我们需要首先定义数据字段,这里称为模式。通过创建 CollectionSchema
对象并通过 add_field()
添加数据字段,我们可以控制数据类型及其特征。这一步骤在向 Milvus 插入任何数据之前是必须的。
schema = milvus_client.create_schema(auto_id=True) # 启用 id 匹配
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
对象上添加更多索引数据。
# 开始为数据字段建立索引
index_params = milvus_client.prepare_index_params()
index_params = milvus_client.add_index(
index_params=index_params, # 传入 index_params 对象
field_name="embedding",
index_type="AUTOINDEX", # 使用自动索引而不是其他复杂的索引方法
metric_type="COSINE", # L2、COSINE 或 IP
)
这个方法是官方 Milvus 实现的轻量级包装器(官方文档)。
创建 collection
在定义了所有数据字段并为它们建立索引后,我们现在需要创建数据库 collection,以便快速准确地访问数据。需要注意的是,我们将 enable_dynamic_field
初始化为 true,这样您可以自由上传任何数据。代价是数据查询可能效率较低。
# 创建 Collection
milvus_client.create_collection(
collection_name=COLLECTION_NAME,
schema=schema,
index_params=index_params
)
上传文档
创建 collection 后,我们准备用文档填充它。在 whyhow_rbr
中,这是通过 MilvusClient
的 upload_documents
方法完成的。它在底层执行以下步骤:
- 预处理:读取提供的 PDF 文件并将其拆分为块
- 嵌入:使用 OpenAI 模型嵌入所有块
- 插入:将嵌入和元数据上传到 Milvus Lite
# 获取 pdf 文件
pdfs = ["harry-potter.pdf", "game-of-thrones.pdf"] # 替换为您的 pdf 文件路径
# 上传 PDF 文档
milvus_client.upload_documents(
collection_name=COLLECTION_NAME,
documents=pdfs
)
问答
现在我们终于可以进行检索增强生成了。
# 搜索数据并实现 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
块的唯一标识符(这是最"极端"的过滤器)- 其他基于布尔表达式的规则
# 规则(在第 8 页的哈利·波特书中搜索):
PARTITION_NAME='harry-potter' # 在书籍中搜索
page_number='page_number == 8'
# 首先创建一个分区来存储书籍,然后在这个特定分区中搜索:
milvus_client.crate_partition(
collection_name=COLLECTION_NAME,
partition_name=PARTITION_NAME # 根据您的 pdf 类型分离
)
# 使用规则搜索
res = milvus_client.search(
question='Tell me about the greedy method',
collection_name=COLLECTION_NAME,
partition_names=PARTITION_NAME,
filter=page_number, # 添加任何遵循布尔表达式规则的规则
anns_field='embedding',
output_fields='text'
)
print(res['answer'])
print(res['matches'])
在这个示例中,我们首先创建一个存储哈利·波特相关 pdf 的分区,通过在这个分区内搜索,我们可以获得最直接的信息。此外,我们将页码作为过滤器来指定我们希望搜索的确切页面。记住,过滤器参数需要遵循布尔规则。
清理
最后,在实施所有指令后,您可以通过调用 drop_collection()
来清理数据库。
# 清理
milvus_client.drop_collection(
collection_name=COLLECTION_NAME
)