2026年7月3日/ AI Engineering Notes
如何搭建企业知识库 RAG 系统
企业知识库 RAG 不是接一个聊天框,而是把文档入库、检索、重排、引用、权限、trace 和评测串成闭环。本文作为专题入口,先讲总体设计、架构分层、技术选型和实施顺序。
企业知识库 RAG 系统不是“把文档丢给大模型,再套一个聊天框”。
真正要搭的是一条工程链路:
文档能稳定入库
问题能召回正确资料
答案能绑定原文引用
权限不会泄露资料
答错后能看 trace
改完后能用评测集回归
这篇只讲总体设计和实施顺序。具体细节拆到后面的子文章里,不在主文里塞满。
先说结论
企业知识库 RAG 的核心不是模型,而是四个闭环:
| 闭环 | 要解决的问题 |
|---|---|
| 入库闭环 | 文档能不能被正确解析、切片、索引、更新和回滚 |
| 检索闭环 | 用户问题能不能找到真正相关的 chunk |
| 引用闭环 | 回答里的结论能不能回到原文证据 |
| 评测闭环 | 每次改切片、embedding、检索策略后,效果能不能量化比较 |
如果只做“上传文档 + 向量检索 + 生成回答”,第一版 Demo 可能能跑,但很难长期用。
企业场景里更容易出问题的是:
- 文档解析丢表格。
- chunk 切断语义。
- 只靠向量检索搜不到错误码、配置项、接口路径。
- 回答有引用编号,但引用片段其实支撑不了结论。
- 用户问了知识库没有的内容,系统仍然编一个答案。
- 文档更新失败后,旧索引被删了,新索引没写完。
所以设计时要先把链路拆清楚。
第一版边界
第一版不要做成大而全的企业知识平台。
建议先选一个知识域:
- 运维手册
- 产品 FAQ
- 内部制度
- 接口文档
- 客服知识库
- 项目排障记录
第一版必须有:
- 文档上传或同步
- 文档解析、清洗、切片
- 向量索引
- 全文检索或关键词检索
- 检索结果重排
- 基于资料生成回答
- 回答引用原文
- 问答 trace
第一版可以先不做:
- 多租户
- 复杂审批流
- 知识图谱
- 多智能体协作
- 用户任意上传公网 Demo
- 自动爬完整企业系统
先把一条主链路跑稳,再扩企业级能力。
总体架构
可以按五层理解。
应用层
问答入口 / 文档管理 / 引用查看 / 管理后台
编排层
查询改写 / 混合检索 / 权限过滤 / rerank / Prompt 组装 / 流式生成
知识处理层
文档解析 / 清洗 / 元数据抽取 / 切片 / embedding / 索引任务
存储层
原始文件 / document / chunk / embedding / 全文索引 / citation / trace
治理层
权限 / 审计 / 评测集 / 失败样本 / 监控告警
这不是代码包名,而是职责边界。用 Java、Python、Node 都可以按这个结构落地。
可以把第一版画成下面这张图:
┌──────────────────────┐
│ 问答页面 │
│ 提问 / 引用 / 反馈 │
└──────────┬───────────┘
│
┌──────────▼───────────┐
│ RAG API │
│ 权限 / trace / 流式输出 │
└──────┬────────┬──────┘
│ │
┌─────────────▼───┐ ┌─▼────────────────┐
│ 检索编排 │ │ 文档入库任务 │
│ rewrite/retrieval│ │ parse/chunk/embed │
│ rerank/context │ │ index/status │
└──────┬──────────┘ └────────┬─────────┘
│ │
┌───────────▼──────────┐ ┌───────▼──────────┐
│ 向量索引 / 全文索引 │ │ document / chunk │
│ vector + keyword │ │ file / metadata │
└───────────┬──────────┘ └───────┬──────────┘
│ │
└──────────┬───────────┘
│
┌──────────▼───────────┐
│ LLM / Embedding │
│ answer / vector / rank│
└──────────────────────┘
这个图里只有一条原则:问答链路和入库链路分开。入库慢、失败、重试,不应该拖住用户提问;提问时只读已经 INDEXED 的资料。
主链路
一套能上线的 RAG,至少有两条主链路。
文档入库链路
接收文件
-> 计算 content_hash
-> 解析文档结构
-> 清洗正文
-> 抽取元数据
-> 按结构切片
-> 生成 embedding
-> 写向量索引
-> 写全文索引
-> 切换 active version
入库链路要异步做。上传成功只代表文件收到了,不代表已经可检索。
细节放到第一篇子文章:
问答检索链路
接收问题
-> 结合会话做 query rewrite
-> 向量召回
-> 全文召回
-> 权限过滤
-> 候选合并
-> rerank
-> 组装上下文
-> 生成回答
-> 绑定引用
-> 保存 trace
这里最容易踩的坑是只做向量检索。
企业文档里有大量精确词:
- 错误码
- 配置项
- 接口路径
- 类名
- 工单编号
- 条款编号
- 产品型号
这些内容靠 embedding 不一定稳。更合理的方案是:
向量检索 + 全文检索 + 元数据过滤 + rerank
这部分后面单独写一篇,放在评测前面。
数据模型
最小数据模型不要只做一张“知识表”。
建议先拆成这些核心对象:
| 对象 | 作用 |
|---|---|
| document | 文档来源、版本、hash、索引状态 |
| chunk | 文档切片、章节路径、页码、正文 |
| embedding | chunk 对应向量、模型名、版本 |
| citation | 回答引用了哪些 chunk |
| retrieval_trace | 每次问答召回了什么、重排后用了什么 |
| eval_case | 固定评测问题和期望 chunk |
| eval_result | 每次评测运行的指标和失败原因 |
其中 document、chunk、embedding 是入库主链路。
citation、retrieval_trace 是线上排查主链路。
eval_case、eval_result 放到后期,但不要完全不设计。否则系统上线后只能靠“感觉效果还行”判断。
第一版接口也不用多,先有这几个就够:
| 接口 | 作用 |
|---|---|
POST /api/documents |
上传文档,返回 document id 和入库任务状态 |
GET /api/documents/{id} |
查看文档解析、切片、索引状态 |
POST /api/chat |
提问,返回答案、引用和 trace id |
GET /api/traces/{id} |
查看一次问答的召回、rerank、上下文和引用 |
POST /api/eval/runs |
后期跑固定评测集 |
POST /api/chat 的返回值至少要带引用,不要只返回一段自然语言:
{
"answer": "ERR_AUTH_401 通常和 token 过期或签名不一致有关,需要先重新获取 token,再检查服务端签名密钥。[1]",
"citations": [
{
"ref": 1,
"document_id": "doc_redis_ops",
"chunk_id": "chunk_0042",
"title": "Redis 运维手册",
"section": "鉴权失败处理",
"page": 7
}
],
"trace_id": "trace_20260708_001"
}
这样读者能看懂:这不是一个“聊天接口”,而是一个带证据和排查入口的问答接口。
技术选型
后端
团队如果本来是 Java 后端,可以用:
- Spring Boot 做业务 API、权限、任务调度
- Spring AI 封装模型、embedding、向量库调用
- PostgreSQL / Redis 做基础存储
团队如果主要做 AI 原型,可以用:
- FastAPI 做接口
- LlamaIndex 或 LangChain 做 RAG 编排
- Qdrant、Milvus、Weaviate 或 pgvector 做向量索引
选型不要只看框架热度。长期能维护,比名字新更重要。
向量库
第一版数据量不大时,可以先用 PostgreSQL + pgvector。
好处是:
- 部署简单
- document / chunk / embedding 可以放一起
- 备份、权限、事务都成熟
- 适合验证主链路
数据量、并发、过滤条件变复杂后,再考虑 Qdrant、Milvus、Weaviate、Pinecone 等专用向量库。
检索
不要只选一个“向量库”就结束。
生产方案至少考虑:
向量召回 topK = 50
全文召回 topK = 50
权限和状态过滤
融合候选
rerank 到 5 到 10 个 chunk
这些数字只是起点,不是标准答案。最终要根据评测集调。
模型
至少三类模型:
| 模型 | 作用 |
|---|---|
| Chat Model | 生成回答、做查询改写 |
| Embedding Model | 把 query 和 chunk 转成向量 |
| Rerank Model | 对候选 chunk 重新排序 |
Embedding 模型不要频繁换。换了就相当于换了向量空间,通常要重建索引并重新评测。
Prompt 只管边界
Prompt 不要写成一篇长说明书。
关键约束就几条:
只能基于给定资料回答。
资料不足时明确说没有足够依据。
不要编造制度、链接、页码、文档名。
关键结论必须标注引用编号。
上下文格式要固定:
[chunk:1]
document: Redis 运维手册
section: 连接超时排查
page: 3
content: ...
[chunk:2]
document: 应用部署规范
section: 发布前检查
page: 8
content: ...
模型输出引用编号,后端再把编号映射回 chunk_id。引用不要只保存文档名,要绑定到 chunk 和原文片段。
权限必须在检索前
企业知识库最不能犯的错是:
先检索所有文档
-> 生成答案
-> 再判断用户能不能看
正确顺序是:
先根据用户权限过滤可见文档范围
-> 只在可见范围内检索
-> 再生成回答
第一版权限模型可以简单:
visibility: public / department / private
department_id
allowed_user_ids
allowed_role_ids
后面再接企业组织架构、用户组、角色和文档权限。
专题顺序
这组文章按系统实现顺序写,不按“哪个概念更热门”写。
建议阅读顺序:
| 顺序 | 主题 | 状态 |
|---|---|---|
| 1 | 总体架构和实施路线 | 本文 |
| 2 | 文档入库:解析、清洗、切片、向量化、索引状态 | 已写 |
| 3 | 数据模型:document、chunk、embedding、citation、trace | 待写 |
| 4 | 检索链路:Hybrid Search、全文检索、rerank、权限过滤 | 待写 |
| 5 | 引用追溯:引用绑定、原文定位、claim 校验 | 待写 |
| 6 | 质量评测:Recall@K、MRR、引用命中、失败样本 | 已写,后面再发布 |
评测放在后面,不是因为它不重要,而是因为评测对象要先稳定下来。没有入库策略、检索链路和引用结构,评测文章会变成单纯讲指标。
实施顺序
真正开发时可以按这个顺序:
- 建
document、chunk、embedding基础表。 - 跑通文档上传、解析、切片、embedding。
- 做向量检索,完成第一版问答。
- 增加全文检索,做 hybrid search。
- 增加 rerank,提高上下文精度。
- 增加 citation,把回答绑定到原文 chunk。
- 增加权限过滤,保证检索前隔离。
- 增加 retrieval trace,能复盘每次问答。
- 再建评测集,记录 Recall@K、MRR、引用命中。
- 根据失败样本迭代切片、检索、rerank 和 prompt。
不要一开始就追求完整平台。第一阶段只要做到:
文档能入库
问题能召回
回答有引用
答错能追踪
改动能评测
这五件事成立,企业知识库 RAG 才有继续迭代的基础。
参考资料
Brief
Enterprise RAG is an engineering loop, not a chat box.
The first version should focus on ingestion, retrieval, citation and traceability.
Evaluation should come after the main retrieval and citation pipeline is in place.