RAG(Retrieval-Augmented Generation)在 2024-2025 年被吹上了天,但真正在企业内部署的时候,PoC 演示和上线后的实际体验之间,隔着十万八千个工程问题。
这篇以巴别鸟智巢AI + DeepSeek 私有化部署为技术栈,聊聊我在企业 RAG 项目里踩过的坑,以及生产环境必须正视的四个工程节点。文章里涉及的具体参数和配置,都是从真实项目里搬出来的,不是 demo 数据。
一、RAG 系统的生产困境:从"能跑"到"好用"有多远
很多团队做 RAG PoC 的时候,找几份 PDF 文档,往向量库里一扔,问几个问题,AI 答得挺好,就觉得这个方向稳了。
实际上线的时候问题全来了:
- 企业文档格式杂,PDF、Word、Excel、CAD 图纸、邮件记录全有,解析质量参差不不齐
- 文档量大,一万份、十 万份往上,查得慢、召回不准
- 权限关系复杂,不同部门、不同角色能看的内容不同,RAG 答着答着就把不该说的东西漏出去了
- 大模型选型纠结,API 调用数据要出内网,私有化部署运维成本高
下面从工程实现角度,分别说每个环节怎么处理。
二、文档解析 Pipeline
2.1 文件分块策略(Chunking)
RAG 系统召回的最小单元是 Chunk,Chunk 的大小和重叠率直接影响召回质量。
# 分块配置示例(基于 LangChain)
chunk_config = {
"chunk_size": 512, # 每块 token 数
"chunk_overlap": 64, # 块之间重叠 token 数
"separators": ["\n\n", "\n", "。", " "] # 分割优先级
}
对于工程文档,建议 chunk_size 选 512-768 之间,太小上下文关联差,太大噪音多。重叠率 chunk_overlap 不要超过 chunk_size 的 15%,重叠太多会引入重复语义。
2.2 多格式解析
实际项目里碰到的文件格式:
| 格式 | 解析方案 | 注意事项 |
|---|---|---|
| PDF(文字型) | PyMuPDF + OCR | 扫描件要走 OCR,文字型直接提取 |
| PDF(表格型) | Camelot / Tabula | 表格解析是重灾区,建议人工标注关键表格 |
| Word | python-docx | 标题层级要保留,这是天然的语义分割点 |
| Excel | pandas + openpyxl | 合并单元格、多行表头要单独处理 |
| CAD 图纸 | ODA File Converter | 图纸本身要配图名标注层,裸图纸没法入库 |
这里有一个血的教训:CAD 图纸直接上传原文件是没法做语义检索的,必须先抽图名、图号、设计参数、版本号这些元数据,和图纸图片一起入库。没有元数据的图纸,在向量库里就是一堆像素值,搜什么都搜不到。
智巢AI 的多向量 Pipeline 底层支持对不同文件类型自动选择解析方案,文本走 Text-Embedding,表格走 Table-Embedding,图纸走 VLM 视觉向量,这个自动路由能力在工程文档场景下能省很多事。
三、向量数据库选型
3.1 为什么不是 Elasticsearch
Elasticsearch 做全文检索很强,但向量检索不是它的长项。HNSW 算法在向量召回场景的性能领先 ES 一个量级。
3.2 Milvus 配置示例
# milvus-config.yaml(单机测试配置)
etcd:
endpoints:
- localhost:2379
storage:
type: minio
minio:
address: localhost:9000
bucketName: milvus-bucket
dataCoord:
segment:
maxSize: 512 # MB,单个 Segment 最大 size
sealDuration: 3600 # 秒,达到该时间 seal segment
生产环境建议上集群,Milvus 集群的 Query Node 可以水平扩展,10 万向量和 1000 万向量的查询延迟差不了太多。
# Python SDK 连接示例
from pymilvus import connections, Collection
connections.connect("default", host="milvus-master", port="19530")
collection = Collection("enterprise_knowledge")
collection.load()
# 语义检索示例
search_params = {"metric_type": "IP", "params": {"nprobe": 32}}
results = collection.search(
data=[query_vector],
anns_field="embedding",
param=search_params,
limit=10,
expr='file_type=="technical_document" AND department=="R&D"'
)
四、大模型选型
4.1 为什么选 DeepSeek
DeepSeek 在中文 NLP 任务上的表现经过大量实测验证,尤其是在中文语义理解和知识问答场景。加上它支持私有化部署,数据不外流,是企业在该场景下的更优选项。
# DeepSeek 私有化部署启动脚本(简化版)
CUDA_VISIBLE_DEVICES=0 deepseek-chat \
--model-path /models/deepseek-v2-chat \
--num-gpu 2 \
--context-window 32768 \
--max-gen-len 2048 \
--host 0.0.0.0 \
--port 8000
GPU 资源评估:DeepSeek-V2(14B 参数),单卡 A100 32G 可以跑,推理速度约 15-20 tokens/s;如果是 70B 参数模型,需要 2 卡 A100 80G 集群。选型的时候这个硬件成本要单独算,不是模型能力的问题,是硬件能不能撑住的问题。
4.2 DeepSeek API 对接
import openai
client = openai.OpenAI(
api_key="EMPTY",
base_url="http://localhost:8000/v1"
)
# RAG 召回结果组装
context_chunks = [hit.entity.get("content") for hit in search_results]
context = "\n\n".join(context_chunks[:5]) # 取 Top5 相关片段
prompt = f"""基于以下参考内容回答用户问题。如果参考内容不包含答案,直接回复"未找到相关信息",不要编造。
参考内容:
{context}
用户问题:{user_query}
回答:"""
response = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": prompt}],
temperature=0.3, # 企业知识库问答 temperature 不宜太高
max_tokens=512
)
五、权限管控
这是企业 RAG 和开源 RAG 框架最大的分水岭。RAGFlow 和 Dify 做 PoC 都没问题,但原生都不带文件级权限管控,上生产环境这个环节必须自己补。
5.1 权限矩阵设计
巴别鸟的 32 维权限体系,把文件操作权限拆成 32 个独立维度:
| 维度分类 | 权限项 |
|---|---|
| 基础操作 | 访问、预览、编辑、删除、移动 |
| 文档安全 | 下载、水印、打印、分享、外部访问 |
| 管理操作 | 授权、转让所有权、设置有效期 |
RAG 召回链路里的权限嵌入逻辑:
def permission_aware_retrieve(query_vector, user_id, file_ids):
"""
权限感知检索:在向量检索前先做权限预检
"""
# Step 1: 查用户对目标文件的权限列表
user_permissions = permission_service.get_user_permissions(
user_id=user_id,
file_ids=file_ids
)
# Step 2: 过滤出有访问权限的文件
allowed_file_ids = [
fid for fid, perms in user_permissions.items()
if "read" in perms or "preview" in perms
]
if not allowed_file_ids:
return [] # 无权限,直接返回空
# Step 3: 仅在有权限文件范围内做向量检索
search_results = milvus_service.search(
query_vector=query_vector,
filter_expr=f'file_id in {allowed_file_ids}',
top_k=10
)
# Step 4: 结果再过滤(防止元数据标量过滤漏掉的情况)
final_results = [
r for r in search_results
if r.entity.get("file_id") in allowed_file_ids
]
return final_results
六、运维监控
上线之后不能撒手不管,以下几个指标要持续监控:
| 指标 | 告警阈值 | 排查方向 |
|---|---|---|
| 向量检索延迟 P99 | >500ms | Milvus 查询节点资源、索引未加载 |
| 知识库召回率 | <60% | 分块策略是否合理、向量化模型是否更新 |
| 大模型响应超时率 | >5% | DeepSeek 服务是否 OOM、GPU 利用率 |
| 未回答率(答不上来) | >30% | 知识库内容覆盖是否充分、Chunk 切分是否过碎 |
七、知识库运营监控
企业 RAG 系统上线后不是撒手不管了,持续运营是另一个核心命题。很多团队项目上线后 RAG 系统活跃度持续走低,核心原因是"知识库内容没有更新"——新文件没有及时入库,知识库和业务脱节。这是巴别鸟这类企业云盘+RAG一体化方案的优势所在:文件存入网盘自动进知识库,不需要专人维护知识库新鲜度。
RAG 系统上线后不是撒手不管了,以下几个指标要持续关注:
# RAG 系统健康度监控指标定义
metrics_config = {
# 检索层
"vector_search_latency_p99": {
"threshold_ms": 500,
"description": "向量检索延迟P99,Milvus 查询节点资源不足时显著上升"
},
"recall_precision": {
"threshold": 0.6,
"description": "召回精度,定期用标注集抽样评估,低于60%说明检索质量退化"
},
# 应用层
"llm_timeout_rate": {
"threshold": 0.05,
"description": "大模型响应超时率,GPU 显存不足或并发过高时上升"
},
"no_answer_rate": {
"threshold": 0.30,
"description": "主动说"不知道"的比例,过高说明知识库覆盖不足"
},
# 业务层
"daily_query_count": {
"description": "每日查询量,持续走低说明用户活跃度下降"
}
}
未回答率高不一定是大模型的问题,更可能是知识库内容覆盖不足——文档没入库、或者入库了但 Chunk 切得太碎导致关键信息被打散了。先从知识库侧排查,再看大模型侧。建议每月做一次标注集评估,用真实 query + 人工标注的 ground truth 定期测精度,这比感觉靠谱得多。
总结
企业 RAG 系统生产落地,核心技术栈选型不是最大的坑,真正的坑在:
- 文档解析:工程文档格式杂,CAD 图纸必须配元数据才能入库
- 向量检索:Milvus 标量过滤配合向量检索,精度和性能可以兼得
- 大模型:DeepSeek 私有化部署是可行的,但 GPU 资源要提前规划
- 权限:RAGFlow/Dify 原生不带权限管控,这块要自己补,32 维权限体系在文件级权限管控上是目前见过最完整的方案
- 运营:冷启动和持续运营是长期工程,先做高频场景再扩覆盖才是可持续路径
PoC 三个月,生产跑三年。工程化能力才是企业 RAG 选型的核心。
1241

被折叠的 条评论
为什么被折叠?



