本文由 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 pymilvus import AnnSearchRequest, WeightedRanker
# BM25 稀疏向量搜索
sparse_req = AnnSearchRequest(
data=[bm25_query_text],
anns_field="sparse_vector",
param={"metric_type": "BM25"},
limit=current_limit,
)
# 稠密向量语义搜索
dense_req = AnnSearchRequest(
data=[dense_embedding],
anns_field=vector_field,
param={"metric_type": "COSINE", "params": {"ef": ef}},
limit=current_limit,
)
# KnowFlow 优化:服务端加权融合 BM25 × 0.7 + COSINE × 0.3
ranker = WeightedRanker(text_weight, vector_weight)
results = client.hybrid_search(
collection_name=collection_name,
reqs=[sparse_req, dense_req],
ranker=ranker,
limit=limit
)
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: int = None) -> str:
"""
命名格式: {index_name}_{vector_size}
例如: knowflow_tenant123_1024
KnowFlow 优化点:
- 搜索时根据 KB 维度定向查询单个 Collection,无需遍历
- 同维度 KB 共享 Collection,资源利用率提升 80%
- 性能与单 Collection 一致,但支持多种嵌入模型
"""
safe_index = re.sub(r"[^a-zA-Z0-9_]", "_", index_name)
if vector_size:
return f"{safe_index}_{vector_size}"
return safe_index
KnowFlow 的设计理由:
生产数据:在 KnowFlow 的实际部署中,单个租户平均使用 2-3 种嵌入模型,这种架构使 Collection 数量控制在可管理范围内(<100 个),同时保持了灵活性。
2.2 Schema 设计:BM25 Function 的巧妙应用
Milvus 2.4+ 引入了 Function 机制,可以自动将文本字段转换为 BM25 稀疏向量。RAGFlow 充分利用了这一特性:
# rag/utils/milvus_conn.py:408-525
def _build_schema(self, vector_size: int):
# content 字段 - BM25 函数输入
fields.append(FieldSchema(
name="content",
dtype=DataType.VARCHAR,
max_length=65535,
enable_analyzer=True,
analyzer_params={"type": "chinese"}, # 中文分词
enable_match=True,
))
# BM25 稀疏向量字段(由 Function 自动生成)
fields.append(FieldSchema(
name="sparse_vector",
dtype=DataType.SPARSE_FLOAT_VECTOR
))
# 添加 BM25 函数
from pymilvus import Function, FunctionType
bm25_function = Function(
name="text_bm25_emb",
input_field_names=["content"],
output_field_names=["sparse_vector"],
function_type=FunctionType.BM25,
)
schema.add_function(bm25_function)
关键设计点:
-
•
content字段存储原始文本,启用中文 analyzer -
•
sparse_vector字段由 BM25 Function 自动生成,无需手动计算 -
• 插入数据时只需提供
content,Milvus 自动完成 BM25 向量化
2.3 知识库隔离策略
当前方案:逻辑隔离
每个知识库通过 kb_id 字段实现逻辑隔离,搜索时通过过滤表达式限定范围:
# KnowFlow 当前实现:逻辑隔离
kb_by_dim = self._group_kbs_by_dimension(knowledgebaseIds)
for vector_size, kb_ids in kb_by_dim.items():
collection_name = self._get_collection_name(indexName, vector_size)
# 构建过滤条件(使用当前维度组的 kb_id 列表)
search_condition = condition.copy()
search_condition["kb_id"] = kb_ids
filter_expr = self._build_filter_expr(search_condition)
# 例如: kb_id in ["kb1", "kb2", "kb3"]
当前方案的优势:
-
• 实现简单:通过标量字段过滤,无需额外配置
-
• 灵活性高:可以跨 KB 联合查询
-
• 资源高效:避免为每个 KB 创建独立 Collection
未来优化方向:物理分区隔离
Milvus 2.4+ 支持 partition_key 功能,可以实现真正的物理分区隔离。KnowFlow 正在评估这一方案:
# 规划方案:物理分区隔离
fields.append(FieldSchema(
name="kb_id",
dtype=DataType.VARCHAR,
max_length=128,
is_partition_key=True # 启用分区键
))
物理分区的优势:
-
• 性能提升:查询时只扫描特定分区,减少数据扫描量
-
• 数据隔离:不同 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_THRESHOLD = 50000 # 超过 50KB 触发压缩
_COMPRESSIBLE_FIELDS = frozenset({"content_with_weight"})
# 插入时自动压缩
for k in _COMPRESSIBLE_FIELDS:
v = result.get(k)
if isinstance(v, str):
raw_bytes = v.encode("utf-8")
if len(raw_bytes) > _COMPRESS_THRESHOLD:
compressed_b64 = base64.b64encode(
zlib.compress(raw_bytes, level=6)
).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-253
if not settings.DOC_ENGINE_INFINITY and not settings.DOC_ENGINE_MILVUS:
src.append(f"q_{len(q_vec)}_vec") # ES 需要返回向量做客户端精排
# Milvus/Infinity 不返回向量字段
原理:
-
• ES 引擎:需要返回向量字段,客户端计算 cosine 相似度做精排
-
• Milvus 引擎:服务端已完成融合排序,客户端只需
_score,无需向量 -
• 单个向量字段:1024维 × 4字节 = 4KB,Top-100 就是 400KB
方案二:延迟加载大字段(Hydrate-After-Search)
# KnowFlow 优化:将大字段从搜索阶段剥离
_HYDRATE_ONLY_OUTPUT_FIELDS = frozenset({
"content_with_weight", # 展示用长文本
"position_int", # 坐标数据(可达 10KB)
"keyframes_json", # 视频关键帧(可达 50KB)
})
# 搜索时先排除大字段
search_output_fields = [f for f in output_fields if f not in _HYDRATE_ONLY_OUTPUT_FIELDS]
# 搜索完成后,按命中 ID 批量补全大字段
if hydrate_fields and docs:
hydrated_docs = self._get_fields_by_ids(
collection_name=collection_name,
ids=[doc["id"] for doc in docs],
output_fields=hydrate_fields,
)
方案三:自动降级 Limit
# KnowFlow 优化:遇到超限错误时自动减半 limit
current_limit = min(max(limit, 1), 128) # 上限 128
while True:
try:
results = self._client.hybrid_search(...)
break
except Exception as search_err:
if not _is_max_output_size_error(search_err):
raise
next_limit = current_limit // 2
logger.warning(f"[KnowFlow] Retry with limit={next_limit}")
current_limit = next_limit
优化效果:
-
• 不返回向量:单次查询数据量减少 400KB(Top-100 场景)
-
• 延迟加载:搜索阶段数据传输量再减少 60%
-
• 自动降级:查询失败率从 12% 降到 0.01%
-
• 综合优化:P99 延迟从 800ms 降到 350ms
四、KnowFlow 的混合检索架构
基于 RAGFlow 的混合检索基础,KnowFlow 采用了 Milvus 服务端融合排序的架构。
4.1 服务端融合排序
# KnowFlow 优化的服务端融合策略
ranker = WeightedRanker(text_weight, vector_weight)
results = client.hybrid_search(reqs=[sparse_req, dense_req], ranker=ranker)
KnowFlow 的融合权重调优:
-
• BM25 权重:0.7(强化关键词匹配)
-
• COSINE 权重:0.3(语义理解)
-
• 支持用户通过
vector_similarity_weight参数动态调整
为什么是 0.7:0.3? 这个比例在专业文档检索场景下,能够平衡精确匹配和语义理解,经过 KnowFlow 实际部署验证效果较优。
4.2 与 ES 引擎的对比
# search.py:574-588
if settings.DOC_ENGINE_INFINITY or settings.DOC_ENGINE_MILVUS:
# Milvus/Infinity: 直接信任服务端融合分数
sim = [sres.field[id].get("_score", 0.0) for id in sres.ids]
else:
# ElasticSearch: 需要客户端词法精排
sim, tsim, vsim = self.rerank(...)
Milvus 的优势:
-
• 服务端融合:BM25 和向量搜索在 Milvus 内部完成融合,无需客户端二次计算
-
• 简化架构:相比 ES 需要客户端精排,Milvus 架构更简洁
-
• 性能提升:减少数据传输和客户端计算开销
五、KnowFlow 的性能优化实践
5.1 三级维度缓存机制
# KnowFlow 优化:三级缓存策略
def _get_kb_dimension(self, kb_id: str) -> int | None:
# 优先级 1: 内存缓存(命中率 >95%)
if kb_id in self._kb_dimension_cache:
return self._kb_dimension_cache[kb_id]
# 优先级 2: 从嵌入模型 API 获取
emb_mdl = LLMBundle(tenant_id, "embedding_model", embd_id)
vts, _ = emb_mdl.encode(["test"])
dim = len(vts[0])
# 优先级 3: 从 Collection 中检测(回退方案)
dim = self._detect_kb_dimension_from_collections(kb_id)
KnowFlow 生产数据:
-
• 缓存命中率:97.3%
-
• 搜索延迟降低:28ms(从 120ms 降到 92ms)
5.2 批量操作优化
# KnowFlow 优化:批量查询 + API 复用
def _group_kbs_by_dimension(self, kb_ids: list[str]) -> dict:
# 批量查询 KB 信息
kbs = KnowledgebaseService.get_by_ids(uncached_kb_ids)
# 按 embd_id 分组,相同模型只调用一次 API
for (embd_id, tenant_id), kb_id_list in embd_to_kbs.items():
emb_mdl = LLMBundle(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-large:3072 维(高精度,成本高)
-
• BGE-M3:1024 维(KnowFlow 推荐,性价比最优)
-
• 多语言模型:768-1024 维
KnowFlow 的建议:
-
• 中文通用场景:BGE-M3(1024 维)
-
• 多语言场景:multilingual-e5-large
-
• 成本敏感场景:BGE-small(512 维,性能损失 <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 工具
wget https://github.com/zilliztech/milvus-backup/releases/download/v0.4.0/milvus-backup
chmod +x milvus-backup
# 配置备份参数(backup.yaml)
minio:
address: localhost:9000
bucketName: milvus-backup
# 创建备份
./milvus-backup create -n my_backup
# 恢复备份
./milvus-backup restore -n my_backup
KnowFlow 的备份策略:
-
• 日常备份:每日增量备份,保留 7 天
-
• 周备份:每周全量备份,保留 4 周
-
• 月备份:每月归档备份,长期保存
-
• 灾难恢复:异地备份,RTO < 4 小时
参考文档:Milvus Backup CLI[2]
七、总结与展望
KnowFlow 的核心价值
通过深度优化 RAGFlow 的 Milvus 集成,KnowFlow 为企业客户提供了生产级的 RAG 解决方案:
生产验证数据
-
• 部署规模:30+ 企业客户,20+ 行业
-
• 数据规模:5000 万+ chunks,1000 万+ 文档页
-
• 查询量:日均 10 万次,峰值 QPS 50+
-
• 稳定性:99.9% 可用性,持续稳定运行
适用场景
KnowFlow 特别适合以下企业场景:
-
• 专业文档检索:法律、金融、制造等领域的专业术语密集场景
-
• 多模态文档:包含大量图表、公式的技术文档
-
• 大规模部署:数千万到数亿级文档的企业知识库
技术展望
随着 Milvus 3.0 和 RAGFlow 的持续演进,KnowFlow 团队将持续优化:
-
• 更强的 BM25:探索自定义 analyzer 插件
-
• GPU 加速:利用 Milvus GPU 版本提升性能
-
• 成本优化:通过分层存储降低企业成本
关于 KnowFlow
KnowFlow 是基于 RAGFlow 深度定制的企业级 RAG 平台,由专业团队提供技术支持和定制化服务。我们的核心优势:
-
• ✅ 生产级优化:解决了开源版本的中文分词、性能瓶颈等关键问题
-
• ✅ 定制化服务:根据行业特点定制检索策略
-
• ✅ 私有化部署:支持企业内网部署,数据安全可控
联系我们:
-
• 关注公众号 KnowFlow 企业知识库
-
• 官网:www.knowflowchat.cn
-
• GitHub(KnowFlow 开源版):github.com/knowflow-ai…
参考资料
-
• Milvus 官方文档 - Hybrid Search[1]
-
• ColPali: Efficient Document Retrieval with Vision Language Models[3]
-
• RAGFlow GitHub Repository[4]
-
• Milvus BM25 Function Guide[5]
引用链接
[1] Milvus 官方文档: *milvus.io*`[2]` Milvus Backup CLI: *milvus.io/docs/zh/mil…: Efficient Document Retrieval with Vision Language Models: *github.com/illuin-tech… GitHub Repository: *github.com/infiniflow/… BM25 Function Guide: milvus.io/docs/full-t…