:Milvus 入门与实践,从创建集合到向量检索`)
RAG从入门到实战六Milvus 入门与实践从创建集合到向量检索文章目录RAG从入门到实战六Milvus 入门与实践从创建集合到向量检索前言一、Milvus 在 RAG 中负责什么二、先理解几个概念三、准备环境3.1 启动或连接 Milvus3.2 安装 Python 客户端四、完整示例写入、搜索和过滤五、逐步理解代码5.1 连接客户端5.2 创建 Collection5.3 写入数据5.4 向量搜索5.5 标量过滤六、如何换成真实 Embedding6.1 进阶显式 Schema 与两类向量字段七、常见问题八、总结参考资料前言上一篇我们用内存中的向量计算相似度。实际知识库中的片段可能越来越多还需要持久化、索引、元数据过滤和管理更新。这时可以考虑使用向量数据库。本文以 Milvus 为例完成以下操作理解 Collection、字段、实体与索引。创建一个演示集合写入向量和元数据。检索相似向量并按字段过滤。理解如何将真实 Embedding 接入 RAG。本篇用手工构造的二维向量说明数据库操作不把这些向量当作真实文本的语义表示。示例数据全部虚构部署、接口及参数需要结合所使用的 Milvus 和 PyMilvus 版本核对。一、Milvus 在 RAG 中负责什么Milvus 是用于管理和检索向量数据的数据库。它可以保存向量以及相关字段建立索引并根据查询向量返回候选结果。在 RAG 中的一个典型位置文档 → 解析和切分 → Embedding → 向量 元数据 → Milvus 问题 → Embedding → Milvus 搜索 → 候选片段 → 重排序 / 上下文组装 → 大模型要注意Milvus 本身不是完整 RAG 系统。解析、Embedding、权限控制、证据核验、提示词和答案生成仍需要其他组件协作完成。不同部署和版本支持的特性也可能不同。二、先理解几个概念概念可以怎样理解本文示例Collection一组具有字段结构的数据一个演示知识库Schema定义字段、类型及约束ID、向量、标题、文本等Entity集合中的一条记录一个知识片段和它的向量Vector field用于相似搜索的向量字段二维vectorScalar field非向量字段文档标题、类别等Index组织向量以支持检索的数据结构示例使用快速创建的默认索引配置常见向量索引包括 FLAT、IVF、HNSW 等。索引的适用性和可调参数会随服务版本、数据规模、距离度量和部署方式变化需要实际测试。不要因为索引存在就假设搜索结果一定准确。三、准备环境3.1 启动或连接 Milvus先准备一个可以访问的 Milvus 服务实例。开发环境可以参考 Milvus 官方安装文档选择 Standalone、Docker 或其他部署方式云服务和生产部署还需要配置认证、网络、安全策略和备份。Windows 用户可以使用其支持的服务部署方式或远程实例基于本地文件的 Milvus Lite 并不保证适用于所有 Windows 环境请以当前官方支持说明为准。本篇假设服务地址为http://localhost:19530。如果使用远程服务或开启认证请将示例值替换为自己的服务地址和认证信息令牌示例是占位符不要直接使用占位文字。可以设置环境变量$env:MILVUS_URI http://localhost:19530# 启用认证的环境按服务端配置设置例如# $env:MILVUS_TOKEN 用户名:密码或服务商提供的令牌不要把真实令牌提交到仓库或展示在截图中。公网环境应使用符合部署要求的加密连接和访问控制命令行设置只用于演示生产环境请使用安全的密钥管理方式。3.2 安装 Python 客户端pipinstallpymilvus使用前应核对客户端与服务端版本的兼容性。本篇使用MilvusClient的快速建集合接口。不同 PyMilvus 版本可能有 API 或默认行为差异安装后请记录并核对客户端及服务端版本。示例需要一个可访问的 Milvus 服务本文没有连接真实服务端进行端到端验证。四、完整示例写入、搜索和过滤保存为milvus_demo.pyimportosimportuuidfrompymilvusimportMilvusClientdefmain():urios.getenv(MILVUS_URI,http://localhost:19530)tokenos.getenv(MILVUS_TOKEN)kwargs{uri:uri}iftoken:kwargs[token]token clientMilvusClient(**kwargs)# 每次运行使用新集合避免覆盖或删除已有数据。collectionrag_demo_uuid.uuid4().hex[:12]print(演示集合,collection)# 快速创建本文向量是二维度量方式为余弦相似度。# 未显式声明的 metadata 字段通过动态字段保存。client.create_collection(collection_namecollection,dimension2,metric_typeCOSINE,auto_idFalse,enable_dynamic_fieldTrue,)# 手工向量仅为演示检索排序不代表真实语义。rows[{id:1,vector:[1.0,0.0],title:年假制度虚构,category:leave,text:入职满一年后可申请年假。},{id:2,vector:[0.9,0.1],title:年假申请虚构,category:leave,text:年假申请需提前提交。},{id:3,vector:[0.0,1.0],title:差旅制度虚构,category:travel,text:出差结束后按规定提交报销。},]resultclient.insert(collection_namecollection,datarows)print(写入结果,result)hitsclient.search(collection_namecollection,data[[1.0,0.0]],limit3,output_fields[title,category,text],search_params{metric_type:COSINE},consistency_levelStrong,)print(\n全部类别)forhitinhits[0]:print(hit)filteredclient.search(collection_namecollection,data[[1.0,0.0]],filtercategory leave,limit3,output_fields[title,category,text],search_params{metric_type:COSINE},consistency_levelStrong,)print(\n仅假期类别)forhitinfiltered[0]:print(hit)print(\n演示集合保留在服务端请记录名称并按你的数据管理流程清理。)if__name____main__:main()运行python milvus_demo.py在余弦相似度按预期工作的情况下查询向量[1, 0]与第 1 条最接近第 2 条次之过滤后只应返回category为leave的记录。具体返回格式、分数精度和可选参数请以客户端与服务端实际版本为准。脚本每次运行都会创建一个新集合并保留数据会消耗服务端资源。先确认连接的是专用测试实例不要在不了解权限和成本的情况下反复运行。本文不自动删除任何已有集合。五、逐步理解代码以下片段摘自第四节依赖前面步骤创建的client、collection等变量它们用于逐步理解不是相互独立的完整脚本。5.1 连接客户端urios.getenv(MILVUS_URI,http://localhost:19530)tokenos.getenv(MILVUS_TOKEN)kwargs{uri:uri}iftoken:kwargs[token]token clientMilvusClient(**kwargs)MilvusClient根据 URI 和可选 token 连接服务。地址填写错误、服务未启动、认证失败或网络被阻断都可能导致连接问题。上例没有打印 token也不在代码中硬编码。发生错误时公开日志前仍要检查其中是否包含连接信息或凭据。5.2 创建 Collectioncollectionrag_demo_uuid.uuid4().hex[:12]client.create_collection(collection_namecollection,dimension2,metric_typeCOSINE,auto_idFalse,enable_dynamic_fieldTrue,)快速创建接口中的dimension2必须与每个插入和查询向量的维度一致metric_typeCOSINE指定余弦相似度。真实 Embedding 模型可能输出数百或更多维必须按模型实际维度创建字段。快速创建适合入门。实际业务往往需要显式 Schema为文本字段指定类型、长度为向量字段指定维度和索引并决定是否允许动态字段。对必需字段、数据格式和约束进行校验能减少后续维护困难。示例使用enable_dynamic_fieldTrue保存额外字段。是否启用动态字段取决于数据治理和服务版本字段命名、可过滤性与限制应依据当前文档核对。5.3 写入数据rows[{id:1,vector:[1.0,0.0],title:年假制度虚构,category:leave,text:入职满一年后可申请年假。},]resultclient.insert(collection_namecollection,datarows)此处仅列出一条记录完整数据见第四节。请勿在已运行完整脚本创建的同一集合中重复插入相同 ID。示例手工提供 ID、向量和额外字段。真实项目应让每条记录关联原始文档和片段例如chunk_id、document_id、document_version、title、section、text、vector通常还需要管理来源和访问权限。文档更新时应保证旧向量、原文和元数据不会长期不一致更新策略可能包括覆盖、版本化或重建索引。批量写入还需考虑重试、幂等性和错误记录。5.4 向量搜索hitsclient.search(collection_namecollection,data[[1.0,0.0]],limit3,output_fields[title,category,text],search_params{metric_type:COSINE},consistency_levelStrong,)data是查询向量列表因此返回结果一般也按查询分组。limit控制返回的候选数量output_fields决定需要返回哪些字段。这里返回text只是为了观察示例真实系统应遵循最小权限和数据泄露防护原则。示例显式指定consistency_levelStrong用于降低刚写入后立即搜索因一致性问题看不到数据的风险一致性选项的可用性、性能影响和具体语义以服务端版本为准。5.5 标量过滤filteredclient.search(collection_namecollection,data[[1.0,0.0]],filtercategory leave,limit3,output_fields[title,category,text],search_params{metric_type:COSINE},consistency_levelStrong,)示例使用固定的category过滤表达式。不要直接拼接用户输入到过滤表达式中应使用 SDK/服务支持的安全参数化机制或严格的白名单与校验规则。过滤不自动等于权限安全。用户身份、租户和文档权限必须由受信任的服务端验证并保证在搜索和返回环节生效不要信任用户自行提供的权限过滤条件。六、如何换成真实 Embedding手工向量只是为了看清 Milvus 的操作。真正接入 RAG 时确定 Embedding 模型、版本、输出维度和相似度要求。将文档片段批量编码并保存文本、来源、版本和向量。将用户问题按模型要求编码为兼容向量。在对应向量字段检索获取候选原文。根据需要融合关键词检索、重排序并组装上下文。部分模型对查询和文档使用不同的前缀或编码函数必须遵循模型要求。更换模型时通常需要重新生成文档向量并重建或迁移索引仅仅维度相同不能证明两个模型的向量兼容。在更完整的 Milvus 应用中还可以进一步使用显式 Schema、稠密与稀疏向量字段并结合混合检索、RRF、Cross-Encoder 或 LangChain 集成。本文先聚焦入门流程检索策略与重排序将在系列后续文章中展开。具体功能和接口应以所用版本及部署方式为准。6.1 进阶显式 Schema 与两类向量字段前面的快速建集合有利于认识基本流程当字段、索引和检索方式需要明确控制时可以使用显式 Schema。下面展示一个配置片段保留主键、稠密向量、稀疏向量、正文和章节section字段并让 Milvus 的 BM25 函数处理正文。它不是独立运行的完整脚本请先连接支持相应功能的 Milvus 服务并确认客户端、服务端版本和中文分词器支持情况。frompymilvusimportDataType,Function,FunctionTypedefcreate_hybrid_collection(client,collection_name:str,embedding_dimension:int):# dimension 必须与实际 Embedding 输出一致不要直接套用示例值。schemaclient.create_schema(auto_idFalse,enable_dynamic_fieldFalse)schema.add_field(field_nameid,datatypeDataType.INT64,is_primaryTrue)schema.add_field(field_namedense,datatypeDataType.FLOAT_VECTOR,dimembedding_dimension)schema.add_field(field_namesparse,datatypeDataType.SPARSE_FLOAT_VECTOR)schema.add_field(field_namesection,datatypeDataType.VARCHAR,max_length128)schema.add_field(field_namecontent,datatypeDataType.VARCHAR,max_length2048,enable_analyzerTrue,analyzer_params{type:chinese},)schema.add_function(Function(namecontent_to_bm25,input_field_names[content],output_field_names[sparse],function_typeFunctionType.BM25,))indexesclient.prepare_index_params()indexes.add_index(field_namedense,index_typeAUTOINDEX,metric_typeCOSINE)indexes.add_index(field_namesparse,index_typeSPARSE_INVERTED_INDEX,metric_typeBM25)client.create_collection(collection_namecollection_name,schemaschema,index_paramsindexes)调用时由应用提供已认证的client、一个未使用的集合名以及实际模型的输出维度。写入前应为content生成对应的稠密向量稀疏字段的生成依赖这里配置的 BM25 函数。本文尚未对这段配置连接真实 Milvus 服务验证具体索引参数和分词器能力以所用版本官方文档为准。这段配置只负责集合结构不会自动完成检索融合。混合检索需要分别构造稠密和稀疏查询再用加权或 RRF 融合详见第八篇。不要在示例中硬编码服务地址、账号或令牌。七、常见问题1. 插入或查询时提示维度不一致检查集合向量字段的维度、文档向量维度和查询向量维度是否一致同时检查是否误用不同模型。2. 刚插入的数据搜索不到先核对集合名称、写入结果、一致性设置、索引与加载状态以及版本对应的接口行为。不要在不了解现有数据的情况下直接删除集合重建。3. 相似度高就代表答案正确吗不代表。向量分数只是一种相关性信号原文可能过期、条件不完整或与问题结论相反。最终仍需要证据核验和评估。4. 每次运行出现新集合怎么办这是示例为避免覆盖已有集合而采用的设计。请在确认集合归属和内容后按照组织的数据管理流程进行清理例如调用client.drop_collection(collection_name)删除对应集合不要复制无条件删除集合的脚本到生产环境。5. 真实服务请求失败检查服务是否启动、URI、网络、认证与客户端/服务端版本。提供错误信息时先移除令牌、密码和不应公开的内部地址。八、总结本文使用 Milvus 完成了一个最小的向量写入与检索流程创建集合 → 写入向量和元数据 → 向量检索 → 按字段过滤真实项目还需要 Embedding 选择、索引配置、权限、更新、评估和监控。下一篇将介绍查询改写、Multi-Query、HyDE 等查询优化方法。参考资料Milvus 文档https://milvus.io/docs/overview.mdPyMilvus 仓库https://github.com/milvus-io/pymilvus
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。