企业实战:Milvues向量数据库实践

发布时间:2026/8/19 11:38:01

企业实战:Milvues向量数据库实践
目录1 存入 Milvus (node_import_milvus)2 节点作用与实现思路3 导入与配置4 核心辅助函数5 主流程定义6 步骤 1: 检查输入7 步骤 2: 准备集合8 步骤 3: 清理旧数据9 步骤 4: 插入数据10 单元测试11 导入数据节点实现与测试11.1 进行主图调用测试 (main_graph)1 存入 Milvus (node_import_milvus)文件:app/import_process/node_import_milvus.py2 节点作用与实现思路节点作用: 数据加载流程的终点负责将处理好的结构化数据切片内容、元数据、向量持久化存储到向量数据库中构建可供即时查询的索引。实现思路:幂等性设计: 在插入新数据前根据item_name或文件 ID 清理旧数据防止重复导入导致的数据污染。Schema 适配: 严格按照 Milvus 集合的 Schema 定义主键、Dense字段、Sparse字段、JSON元数据字段组织数据确保插入成功率。混合索引构建: 确保存入的数据能够支持 Milvus 的 Hybrid SearchDense Sparse 加权最大化检索效果。3 导入与配置目的: 导入必要的库如pymilvus和项目工具类配置 Milvus 集合名称。关键点:CHUNKS_COLLECTION_NAME: 从环境变量获取集合名。add_running_task: 记录任务执行状态。# 导入Milvus相关依赖frompymilvusimportDataType# 导入自定义模块fromapp.import_process.agent.stateimportImportGraphStatefromapp.clients.milvus_utilsimportget_milvus_clientfromapp.utils.task_utilsimportadd_running_task,add_done_taskfromapp.core.loggerimportlogger,node_log,step_logfromapp.conf.milvus_configimportmilvus_config# 从配置文件读取切片集合名称与配置解耦便于环境切换CHUNKS_COLLECTION_NAMEmilvus_config.chunks_collection4 核心辅助函数功能: 处理幂等性清理删除旧数据和字符串转义。fromapp.utils.escape_milvus_string_utilsimportescape_milvus_string5 主流程定义函数:node_import_milvus逻辑:Step 1: 检查输入 (step_1_check_input)。Step 2: 准备环境 (step_2_prepare_collection)。Step 3: 清理旧数据 (step_3_clean_old_data)。Step 4: 插入数据 (step_4_insert_data)。 1. 检查数据 chunks是否存在 2. 前置准备工作 准备 milvus的集合和字段等 3. 删除旧数据 4. 查询chunks的数据即可 node_log(node_import_milvus)defnode_import_milvus(state:ImportGraphState)-ImportGraphState: 节点: 导入向量库 (node_import_milvus) 为什么叫这个名字: 将处理好的向量数据写入 Milvus 数据库。 # 准备日志和任务列表add_running_task(state[task_id],node_import_milvus)# 1. 检查数据 chunks是否存在chunksstate.get(chunks)ifnotchunks:logger.error(node_import_milvus: chunks数据不存在)raiseValueError(node_import_milvus: chunks数据不存在)# 2. 前置准备工作 创建 Milvus 集合和字段milvus_clientget_milvus_client()step_2_prepare_collection(milvus_client)# 3. 删除旧数据step_3_delete_old_data(milvus_client,state[item_name])# 4. 插入chunks的数据即可with_id_chunksstep_4_insert_collections(milvus_client,chunks)state[chunks]with_id_chunks add_done_task(state[task_id],node_import_milvus)returnstate6 步骤 1: 检查输入功能: 验证chunks是否存在并提取dense_vector维度和item_name。# 1. 检查数据 chunks是否存在chunksstate.get(chunks)ifnotchunks:logger.error(node_import_milvus: chunks数据不存在)raiseValueError(node_import_milvus: chunks数据不存在)7 步骤 2: 准备集合功能: 获取 Milvus 客户端如果集合不存在则创建。step_log(step_2_prepare_collection)defstep_2_prepare_collection(milvus_client): 准备和创建chunks对应的集合 :param milvus_client: :return: # 2. 判断是否存在集合表存在创建集合表ifnotmilvus_client.has_collection(collection_namemilvus_config.chunks_collection):# 创建集合# 3.1. 创建集合对应的列的信息schemamilvus_client.create_schema(auto_idTrue,# 主键自增长enable_dynamic_fieldTrue,# 动态字段)# 3.2. Add fields to schema# pk file_title item_name dense_vector sparse_vectorschema.add_field(field_namechunk_id,datatypeDataType.INT64,is_primaryTrue,auto_idTrue)schema.add_field(field_namefile_title,datatypeDataType.VARCHAR,max_length65535)schema.add_field(field_nameitem_name,datatypeDataType.VARCHAR,max_length65535)schema.add_field(field_namecontent,datatypeDataType.VARCHAR,max_length65535)schema.add_field(field_nametitle,datatypeDataType.VARCHAR,max_length65535)schema.add_field(field_nameparent_title,datatypeDataType.VARCHAR,max_length65535)schema.add_field(field_namepart,datatypeDataType.INT8)schema.add_field(field_namedense_vector,datatypeDataType.FLOAT_VECTOR,dim1024)schema.add_field(field_namesparse_vector,datatypeDataType.SPARSE_FLOAT_VECTOR)# 3.3 查询快配置索引index_paramsmilvus_client.prepare_index_params()index_params.add_index(field_namedense_vector,# 给哪个列创建索引 稠密index_namedense_vector_index,# 索引的名字index_typeHNSW,# 配置查找所用的算法metric_typeCOSINE,# 配置向量匹配和对比的 IP COSINEparams{M:32,# Maximum number of neighbors each node can connect to in the graphefConstruction:300},# or DAAT_WAND or TAAT_NAIVE) 10000 M 16 efConstruction 200 50000 M 32 efConstruction 300 100000 M 64 efConstruction 400 M:图中每个节点在层次结构的每个层级所能拥有的最大边数或连接数。M 越高图的密度就越大搜索结果的召回率和准确率也就越高因为有更多的路径可以探索但同时也会消耗更多内存并由于连接数的增加而减慢插入时间。如上图所示M 5表示 HNSW 图中的每个节点最多与 5 个其他节点直接相连。这就形成了一个中等密度的图结构节点有多条路径到达其他节点。 efConstruction:索引构建过程中考虑的候选节点数量。efConstruction 越高图的质量越好但需要更多时间来构建。 index_params.add_index(field_namesparse_vector,# Name of the vector field to be indexedindex_typeSPARSE_INVERTED_INDEX,# Type of the index to createindex_namesparse_vector_index,# Name of the index to createmetric_typeIP,# Metric type used to measure similarity# 只计算可能得高分的向量跳过大量的 0params{inverted_index_algo:DAAT_MAXSCORE},# Algorithm used for building and querying the index)milvus_client.create_collection(collection_namemilvus_config.chunks_collection,schemaschema,# 字段index_paramsindex_params# 索引)returnmilvus_client8 步骤 3: 清理旧数据功能: 根据item_name删除已存在的切片确保幂等性。step_log(step_3_delete_old_data)defstep_3_delete_old_data(milvus_client,item_name): 删除旧数据 根据item_name删除 :param milvus_client: :param item_name: :return: milvus_client.delete(collection_nameCHUNKS_COLLECTION_NAME,filterfitem_name{item_name})# 调用 load_collection() 会触发 Milvus 重新加载集合数据、刷新索引、清理已标记删除的数据确保删除操作真正生效避免新旧数据混杂导致检索错误。milvus_client.load_collection(collection_nameCHUNKS_COLLECTION_NAME)9 步骤 4: 插入数据功能: 移除临时chunk_id批量插入数据并回填生成的 ID。step_log(step_4_insert_collections)defstep_4_insert_collections(milvus_client,chunks): 插入集合的数据 :param milvus_client :param chunks: :return: chunks - 主键回显 insert_resultmilvus_client.insert(collection_nameCHUNKS_COLLECTION_NAME,datachunks)# 成功插入了几条insert_countinsert_result.get(insert_count,0)logger.info(f完成了数据插入成功插入了{insert_count}条数据)# 获取回显的idsidsinsert_result.get(ids,[])ifidsandlen(ids)len(chunks):forindex,chunkinenumerate(chunks):chunk[chunk_id]ids[index]returnchunks10 单元测试您可以在node_import_milvus.py文件底部直接运行以下测试代码if__name____main__:# --- 单元测试 ---# 目的验证 Milvus 导入节点的完整流程包括连接、创建集合、清理旧数据和插入新数据。importsysimportosfromdotenvimportload_dotenv# 加载环境变量 (自动寻找项目根目录的 .env)current_diros.path.dirname(os.path.abspath(__file__))project_rootos.path.dirname(os.path.dirname(current_dir))load_dotenv(os.path.join(project_root,.env))# 构造测试数据dim1024test_state{task_id:test_milvus_task,item_name:测试项目_Milvus,chunks:[{content:Milvus 测试文本 1,title:测试标题,item_name:测试项目_Milvus,# 必须有 item_name用于幂等清理parent_title:test.pdf,part:1,file_title:test.pdf,dense_vector:[0.1]*dim,# 模拟 Dense Vectorsparse_vector:{1:0.5,10:0.8}# 模拟 Sparse Vector},{content:Milvus 测试文本 2,title:测试标题2,item_name:测试项目_Milvus2,# 必须有 item_name用于幂等清理parent_title:test.pdf2,part:1,file_title:test.pdf2,dense_vector:[0.1]*dim,# 模拟 Dense Vectorsparse_vector:{1:0.5,10:0.8}# 模拟 Sparse Vector}]}print(正在执行 Milvus 导入节点测试...)try:# 检查必要的环境变量ifnotos.getenv(MILVUS_URL):print(❌ 未设置 MILVUS_URL无法连接 Milvus)elifnotos.getenv(CHUNKS_COLLECTION):print(❌ 未设置 CHUNKS_COLLECTION)else:# 执行节点函数result_statenode_import_milvus(test_state)# 验证结果chunksresult_state.get(chunks,[])ifchunksandchunks[0].get(chunk_id):print(f✅ Milvus 导入测试通过生成 ID:{chunks[0][chunk_id]})else:print(❌ 测试失败未能获取 chunk_id)exceptExceptionase:print(f❌ 测试失败:{e})11 导入数据节点实现与测试11.1 进行主图调用测试 (main_graph)主图添加测试代码进行流程完成测试if__name____main__:fromapp.utils.path_utilimportPROJECT_ROOTimportos# 全流程测试验证PDF导入→Milvus入库→KG导入完整链路logger.info( 开始执行知识图谱导入全流程测试 )# 1. 构造测试文件路径复用你项目的doc目录和pdf2md测试文件一致test_pdf_nameos.path.join(doc,万用表RS-12的使用.pdf)test_pdf_pathos.path.join(PROJECT_ROOT,test_pdf_name)# 2. 构造输出目录存放MD/图片等中间文件test_output_diros.path.join(PROJECT_ROOT,output)os.makedirs(test_output_dir,exist_okTrue)# 不存在则创建# 3. 校验测试PDF文件是否存在ifnotos.path.exists(test_pdf_path):logger.error(f全流程测试失败测试PDF文件不存在路径{test_pdf_path})logger.info(请检查文件路径或手动将测试文件放入项目根目录的doc文件夹中)else:# 4. 构造测试状态贴合实际业务入参开启PDF解析开关test_stateImportGraphState({task_id:test_kg_import_workflow_001,# 测试任务IDuser_id:test_user,# 测试用户IDlocal_file_path:test_pdf_path,# 测试PDF文件路径local_dir:test_output_dir,# 中间文件输出目录is_pdf_read_enabled:False,# 开启PDF解析核心开关is_md_read_enabled:False# 关闭MD解析})try:logger.info(f测试任务启动PDF文件路径{test_pdf_path})logger.info(f中间文件输出目录{test_output_dir})logger.info(开始执行全流程节点依次执行entry→pdf2md→md_img→split→item_name→embedding→milvus→kg)# 5. 执行LangGraph全流程流式执行打印节点执行进度final_stateNoneforstepinkb_import_app.stream(test_state,stream_modevalues):# 打印当前执行完成的节点流式输出更直观current_nodelist(step.keys())[-1]ifstepelse未知节点logger.info(f✅ 节点执行完成{current_node})final_statestep# 保存最终状态# 6. 全流程执行完成结果预览和核心指标打印iffinal_state:logger.info(-*80)logger.info( 全流程测试执行成功核心结果预览 )# 提取核心结果指标chunksfinal_state.get(chunks,[])chunk_countlen(chunks)md_contentfinal_state.get(md_content,)[:150]# MD内容前150字符has_embeddingall(dense_vectorincandsparse_vectorincforcinchunks)ifchunkselseFalsehas_chunk_idall(chunk_idincforcinchunks)ifchunkselseFalsekg_idfinal_state.get(kg_id,未生成)# KG导入生成的ID按实际业务字段调整# 打印核心指标logger.info(f PDF转MD内容预览前150字符{md_content}...)logger.info(f 文档切分总切片数{chunk_count})logger.info(f 所有切片是否完成向量化{是ifhas_embeddingelse否})logger.info(f️ 所有切片是否完成Milvus入库含chunk_id{是ifhas_chunk_idelse否})logger.info(f 知识图谱导入ID{kg_id})logger.info(f 最终状态包含的核心键{list(final_state.keys())})logger.info(-*80)exceptExceptionase:logger.exception(f 全流程测试运行失败 )logger.info( 知识图谱导入全流程测试结束 )输出日志—识别完成: HAK 180 烫金机—[Stub]执行节点node_bge_embedding—开始 BGE-M3 向量化处理 (node_bge_embedding)—成功获取第 1-5 项的嵌入。成功获取第 6-6 项的嵌入。— 向量化处理完成共处理 6 条数据 —[Stub] 执行节点node_import_milvus—开始导入 Milvus—从数据中检测到向量维度为: 1024从数据中检测到 item_name 为: HAK 180 烫金机正在连接到 Milvus 并准备集合 ‘kb_chunks’…幂等清理正在删除 Milvus 集合 ‘kb_chunks’ 中 item_nameHAK 180 烫金机 的旧切片…幂等清理完成item_nameHAK 180 烫金机准备了 6 条数据正在执行插入操作…成功插入 6 条数据。[Stub]执行节点node_import_kg 流程执行结束 ✅ 任务ID: full_graph_test_001✅ 文件标题: hak180产品安全手册✅ 识别商品: HAK 180 烫金机✅ 切片数量: 6✅ 向量化结果: 成功 (检测到 6 条带向量的数据)效果体现

相关新闻

多智能体系统规模化实战:架构、通信与决策的权衡之道

多智能体系统规模化实战:架构、通信与决策的权衡之道

2026/8/19 11:38:01

1. 项目概述:多智能体自主系统的规模化与权衡之道最近和几个做机器人集群和分布式AI的老同事聊天,大家不约而同地提到了一个共同的“甜蜜的烦恼”:系统规模上去了,但性能、成本和稳定性之间的拉扯也越来越让人头疼。这让我想起了我…

AI论文写作工具哪个最好?2026实测

AI论文写作工具哪个最好?2026实测

2026/8/19 11:38:01

"开题报告改5版仍被打回""文献综述堆30篇却毫无逻辑""格式排版耗3天还不符合学校要求""AI生成内容被AIGC检测标红"——2026年高校AI学术规范全面收紧,论文写作正面临前所未有的挑战。面对日益严格的审核标准,毕…

006.鸿蒙30痛——微服务/Ability:过度拆分下的“IPC风暴”与启动时延暴涨

006.鸿蒙30痛——微服务/Ability:过度拆分下的“IPC风暴”与启动时延暴涨

2026/8/19 11:38:01

6.0 微服务/Ability:过度拆分下的“IPC风暴”与启动时延暴涨 ——鸿蒙OS7 30痛:Ability粒度过细导致的跨进程调用非线性爆炸与启动边界 鸿蒙OS7 30大核心痛点:逻辑拓扑与因果链索引图兼目录 ↑↑↑——本系列总纲,建议优先阅读。所有痛点的前因后果、依赖关系、推荐阅读…

BPMN(Business Process Model and Notation)流程图中,泳道(Pool 和 Lane)是组织和可视化流程责任归属的关键结构

BPMN(Business Process Model and Notation)流程图中,泳道(Pool 和 Lane)是组织和可视化流程责任归属的关键结构

2026/8/19 12:38:03

BPMN(Business Process Model and Notation)流程图中,泳道(Pool 和 Lane)是组织和可视化流程责任归属的关键结构: Pool(池) 代表一个独立的参与者(如部门、系统或外部组织…

选对AI写作辅助软件少熬 3 个大夜!高口碑工具盘点 + 避坑全攻略

选对AI写作辅助软件少熬 3 个大夜!高口碑工具盘点 + 避坑全攻略

2026/8/19 12:38:03

每到毕业季,论文就像一道过不去的坎儿,选题没思路、写初稿卡得慌、格式改来改去、查重标红一大片、AIGC检测风险还高悬,通宵熬夜成了家常便饭。很多人以为AI工具能一键生成整篇论文,结果一用就翻车,不仅没帮上忙&#…

一键生成论文工具最全盘点:从语法纠错到查重降AI,这一篇承包你的全部痛点

一键生成论文工具最全盘点:从语法纠错到查重降AI,这一篇承包你的全部痛点

2026/8/19 12:38:03

论文写完了,但总觉得哪里不对劲?别急,这些 AI 工具能帮你把初稿打磨成能上战场的“兵器”。每年毕业季,后台总能看到无数同学在问:“论文写完怎么改才能过审?”作为一个从“查重率 50%”被吓到肝颤、最后靠…

基于视觉语言模型的无人机自主导航:QuadAgent系统架构与工程实践

基于视觉语言模型的无人机自主导航:QuadAgent系统架构与工程实践

2026/8/19 12:38:03

1. 项目概述:当无人机学会“看”与“听”最近在机器人圈子里,一个叫“QuadAgent”的项目讨论热度挺高。简单来说,它试图解决一个听起来很科幻、但实际落地困难重重的问题:让一架四旋翼无人机(Quadrotor)不仅…

选对AI写论文工具少掉 3 把头发!人气工具盘点 + 选前必看避坑

选对AI写论文工具少掉 3 把头发!人气工具盘点 + 选前必看避坑

2026/8/19 12:38:03

每到毕业季,无数同学陷入论文循环:选题毫无头绪、写初稿卡壳、反复改格式、查重标红一大片、AIGC检测风险高悬,通宵熬夜成为常态。很多人误以为AI工具就是一键生成整篇论文,踩坑之后才发现,工具选不对,不仅…

基于树莓派的智能硬件开发:从语音识别到视觉处理的端侧AI实践

基于树莓派的智能硬件开发:从语音识别到视觉处理的端侧AI实践

2026/8/19 12:28:02

1. 项目缘起:从“Laura”到“Smart Rabbit”的智能构想最近在捣鼓一个挺有意思的小项目,我给它起了个名字叫“Smart Rabbit : Laura”。这个名字听起来可能有点抽象,但它的内核其实很具体:我想做一个能听、能看、能思考&#xff0…

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

2026/8/19 3:36:59

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

【双层规划,节点出清价,绿证交易,CVaR方法】两级电力市场环境下计及风险的省间交易商最优购电模型附Matlab代码

【双层规划,节点出清价,绿证交易,CVaR方法】两级电力市场环境下计及风险的省间交易商最优购电模型附Matlab代码

2026/8/19 9:17:18

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

隐式mpc+自适应mpc+时变mpc,线性时变模型预测控制附Simulink仿真

隐式mpc+自适应mpc+时变mpc,线性时变模型预测控制附Simulink仿真

2026/8/19 8:02:16

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

SQL 调优 [ 2 ]

SQL 调优 [ 2 ]

2026/8/19 0:07:32

type列详解EXPLAIN输出的type列描述了表是如何连接的,性能从最好到最差的排序如下:systemconsteq_refreffulltextref_or_nullindex_mergeunique_subqueryindex_subqueryrangeindexALL接下来我们对 type列 做详细讲解。我们都知道,想要评估一条…

正式评优怎么选投票工具?人人微投票审计级防刷能力实测

正式评优怎么选投票工具?人人微投票审计级防刷能力实测

2026/8/19 0:07:32

在线上投票工具遍地开花的今天,选择一个合适的平台,本质上是在做一道关于场景与需求的匹配题。人人微投票是一个很典型的案例——它的产品逻辑、技术架构和商业模式,都围绕着“正式评选”这个细分场景深度扎根,也因此形成了自己鲜…

15 天 3 连发:DeepSeek 的「机枪」节奏,到底在下什么棋?

15 天 3 连发:DeepSeek 的「机枪」节奏,到底在下什么棋?

2026/8/19 0:07:32

15 天 3 连发:DeepSeek 的「机枪」节奏,到底在下什么棋?回看 2026 年 8 月这半个月,DeepSeek 的动作密度堪称疯狂:月初端出便宜快速的 V4-Flash,8 月 13 日同一天甩出 V4-Pro 正式版 开源 Harness 框架&am…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/17 12:00:53

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/15 10:10:27

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/18 12:20:24

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…