【RAG】【vector_stores055】Milvus向量存储
案例目标
本案例展示了如何使用Milvus作为LlamaIndex的向量存储后端,构建检索增强生成(RAG)系统。Milvus是全球最先进的开源向量数据库,专为支持嵌入相似性搜索和AI应用而构建。通过本案例,您将学习如何:
- 配置Milvus向量存储,支持本地文件、Docker服务器和Zilliz Cloud三种部署方式
- 将文档向量化并存储到Milvus中
- 构建基于Milvus的向量索引
- 执行向量查询并获取相关文档内容
- 实现元数据过滤功能,提高检索精度
- 管理索引的覆盖和追加操作
技术栈与核心依赖
本案例使用的主要技术栈和依赖包括:
- Milvus: 开源向量数据库,支持大规模向量相似性搜索
- llama-index-vector-stores-milvus: LlamaIndex的Milvus向量存储适配器
- LlamaIndex: 用于构建向量索引和查询引擎的核心框架
- pymilvus: Milvus的Python客户端库
- OpenAI: 用于生成嵌入和回答问题的API服务
环境配置
在运行本案例之前,需要完成以下环境配置:
安装依赖
首先需要安装必要的依赖包:
%pip install llama-index-vector-stores-milvus %pip install llama-index %pip install pymilvus>=2.4.2注意
如果您使用的是Google Colab,为了启用刚刚安装的依赖,您可能需要重启运行时(点击屏幕顶部的"Runtime"菜单,然后从下拉菜单中选择"Restart session")。
配置OpenAI API
设置OpenAI API密钥以访问ChatGPT:
import openai openai.api_key = "sk-***********"准备数据
下载示例数据:
! mkdir -p "data/" ! wget "https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt" -O "data/paul_graham_essay.txt" ! wget "https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/10k/uber_2021.pdf" -O "data/uber_2021.pdf"案例实现
1. 加载文档
首先,我们使用SimpleDirectoryReader加载Paul Graham的论文:
from llama_index.core import SimpleDirectoryReader # 加载文档 documents = SimpleDirectoryReader( input_files=["./data/paul_graham_essay.txt"] ).load_data() print("Document ID:", documents[0].doc_id)2. 创建Milvus向量存储和索引
接下来,我们创建MilvusVectorStore并构建向量索引:
from llama_index.core import VectorStoreIndex, StorageContext from llama_index.vector_stores.milvus import MilvusVectorStore vector_store = MilvusVectorStore( uri="./milvus_demo.db", dim=1536, overwrite=True ) storage_context = StorageContext.from_defaults(vector_store=vector_store) index = VectorStoreIndex.from_documents( documents, storage_context=storage_context )提示
对于MilvusVectorStore的参数:
- 将
uri设置为本地文件(如./milvus.db)是最方便的方法,它会自动使用Milvus Lite将所有数据存储在此文件中 - 如果您有大规模数据,可以在docker或kubernetes上设置性能更高的Milvus服务器,然后使用服务器uri(如
http://localhost:19530)作为您的uri - 如果您想使用Zilliz Cloud(Milvus的全托管云服务),请调整
uri和token,它们对应于Zilliz Cloud中的公共端点和API密钥
3. 查询数据
创建查询引擎并执行查询:
query_engine = index.as_query_engine() res = query_engine.query("What did the author learn?") print(res) res = query_engine.query( "What challenges did the disease pose for the author?" ) print(res)4. 索引管理
覆盖现有索引
以下测试展示了覆盖操作会删除之前的数据:
from llama_index.core import Document vector_store = MilvusVectorStore( uri="./milvus_demo.db", dim=1536, overwrite=True ) storage_context = StorageContext.from_defaults(vector_store=vector_store) index = VectorStoreIndex.from_documents( [Document(text="The number that is being searched for is ten.")], storage_context, ) query_engine = index.as_query_engine() res = query_engine.query("Who is the author?") print(res)向现有索引添加数据
以下测试展示了向已存在的索引添加额外数据:
del index, vector_store, storage_context, query_engine vector_store = MilvusVectorStore(uri="./milvus_demo.db", overwrite=False) storage_context = StorageContext.from_defaults(vector_store=vector_store) index = VectorStoreIndex.from_documents( documents, storage_context=storage_context ) query_engine = index.as_query_engine() res = query_engine.query("What is the number?") print(res) res = query_engine.query("Who is the author?") print(res)5. 元数据过滤
我们可以通过过滤特定源来生成结果。以下示例说明了如何从目录加载所有文档,然后根据元数据进行过滤:
from llama_index.core.vector_stores import ExactMatchFilter, MetadataFilters # 加载之前加载的两个文档 documents_all = SimpleDirectoryReader("./data/").load_data() vector_store = MilvusVectorStore( uri="./milvus_demo.db", dim=1536, overwrite=True ) storage_context = StorageContext.from_defaults(vector_store=vector_store) index = VectorStoreIndex.from_documents(documents_all, storage_context)从uber_2021.pdf文件检索文档
filters = MetadataFilters( filters=[ExactMatchFilter(key="file_name", value="uber_2021.pdf")] ) query_engine = index.as_query_engine(filters=filters) res = query_engine.query( "What challenges did the disease pose for the author?" ) print(res)从paul_graham_essay.txt文件检索文档
filters = MetadataFilters( filters=[ExactMatchFilter(key="file_name", value="paul_graham_essay.txt")] ) query_engine = index.as_query_engine(filters=filters) res = query_engine.query( "What challenges did the disease pose for the author?" ) print(res)案例效果
运行本案例后,您将看到以下效果:
- 文档被成功向量化并存储到Milvus中(本地文件、Docker服务器或Zilliz Cloud)
- 基于向量相似度的查询能够返回与问题相关的文档内容
- 通过元数据过滤,可以精确地从特定文档中检索信息
- 可以管理索引的覆盖和追加操作,灵活控制数据存储
提示
Milvus支持三种部署模式,每种模式适用于不同的场景:
- Milvus Lite: 适合快速原型开发和小规模数据,所有数据存储在单个本地文件中
- Docker服务器: 适合中等规模数据和生产环境,提供更好的性能和可扩展性
- Zilliz Cloud: 适合大规模数据和企业级应用,提供全托管的云服务
案例实现思路
本案例的实现思路如下:
- 环境准备: 安装必要的依赖包,包括Milvus客户端和LlamaIndex的相关适配器
- 文档准备: 下载示例文档并使用SimpleDirectoryReader加载
- 向量存储初始化: 根据需求选择Milvus的部署模式(本地文件、Docker服务器或Zilliz Cloud)
- 向量索引构建: 使用StorageContext将Milvus向量存储与LlamaIndex集成,构建VectorStoreIndex
- 查询执行: 创建查询引擎,执行自然语言查询并获取相关文档内容
- 索引管理: 实现索引的覆盖和追加操作,灵活控制数据存储
- 元数据过滤: 使用MetadataFilters和ExactMatchFilter实现基于元数据的精确检索
扩展建议
基于本案例,您可以考虑以下扩展方向:
- 高级过滤: 实现更复杂的元数据过滤条件,如范围过滤、多字段组合过滤等
- 自定义嵌入模型: 集成不同的嵌入模型,如Hugging Face模型或本地部署的嵌入服务
- 批量操作: 实现批量添加、更新和删除向量数据的操作
- 多模态数据: 扩展支持图像、音频等多模态数据的向量化存储
- 性能优化: 调整Milvus的索引参数和搜索配置,优化大规模数据下的查询性能
- 分布式部署: 在分布式环境中部署Milvus集群,实现高可用和负载均衡
- 稀疏向量支持: 利用Milvus的稀疏向量功能,实现混合搜索
- 实时更新: 实现向量数据的实时更新和增量索引
总结
本案例展示了如何使用Milvus作为LlamaIndex的向量存储后端,构建检索增强生成(RAG)系统。Milvus作为全球最先进的开源向量数据库,专为支持嵌入相似性搜索和AI应用而构建,提供了从本地开发到企业级部署的多种选项。
通过LlamaIndex的Milvus向量存储适配器,我们可以轻松地将Milvus集成到RAG应用中,构建高性能的语义搜索系统。Milvus的强大功能(如元数据过滤、多种索引类型和分布式部署)使其成为构建大规模向量搜索应用的理想选择。
