LangChain与Milvus向量数据库DML操作实战指南

发布时间:2026/8/24 12:12:25
LangChain与Milvus向量数据库DML操作实战指南
1. 先搞清楚 LangChain Milvus DML 到底能解决什么问题如果你正在处理海量的非结构化数据比如文档、图片、音频并且想快速从中找到相似内容或者构建一个能“理解”你问题的智能问答系统那么 LangChain 结合 Milvus 的 DML数据操作语言能力就是一个绕不开的技术栈。它解决的核心问题是如何高效地存储、检索和管理由大模型生成的向量数据并让这些数据能被 LangChain 的智能体Agent或链Chain灵活调用。很多人一听到 LangChain 和 Milvus 就觉得复杂其实可以拆开看LangChain是你的“大脑”和“指挥中心”。它负责调用大模型LLM来理解你的问题、生成文本、做决策并且能串联起不同的工具和步骤。Milvus是你的“超级记忆库”。它专门用来存储和检索向量一种用数字表示文本、图像等内容的数学形式。当你问“帮我找和合同第5条最相似的条款”Milvus 能在一亿条数据里毫秒级找到最相关的几条。DML就是操作这个“记忆库”的语言。它不只是简单的“存”和“查”而是包括了插入Insert、删除Delete、更新Update、查询Search/Query这一整套对向量数据的增删改查操作。所以这个组合的实战价值在于你将拥有一个既能理解复杂意图LangChain又能瞬间从海量数据中精准定位信息Milvus并且能对底层数据进行动态管理DML的智能系统。它非常适合构建企业级知识库问答、内容推荐、欺诈检测、AIGC内容去重等场景。我建议你先别急着看代码而是想清楚你的数据流用户问题 - LangChain 解析并可能调用工具 - 工具将问题转化为向量 - 向 Milvus 发起 DML 操作 - 拿到结果 - LangChain 组织答案。把这个流程想通了再看具体实现会清晰很多。2. 环境准备别在依赖版本上踩坑实战的第一步永远是搭环境。这里最容易出问题的不是 LangChain 或 Milvus 本身而是它们依赖的 Python 包版本冲突以及 Milvus 的服务状态。下面是我实测过相对稳定的组合你可以作为起点。2.1 核心组件与版本建议我一般会创建一个新的 Python 虚拟环境来隔离依赖避免污染系统环境。# 创建并激活虚拟环境以 conda 为例 conda create -n langchain-milvus python3.9 conda activate langchain-milvus然后安装核心包。注意版本这是关键pip install langchain0.1.0 # 选择一个稳定的主版本 pip install pymilvus2.3.0 # 与你的 Milvus 服务端版本匹配至关重要 pip install langchain-community # 很多社区集成的向量库连接器在这里 pip install sentence-transformers # 用于本地生成文本向量可选但测试很方便为什么强调版本pymilvus的客户端版本必须与后端 Milvus 服务端版本兼容。如果你用 Milvus 2.3.x客户端最好也用 2.3.x。版本不匹配可能会导致连接失败、API 调用错误等难以排查的问题。安装前先确认你的 Milvus 服务端版本。2.2 Milvus 服务部署与连接验证Milvus 可以以 Standalone单机或 Cluster集群模式运行。对于学习和功能验证Standalone 模式完全足够。安装与启动以 Docker 方式为例# 拉取最新稳定版本的 Standalone 镜像 docker pull milvusdb/milvus:v2.3.0-standalone-latest # 运行容器映射端口 docker run -d --name milvus-standalone \ -p 19530:19530 \ -p 9091:9091 \ milvusdb/milvus:v2.3.0-standalone-latest19530是 Milvus 的服务端口。9091是 Milvus 的管理界面Attu端口方便可视化操作。连接验证服务启动后不要假设它一定正常。先用最简单的 Python 脚本测试连通性。from pymilvus import connections, utility # 连接到 Milvus 服务 connections.connect(hostlocalhost, port19530) # 检查连接是否成功并查看服务端版本 print(utility.get_server_version()) print(utility.list_collections()) # 查看现有集合初始应为空列表如果这段代码能成功运行并打印出版本号说明 Milvus 服务连接正常。如果报错按以下顺序排查服务状态docker ps确认容器是否在运行。网络连通telnet localhost 19530或curl localhost:9091/health检查端口是否可访问。版本兼容确认pymilvus与 Milvus 服务端版本。防火墙检查服务器防火墙是否放行了相关端口。3. 从零构建一个向量检索链理解核心 DML 操作环境就绪后我们用一个完整的例子串起 LangChain 和 Milvus 的 DML 操作。目标是将几段文本存入 Milvus然后通过 LangChain 发起一个问答让 LangChain 自动从 Milvus 中检索出相关文本作为上下文最终生成答案。3.1 第一步创建集合Collection与定义 Schema在 Milvus 里数据存储在“集合”中类似于数据库的表。定义集合需要指定 Schema其中最重要的是向量字段。from pymilvus import CollectionSchema, FieldSchema, DataType, Collection # 1. 定义字段 # 主键字段 id_field FieldSchema(nameid, dtypeDataType.INT64, is_primaryTrue, auto_idTrue) # 文本内容字段 text_field FieldSchema(nametext, dtypeDataType.VARCHAR, max_length65535) # 向量字段假设我们使用 384 维的向量 embedding_field FieldSchema(nameembedding, dtypeDataType.FLOAT_VECTOR, dim384) # 2. 构建 Schema schema CollectionSchema(fields[id_field, text_field, embedding_field], description用于测试的文档集合) # 3. 创建集合 collection_name langchain_demo_collection collection Collection(namecollection_name, schemaschema) # 4. 创建索引这是高效检索的前提 index_params { index_type: IVF_FLAT, # 一种常见的量化索引类型适合中小规模数据集 metric_type: L2, # 距离度量方式L2欧氏距离也常用“IP”内积 params: {nlist: 128}, # 聚类中心数影响检索速度和精度通常设为 sqrt(数据量) } collection.create_index(field_nameembedding, index_paramsindex_params) print(f集合 {collection_name} 创建成功并已建立索引。)关键点解析auto_idTrue让 Milvus 自动生成唯一 ID简化插入操作。dim384必须与你后续生成的向量维度一致。例如sentence-transformers的all-MiniLM-L6-v2模型生成 384 维向量。创建索引这是 DML 中影响性能最关键的一步。没有索引的向量检索是暴力扫描数据量稍大就不可用。IVF_FLAT是平衡速度和精度的常用选择。3.2 第二步插入数据Insert DML接下来我们生成一些文本的向量并插入到集合中。from sentence_transformers import SentenceTransformer import random # 加载一个本地嵌入模型 embed_model SentenceTransformer(all-MiniLM-L6-v2) # 准备一些示例文本 documents [ LangChain 是一个用于开发由大语言模型驱动的应用程序的框架。, Milvus 是一个开源的向量数据库专为海量向量数据的存储和检索而设计。, DML 指的是数据操作语言包括插入、删除、更新和查询。, 向量检索是通过计算向量间的相似度来找到最相关的内容。, Python 是一种流行的编程语言广泛用于人工智能和数据分析。 ] # 为文本生成向量 embeddings embed_model.encode(documents).tolist() # 转换为列表 # 准备插入的数据注意字段顺序与 Schema 定义一致 # id 字段是自增的所以我们不需要提供 data_to_insert [ documents, # 对应 text 字段 embeddings # 对应 embedding 字段 ] # 执行插入操作 insert_result collection.insert(data_to_insert) print(f插入了 {len(insert_result.primary_keys)} 条数据。) print(f生成的主键 IDs: {insert_result.primary_keys}) # 重要将数据从内存持久化到磁盘 collection.flush()注意collection.flush()非常关键。插入操作默认先写入内存缓冲区flush会确保数据被持久化并变得可搜索。在生产环境中你可能需要根据数据量和性能要求调整刷盘策略。3.3 第三步构建 LangChain 检索链现在我们让 LangChain 登场。我们将使用LangChain的VectorStore抽象来封装 Milvus 的操作。from langchain.vectorstores import Milvus from langchain.embeddings import HuggingFaceEmbeddings from langchain.chains import RetrievalQA from langchain.llms import OpenAI # 或者使用 ChatOpenAI import os # 1. 设置 OpenAI API Key (如果你使用 OpenAI 的模型) os.environ[OPENAI_API_KEY] your-api-key-here # 2. 创建 LangChain 兼容的嵌入模型对象 # 这里我们使用与插入时相同的模型确保向量空间一致 embeddings HuggingFaceEmbeddings(model_nameall-MiniLM-L6-v2) # 3. 连接到已存在的 Milvus 集合创建 VectorStore 对象 # 这一步本质上是将我们之前手动创建的 Collection 用 LangChain 的方式包装起来 vector_store Milvus( embedding_functionembeddings, collection_namelangchain_demo_collection, connection_args{host: localhost, port: 19530}, ) # 4. 创建检索器 (Retriever) # search_kwargs 可以控制返回的结果数量 retriever vector_store.as_retriever(search_kwargs{k: 3}) # 5. 创建大语言模型对象 llm OpenAI(temperature0) # temperature0 使输出更确定适合事实性问答 # 6. 构建检索问答链 qa_chain RetrievalQA.from_chain_type( llmllm, chain_typestuff, # 将检索到的所有文档内容“塞”进上下文 retrieverretriever, return_source_documentsTrue # 返回检索到的源文档便于调试 ) # 7. 进行提问 question 什么是 Milvus result qa_chain({query: question}) print(f问题: {question}) print(f答案: {result[result]}) print(\n--- 检索到的源文档 ---) for doc in result[source_documents]: print(f- {doc.page_content})流程解读Milvus这个VectorStore类帮我们隐藏了底层的 DML 细节。当执行检索时它内部会做将问题文本编码成向量 - 在 Milvus 集合中执行向量相似性搜索Search DML- 返回最相似的原始文本。RetrievalQA链将检索和问答组合它先调用retriever获取相关文档然后将这些文档和问题一起组装成提示词Prompt发送给 LLM 生成最终答案。chain_typestuff是最简单直接的方式但如果检索到的文档总长度超过 LLM 的上下文限制会报错。对于长文档需要考虑map_reduce、refine等其他链类型。3.4 第四步探索其他 DML 操作更新与删除一个完整的系统需要对数据生命周期进行管理。除了插入和查询更新和删除也是必要的。更新Update DMLMilvus 支持通过主键更新标量字段如text但不支持直接更新向量字段。更新向量通常需要先删除再插入。# 假设我们要更新 id 为 1 的记录的文本内容 expr id 1 new_text [“Milvus 是一个高性能、云原生的开源向量数据库。”] # 准备更新数据注意字段名和数据的对应关系 update_data {text: new_text} # 执行更新 collection.upsert(dataupdate_data) # upsert 是 update 和 insert 的合并操作 collection.flush() print(“数据更新完成。”)删除Delete DML删除操作基于布尔表达式。# 删除 text 字段包含“Python”的记录 delete_expr ‘text like “%Python%”’ collection.delete(exprdelete_expr) collection.flush() print(“符合条件的数据已删除。”) # 清空整个集合谨慎操作 # collection.drop()4. 进阶实战在 Agent 中动态使用 Milvus DMLLangChain 的 Agent 是其精髓它可以让 LLM 自主决定何时、如何使用工具。我们可以将 Milvus 的 DML 操作封装成工具交给 Agent 调用。4.1 将 Milvus 操作封装为 Toolfrom langchain.tools import Tool from pymilvus import Collection, connections # 确保连接已建立 connections.connect(host‘localhost’, port‘19530’) collection Collection(“langchain_demo_collection”) collection.load() # 将集合加载到内存以进行搜索 def search_in_milvus(query: str) - str: “”“一个简单的搜索工具根据查询文本在 Milvus 中查找相似内容。”“” from sentence_transformers import SentenceTransformer model SentenceTransformer(‘all-MiniLM-L6-v2’) query_embedding model.encode([query]) search_params {“metric_type”: “L2”, “params”: {“nprobe”: 10}} # nprobe 搜索时探查的聚类数 results collection.search( dataquery_embedding, anns_field“embedding”, paramsearch_params, limit3, output_fields[“text”] # 指定要返回的字段 ) ret [] for hits in results: for hit in hits: ret.append(f”[相似度: {hit.score:.4f}] {hit.entity.get(‘text’)}“) return ”\n“.join(ret) if ret else “未找到相关结果。” def insert_to_milvus(text: str) - str: “”“一个插入工具将一段文本存入 Milvus。”“” from sentence_transformers import SentenceTransformer model SentenceTransformer(‘all-MiniLM-L6-v2’) text_embedding model.encode([text]).tolist() data [[text], text_embedding] insert_result collection.insert(data) collection.flush() return f”插入成功主键 ID 为{insert_result.primary_keys}“ # 创建 Tool 列表 tools [ Tool( name“KnowledgeBaseSearch”, funcsearch_in_milvus, description“当用户询问关于 LangChain, Milvus, 向量数据库DML 或相关技术概念时使用此工具从知识库中查找最相关的信息。” ), Tool( name“AddToKnowledgeBase”, funcinsert_to_milvus, description“当用户提供一段新的、有价值的技术文本关于AI、数据库、编程等并希望保存到知识库时使用此工具。” ), ]4.2 创建并运行 Agentfrom langchain.agents import initialize_agent, AgentType from langchain.llms import OpenAI llm OpenAI(temperature0, model“gpt-3.5-turbo-instruct”) # 使用适合 Agent 的模型 # 初始化 Agent agent initialize_agent( tools, llm, agentAgentType.ZERO_SHOT_REACT_DESCRIPTION, # 一种通用的 Agent 类型 verboseTrue, # 打印 Agent 的思考过程便于调试 handle_parsing_errorsTrue # 处理解析错误 ) # 运行 Agent print(“ Agent 对话开始 ) result agent.run(“LangChain 和 Milvus 通常如何一起使用”) print(f”最终答案{result}“) print(”\n Agent 执行插入操作 ) result2 agent.run(“请将这句话加入知识库’RAG 是检索增强生成的缩写它结合了检索系统和生成模型。’”) print(f”插入结果{result2}“)当你运行这段代码并设置verboseTrue时你会看到 Agent 的思考链ReAct例如Thought: 用户问的是 LangChain 和 Milvus 如何一起使用这是一个技术概念问题。我应该使用 KnowledgeBaseSearch 工具。 Action: KnowledgeBaseSearch Action Input: LangChain Milvus usage Observation: [相似度: 0.12] LangChain 是一个用于开发由大语言模型驱动的应用程序的框架。 [相似度: 0.25] Milvus 是一个开源的向量数据库专为海量向量数据的存储和检索而设计。 Thought: 我找到了一些相关信息我可以结合这些信息来回答用户。 Final Answer: LangChain 是一个LLM应用开发框架而 Milvus 是专门的向量数据库。它们通常一起用于构建检索增强生成RAG系统。具体流程是用 LangChain 处理用户查询和协调流程用 Milvus 存储和快速检索文档的向量化表示然后将检索到的文档作为上下文提供给 LLM 生成精准答案。通过这种方式Milvus 的 DML 操作搜索、插入就变成了 Agent 可自主调用的“技能”能够处理更复杂、多步骤的交互任务。5. 生产环境考量与常见问题排查把 Demo 跑通只是第一步。要真正用于生产有几个关键点必须提前规划。5.1 性能、稳定性与扩展性索引选择与调优IVF_FLAT适合内存充足、追求精度的场景。如果数据量极大数亿以上需要考虑IVF_SQ8量化节省空间或HNSW高召回率、速度快但内存占用大等索引。nlist、M、efConstruction等参数需要根据数据和硬件调整。集合分区Partition对于超大规模数据或有多租户需求的场景使用分区可以将数据物理隔离提升查询效率和管理灵活性。DML 操作需要指定分区键。连接管理与池化在高并发场景下频繁创建和关闭连接开销很大。需要使用连接池如pymilvus.connections提供的连接别名和池化配置。负载均衡与高可用Standalone 模式有单点故障风险。生产环境应部署 Milvus 集群并配置负载均衡器。LangChain 客户端可以配置多个连接地址。数据持久化与备份虽然 Milvus 有持久化机制但定期的数据快照和日志备份是必须的。了解backup和restore命令。5.2 常见错误与排查清单问题连接 Milvus 失败。排查检查 Milvus 服务是否运行 (docker ps或systemctl status milvus)。检查主机名、端口、防火墙。检查pymilvus版本兼容性。问题插入数据成功但搜索不到。排查是否忘记了collection.flush()数据是否还在内存缓冲区插入后是否执行了collection.load()将集合加载到内存索引是否创建成功问题搜索速度很慢。排查集合是否已加载索引类型是否合适搜索参数nprobe是否设置过大精度高但速度慢服务器资源CPU、内存是否充足问题LangChain 检索器返回的结果不相关。排查这是最常见的问题之一。首先确认插入数据和查询时使用的嵌入模型是否完全相同。不同的模型产生的向量不在同一个空间无法比较。其次检查向量维度dim是否定义正确。最后尝试调整检索时的search_kwargs比如增加k值或使用不同的search_type如mmr最大边际相关性来兼顾相关性和多样性。问题Agent 不调用我定义的 Milvus 工具。排查检查 Tool 的description是否清晰、准确地描述了使用场景。LLM 根据描述决定是否调用。可以尝试将描述写得更具体包含关键词。同时在initialize_agent时尝试使用AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION等更适合对话的 Agent 类型。问题处理长文档时 LLM 报错超出上下文长度。排查这是RetrievalQA链chain_type“stuff”的局限性。需要切换策略map_reduce: 将每个检索到的文档单独总结再总结所有摘要。refine: 迭代地处理文档不断精炼答案。map_rerank: 对每个文档打分只选用高分文档。或者在数据入库前对长文档进行切分chunking这是 RAG 系统的基础步骤LangChain 提供了多种文本分割器。5.3 监控与日志Milvus 监控使用AttuWeb UI或PrometheusGrafana监控集群健康度、QPS、延迟、资源使用情况。LangChain 日志开启 LangChain 的详细日志 (verboseTrue) 来跟踪 Agent 的决策过程和工具调用链。应用日志在你的应用代码中记录关键的 DML 操作如插入ID、查询条件、返回数量和耗时便于问题追踪和性能分析。把 LangChain、Milvus 和 DML 结合起来真正的挑战不在于写出能跑的代码而在于设计一个稳定、高效、易维护的数据流和架构。我的建议是在项目初期就明确数据的来源、更新频率、查询模式并据此设计 Milvus 的集合结构、索引策略和 LangChain 的链/Agent 流程。先用一个最小可行产品MVP跑通核心流程然后逐步加入错误处理、日志、监控和性能优化。