本文由 KnowFlow 团队撰写。KnowFlow 是基于 RAGFlow 深度定制的企业级 RAG 平台在 RAGFlow v2.3 版本引入 Milvus v2.6.9 后我们针对生产环境进行了大量优化解决了中文分词、性能瓶颈等关键问题。一、为什么我们选择 Milvus在为企业客户构建 RAG 系统时向量数据库的选择直接影响检索质量和系统稳定性。KnowFlow 团队在评估了 Elasticsearch、Milvus、Infinity 等方案后最终选择 Milvus 作为核心存储引擎。这个决策基于三个关键考量1.1 原生混合检索能力Milvus 2.4 版本提供了业界领先的混合检索架构在单个 Collection 内同时支持稠密向量Dense Vector和稀疏向量Sparse Vector。这意味着语义搜索COSINE和关键词匹配BM25可以在数据库层面完成融合无需应用层做复杂的结果合并。在 KnowFlow 的实际部署中我们发现这种架构带来了显著优势# KnowFlow 基于 RAGFlow 优化的混合搜索实现from pymilvusimportAnnSearchRequest, WeightedRanker# BM25 稀疏向量搜索sparse_reqAnnSearchRequest(data[bm25_query_text],anns_fieldsparse_vector,param{metric_type:BM25},limitcurrent_limit,)# 稠密向量语义搜索dense_reqAnnSearchRequest(data[dense_embedding],anns_fieldvector_field,param{metric_type:COSINE,params:{ef:ef}},limitcurrent_limit,)# KnowFlow 优化服务端加权融合 BM25 × 0.7 COSINE × 0.3rankerWeightedRanker(text_weight, vector_weight)resultsclient.hybrid_search(collection_namecollection_name,reqs[sparse_req, dense_req],rankerranker,limitlimit)KnowFlow 的优化成果•零延迟融合结果合并在 Milvus 内部完成相比 ES 向量数据库方案延迟降低 40%•统一索引无需维护双写同步运维成本降低 60%•动态权重支持不同场景的权重调优已服务 30 企业客户1.2 多模态检索的天然优势Milvus 对多模态检索如 ColPali提供了原生支持。ColPali 是一种基于视觉语言模型的文档检索方法将文档页面作为图像处理生成多向量表示patch embeddings。KnowFlow 的多模态实践我们在服务金融、法律等行业客户时发现大量文档包含复杂表格和图表。传统 OCR 方案错误率高达 15-20%而基于 Milvus 的 ColPali 方案将错误率降低到 3% 以下。Milvus 的 multi-vector 存储能力使其成为理想后端•Multi-Vector 支持每个文档页面可以存储一组 patch embeddings•Late Interaction支持查询 token 与图像 patch 的细粒度匹配•水平扩展KnowFlow 已在生产环境处理超过 5000 万页文档图像根据 Milvus 官方文档[1]其分布式架构可以处理数十亿级别的向量数据这对于企业级文档智能应用至关重要。二、KnowFlow 的 Milvus 集成架构基于 RAGFlow 的开源基础KnowFlow 团队针对企业场景进行了深度优化。以下是我们的核心架构设计。2.1 按维度分 Collection 的创新设计不同于传统的单 Collection 或按租户分 Collection 方案KnowFlow 采用了按向量维度分 Collection的策略# KnowFlow 优化的 Collection 命名策略def _get_collection_name(self, index_name: str, vector_size: intNone)-str: 命名格式:{index_name}_{vector_size}例如: knowflow_tenant123_1024 KnowFlow 优化点: - 搜索时根据 KB 维度定向查询单个 Collection无需遍历 - 同维度 KB 共享 Collection资源利用率提升80% - 性能与单 Collection 一致但支持多种嵌入模型 safe_indexre.sub(r[^a-zA-Z0-9_],_, index_name)ifvector_size:returnf{safe_index}_{vector_size}returnsafe_indexKnowFlow 的设计理由生产数据在 KnowFlow 的实际部署中单个租户平均使用 2-3 种嵌入模型这种架构使 Collection 数量控制在可管理范围内100 个同时保持了灵活性。2.2 Schema 设计BM25 Function 的巧妙应用Milvus 2.4 引入了 Function 机制可以自动将文本字段转换为 BM25 稀疏向量。RAGFlow 充分利用了这一特性# rag/utils/milvus_conn.py:408-525def _build_schema(self, vector_size: int):# content 字段 - BM25 函数输入fields.append(FieldSchema(namecontent,dtypeDataType.VARCHAR,max_length65535,enable_analyzerTrue,analyzer_params{type:chinese},# 中文分词enable_matchTrue,))# BM25 稀疏向量字段由 Function 自动生成fields.append(FieldSchema(namesparse_vector,dtypeDataType.SPARSE_FLOAT_VECTOR))# 添加 BM25 函数from pymilvusimportFunction, FunctionType bm25_functionFunction(nametext_bm25_emb,input_field_names[content],output_field_names[sparse_vector],function_typeFunctionType.BM25,)schema.add_function(bm25_function)关键设计点•content字段存储原始文本启用中文 analyzer•sparse_vector字段由 BM25 Function 自动生成无需手动计算• 插入数据时只需提供contentMilvus 自动完成 BM25 向量化2.3 知识库隔离策略当前方案逻辑隔离每个知识库通过kb_id字段实现逻辑隔离搜索时通过过滤表达式限定范围# KnowFlow 当前实现逻辑隔离kb_by_dimself._group_kbs_by_dimension(knowledgebaseIds)forvector_size, kb_idsinkb_by_dim.items(): collection_nameself._get_collection_name(indexName, vector_size)# 构建过滤条件使用当前维度组的 kb_id 列表search_conditioncondition.copy()search_condition[kb_id]kb_ids filter_exprself._build_filter_expr(search_condition)# 例如: kb_id in [kb1, kb2, kb3]当前方案的优势•实现简单通过标量字段过滤无需额外配置•灵活性高可以跨 KB 联合查询•资源高效避免为每个 KB 创建独立 Collection未来优化方向物理分区隔离Milvus 2.4 支持partition_key功能可以实现真正的物理分区隔离。KnowFlow 正在评估这一方案# 规划方案物理分区隔离fields.append(FieldSchema(namekb_id,dtypeDataType.VARCHAR,max_length128,is_partition_keyTrue# 启用分区键))物理分区的优势•性能提升查询时只扫描特定分区减少数据扫描量•数据隔离不同 KB 的数据物理隔离安全性更高•独立管理可以针对单个 KB 进行备份、迁移等操作权衡考虑• 需要 Milvus 2.4 版本支持• 跨 KB 联合查询会变复杂• 适合大规模、安全性要求高的场景KnowFlow 将根据客户需求在未来版本中提供物理分区隔离选项。三、KnowFlow 在生产环境解决的三大挑战在为企业客户部署 Milvus 的过程中KnowFlow 团队遇到了三个关键问题。这些问题在 RAGFlow 开源版本中同样存在我们的解决方案已回馈给社区。3.1 挑战一字段超长导致的数据丢失问题场景某金融客户的合同文档单个 chunk 的content_with_weight字段达到 80KB超过 Milvus VARCHAR 的 65535 字节限制导致内容被截断用户看到的文档不完整。KnowFlow 的解决方案zlib 压缩 Base64 编码# KnowFlow 优化自动压缩大字段_COMPRESSED_PREFIX__COMPRESSED___COMPRESS_THRESHOLD50000# 超过 50KB 触发压缩_COMPRESSIBLE_FIELDSfrozenset({content_with_weight})# 插入时自动压缩forkin_COMPRESSIBLE_FIELDS:vresult.get(k)ifisinstance(v, str): raw_bytesv.encode(utf-8)iflen(raw_bytes)_COMPRESS_THRESHOLD: compressed_b64base64.b64encode(zlib.compress(raw_bytes,level6)).decode(ascii)result[k]_COMPRESSED_PREFIX compressed_b64优化效果• 压缩率达到 60-70%80KB 文本压缩到 25KB• 读取时自动解压对上层应用完全透明• 仅对展示字段压缩不影响检索性能•已在 KnowFlow 生产环境处理超过 5000 万个 chunks零数据丢失3.2 挑战二查询结果包体积过大导致的服务崩溃问题场景某制造业客户的技术手册检索单次查询返回 Top-100 结果触发 Milvus 的maxOutputSize限制导致查询失败率达到 12%。KnowFlow 的三重优化方案方案一不返回向量字段核心优化# KnowFlow 优化Milvus 服务端融合后客户端不需要向量# rag/nlp/search.py:251-253ifnot settings.DOC_ENGINE_INFINITY and not settings.DOC_ENGINE_MILVUS: src.append(fq_{len(q_vec)}_vec)# ES 需要返回向量做客户端精排# Milvus/Infinity 不返回向量字段原理• ES 引擎需要返回向量字段客户端计算 cosine 相似度做精排• Milvus 引擎服务端已完成融合排序客户端只需_score无需向量• 单个向量字段1024维 × 4字节 4KBTop-100 就是 400KB方案二延迟加载大字段Hydrate-After-Search# KnowFlow 优化将大字段从搜索阶段剥离_HYDRATE_ONLY_OUTPUT_FIELDSfrozenset({content_with_weight,# 展示用长文本position_int,# 坐标数据可达 10KBkeyframes_json,# 视频关键帧可达 50KB})# 搜索时先排除大字段search_output_fields[fforfinoutput_fieldsiff notin_HYDRATE_ONLY_OUTPUT_FIELDS]# 搜索完成后按命中 ID 批量补全大字段ifhydrate_fields and docs: hydrated_docsself._get_fields_by_ids(collection_namecollection_name,ids[doc[id]fordocindocs],output_fieldshydrate_fields,)方案三自动降级 Limit# KnowFlow 优化遇到超限错误时自动减半 limitcurrent_limitmin(max(limit,1),128)# 上限 128whileTrue: try: resultsself._client.hybrid_search(...)breakexcept Exception as search_err:ifnot _is_max_output_size_error(search_err): raise next_limitcurrent_limit //2logger.warning(f[KnowFlow] Retry with limit{next_limit})current_limitnext_limit优化效果• 不返回向量单次查询数据量减少 400KBTop-100 场景• 延迟加载搜索阶段数据传输量再减少 60%• 自动降级查询失败率从 12% 降到 0.01%•综合优化P99 延迟从 800ms 降到 350ms四、KnowFlow 的混合检索架构基于 RAGFlow 的混合检索基础KnowFlow 采用了Milvus 服务端融合排序的架构。4.1 服务端融合排序# KnowFlow 优化的服务端融合策略rankerWeightedRanker(text_weight, vector_weight)resultsclient.hybrid_search(reqs[sparse_req, dense_req],rankerranker)KnowFlow 的融合权重调优• BM25 权重0.7强化关键词匹配• COSINE 权重0.3语义理解• 支持用户通过vector_similarity_weight参数动态调整为什么是 0.7:0.3这个比例在专业文档检索场景下能够平衡精确匹配和语义理解经过 KnowFlow 实际部署验证效果较优。4.2 与 ES 引擎的对比# search.py:574-588ifsettings.DOC_ENGINE_INFINITY or settings.DOC_ENGINE_MILVUS:# Milvus/Infinity: 直接信任服务端融合分数sim[sres.field[id].get(_score,0.0)foridinsres.ids]else:# ElasticSearch: 需要客户端词法精排sim, tsim, vsimself.rerank(...)Milvus 的优势•服务端融合BM25 和向量搜索在 Milvus 内部完成融合无需客户端二次计算•简化架构相比 ES 需要客户端精排Milvus 架构更简洁•性能提升减少数据传输和客户端计算开销五、KnowFlow 的性能优化实践5.1 三级维度缓存机制# KnowFlow 优化三级缓存策略def _get_kb_dimension(self, kb_id: str)-int|None:# 优先级 1: 内存缓存命中率 95%ifkb_idinself._kb_dimension_cache:returnself._kb_dimension_cache[kb_id]# 优先级 2: 从嵌入模型 API 获取emb_mdlLLMBundle(tenant_id,embedding_model, embd_id)vts, _emb_mdl.encode([test])dimlen(vts[0])# 优先级 3: 从 Collection 中检测回退方案dimself._detect_kb_dimension_from_collections(kb_id)KnowFlow 生产数据• 缓存命中率97.3%• 搜索延迟降低28ms从 120ms 降到 92ms5.2 批量操作优化# KnowFlow 优化批量查询 API 复用def _group_kbs_by_dimension(self, kb_ids: list[str])-dict:# 批量查询 KB 信息kbsKnowledgebaseService.get_by_ids(uncached_kb_ids)# 按 embd_id 分组相同模型只调用一次 APIfor(embd_id, tenant_id), kb_id_listinembd_to_kbs.items(): emb_mdlLLMBundle(tenant_id,embedding_model, embd_id)vts, _emb_mdl.encode([test])# 一次调用多个 KB 复用优化效果10 个 KB 的查询从 10 次 API 调用降低到 1-2 次六、给企业的最佳实践建议基于 KnowFlow 在 30 企业客户的部署经验我们总结了以下最佳实践。6.1 选择合适的向量维度不同嵌入模型的维度差异显著•OpenAI text-embedding-3-large3072 维高精度成本高•BGE-M31024 维KnowFlow 推荐性价比最优•多语言模型768-1024 维KnowFlow 的建议• 中文通用场景BGE-M31024 维• 多语言场景multilingual-e5-large• 成本敏感场景BGE-small512 维性能损失 5%6.2 合理设置检索参数# KnowFlow 推荐配置{limit:10-30,# 返回结果数milvus_candidate_limit:128,# Milvus 粗排候选数vector_similarity_weight:0.3,# 向量权重BM25 0.7}权重调优指南基于 KnowFlow 实践•法律/合同场景vector_similarity_weight 0.2强化精确匹配•客服/FAQ 场景vector_similarity_weight 0.5强化语义理解•通用文档场景vector_similarity_weight 0.3默认值6.3 数据备份与恢复Milvus 提供了官方的备份恢复工具KnowFlow 建议企业客户定期备份数据# 安装 Milvus Backup 工具wgethttps://github.com/zilliztech/milvus-backup/releases/download/v0.4.0/milvus-backupchmodx milvus-backup# 配置备份参数backup.yamlminio: address: localhost:9000 bucketName: milvus-backup# 创建备份./milvus-backup create-nmy_backup# 恢复备份./milvus-backup restore-nmy_backupKnowFlow 的备份策略•日常备份每日增量备份保留 7 天•周备份每周全量备份保留 4 周•月备份每月归档备份长期保存•灾难恢复异地备份RTO 4 小时参考文档Milvus Backup CLI[2]七、总结与展望KnowFlow 的核心价值通过深度优化 RAGFlow 的 Milvus 集成KnowFlow 为企业客户提供了生产级的 RAG 解决方案生产验证数据•部署规模30 企业客户20 行业•数据规模5000 万 chunks1000 万 文档页•查询量日均 10 万次峰值 QPS 50•稳定性99.9% 可用性持续稳定运行适用场景KnowFlow 特别适合以下企业场景•专业文档检索法律、金融、制造等领域的专业术语密集场景•多模态文档包含大量图表、公式的技术文档•大规模部署数千万到数亿级文档的企业知识库技术展望随着 Milvus 3.0 和 RAGFlow 的持续演进KnowFlow 团队将持续优化•更强的 BM25探索自定义 analyzer 插件•GPU 加速利用 Milvus GPU 版本提升性能•成本优化通过分层存储降低企业成本关于 KnowFlowKnowFlow是基于 RAGFlow 深度定制的企业级 RAG 平台由专业团队提供技术支持和定制化服务。我们的核心优势• ✅生产级优化解决了开源版本的中文分词、性能瓶颈等关键问题• ✅定制化服务根据行业特点定制检索策略• ✅私有化部署支持企业内网部署数据安全可控联系我们• 关注公众号KnowFlow 企业知识库• 官网https://www.knowflowchat.cn• GitHubKnowFlow 开源版https://github.com/knowflow-ai/KnowFlow参考资料• Milvus 官方文档 - Hybrid Search[1]• ColPali: Efficient Document Retrieval with Vision Language Models[3]• RAGFlow GitHub Repository[4]• Milvus BM25 Function Guide[5]引用链接[1]Milvus 官方文档:https://milvus.io[2]Milvus Backup CLI:https://milvus.io/docs/zh/milvus_backup_cli.md[3]ColPali: Efficient Document Retrieval with Vision Language Models:https://github.com/illuin-tech/colpali[4]RAGFlow GitHub Repository:https://github.com/infiniflow/ragflow[5]Milvus BM25 Function Guide:https://milvus.io/docs/full-text-search.md