把知识库 RAG 做到生产级:我们的选型、架构与取舍
引子:一个 58% 的数字
斯坦福的研究者在 2024 年做过一个实验:让没有外接任何资料的大模型,直接回答美国联邦法院真实案件里那些可以核实的具体问题——某个判决的 holding 是什么、两个判例之间是不是引用关系。结果模型答得信誓旦旦,幻觉率却高达 58%–88%(1)。也就是说,你问十个具体的法律问题,它能一本正经地编错五到九个。医疗领域类似的测试里,模型在需要推理的任务上准确率普遍不到 42%(2)。
一个再聪明的模型,如果没有实时的正确的信息,它很可能会胡说八道。这是由大语言模型的本质决定的。而企业要的恰恰是"基于我自己的合同、手册、工单、论文来回答",不是基于模型脑子里那团模糊的、过时的、还会串味的记忆。
自然而然的,我们会想到要给模型提供一个获取信息的途径:把企业自己的资料沉淀成一个可检索的知识库,回答问题时先从里面找出相关内容,再交给模型来组织答案(这种"先检索、再生成"的做法,业界通常简称 RAG)。听起来简单,几乎成了"标准答案"。但真正动手做过的人都知道,从"周末写个 demo"到"扛得住生产",中间差了十万八千里。
这篇文章想聊的,就是这里到底有哪些坑,以及我们是怎么趟过去的。
幻觉只是冰山一角。真正把企业逼向知识库的,是三个大模型靠自己解决不了的硬约束:
- 时效性:模型的知识停在训练截止日期。上周改的报销政策、昨天提交的工单、今早签的合同,它一概不知道。靠不断重新训练去追新信息,既不现实也不经济。
- 私域性:企业最值钱的知识——内部流程、客户档案、研发资料——根本不在模型的训练语料里,而且也不该进去。
- 准确性与可追溯:高风险场景(法律、医疗、金融)不只要答案对,还要能指出"这句话出自哪份文件的哪一段"。一个无法溯源的答案,在这些场景里等于没有答案。
这三条,恰好是检索能补上、而再大的模型也补不上的。下面分别从"业务"和"技术"两个角度,把这件事说透。
几乎每家有点年头的公司,都坐在一座知识金矿上:产品手册、技术文档、历史工单、合同条款、研究报告、会议纪要……问题从来不是"没有知识",而是知识用不起来。
它散落在十几个系统里,沉在某个人的电脑硬盘上,藏在一篇 80 页 PDF 的第 63 页。新人上手要问遍一圈老员工,老员工一离职就带走一脑子"只可意会"的经验,客服面对一个老问题还要重新翻一遍文档。传统的做法是搭一个 wiki 或文档中心,但你我都见过它们最后的样子:写的人没动力维护,看的人搜不到想要的,最后沦为"信息坟场"。
学术界对"知识管理为什么失败"有过系统综述,六大主因里有五个是组织和治理层面的——缺乏明确目的、难融入工作流、缺少激励、文化不支持(3)。换句话说,传统知识库的死因,往往不是技术不行,而是"维护成本高、检索体验差,导致没人用,于是更没人维护"的恶性循环。
大模型给了这个老问题一个新解法:不再让人去"搜索 + 阅读 + 提炼",而是直接问、直接得到答案。但前提是——模型得真的基于你的知识来回答。
回到开头那些数字,它们证明了同一件事:让大模型"凭记忆"回答专业问题,是不可靠的。
需要强调几个前提,免得误导:那些 58%–88%、低于 42% 的幻觉率,多数来自 2023 年前后的旧模型,且是专门挑"最难记、最容易混"的对抗性问题测出来的,不能拿来代表今天前沿模型的日常表现(1)(2)。但即便是 2025 年较新的模型,在植入了虚假医学细节的对抗性临床测试里,依然有约一半的输出会把一本正经地胡说八道,而且单靠改提示词无法解决这个问题(4)。趋势很清楚:模型在变强,但"参数里的记忆"这条路,对高风险、要精确、要可追溯的场景,结构性地不够用。
这时候一定会有人问:"这几年模型一直在进化,上下文越来越大,有没有可能将来就不用检索了,直接把信息都塞进上下文不就可以了?"
这里我们首先要提一个叫 "context rot"(上下文腐烂)的概念/现象:随着塞进窗口的内容变多,模型从里面准确捞出某条信息的能力反而在下降——有测试显示从 1 万 token 涨到 10 万+ token 时,准确率会掉 20%–50%,而且所有被测的前沿模型都中招,只是程度不同(5)。再加可以预见的,每个人、组织的知识一定会不断沉淀、增长,模型能力增长的再快也无法满足知识的增长速率。更别提大上下文带来的计算成本幂级增长,性价比实在太低。所以这条路在实际的场景中只能解决一小部分问题,更多的场景是无法通过把信息塞入上下文来解决的。
所以结论是:大上下文和精准检索不是替代关系。窗口再大,也总有不够用的时候;更关键的是,上下文窗口是一种稀缺资源。我们需要把这块宝贵的空间留给更重要信息:任务指令、Skill信息、工具信息、更重要的任务上下文等。
这其实正是一条被业界重新认识的主线。从早期的"提示工程"(怎么把一条指令写好),到"上下文工程"(怎么策展整个窗口里的全部信息——系统提示、对话历史、检索结果、工具、记忆),再到更上层的"编排工程"(harness engineering,怎么跨多步、多轮、多会话地组织这一切),本质上都在回答同一个问题:在有限的上下文里,怎么放进恰到好处的信息。
而知识库的价值,就在于能更准确地获取到所需的信息,减少上下文的浪费。这个"更准确的获取到所需的信息",就是知识库的核心,也是它全部的难点所在。
|
顺带一提:知识库的角色已经从"问答前一次性检索好的语料"转变成"智能体执行任务时随时按需查阅的环境"。 |
知识库的基本链路其实非常清晰:

网上随手一搜就有"xx行代码做个知识库问答"的教程,跟着抄确实能快速跑起来一个能问答的 demo。但它们跳过了所有真正难的部分——而难的,恰恰是这条链路上每一个环节都是一道开放的选择题:
- 解析:一份 PDF 怎么变成干净的文本?扫描件要不要 OCR?表格的合并单元格怎么办?公式、图片、页眉页脚怎么处理?选 MinerU、Marker 还是 VLM 类的 OCR,精度、速度、成本完全不同。这里可以参考我们之前的另一篇关于解析的文章:数据知识化:迈出“构建以AI为中心”工作流的第一步
- 切块:切多大?按固定长度切,会把一句话拦腰斩断;按段落切,又可能一段长到塞不进模型。代码、表格、问答对、长文档,根本不能用同一种切法。切块的质量,几乎直接决定了召回的上限——这一点业界已有共识:换个切块策略带来的提升,往往比换个更强的 embedding 模型还大。
- 向量化:选哪个 embedding 模型?维度多少?中文场景表现如何?换模型就意味着全量重新索引,这在生产上是个不小的工程。
- 检索:只用向量检索(语义相似)够吗?不够——它对错误码、SKU、人名这类"精确 token"特别不擅长,会把 ERR_BLOCKED_BY_CLIENT 匹配到一堆"长得像的"无关文档上。这时候需要把传统的关键词检索(BM25)也拉进来做混合检索。
- 重排:召回回来的几十段,怎么排序?要不要上一个专门的 reranker 模型做二次精排?省掉它,可能有 40% 的答案会被"沾边但不相关"的内容带偏。
每一道题选错,最终效果都会打个折扣,而且这些折扣会乘起来。这就是为什么"demo 惊艳、上线翻车"成了知识库项目的经典剧情:demo 只需要每个环节"能跑",生产却需要每个环节"做对"。
更有意思的是,这个领域本身还在不断演化,有一些可能更适合模型的检索思路在不断涌现。如果说早期的做法是"离线把索引建好、查询时一把捞出来",那么现在有两条主线正在改写它:
- 纵向:检索的"智能"正在从离线索引转移到在线推理——智能体在回答过程中自己决定搜什么、要不要再搜一次、怎么改写问题(Agentic RAG)。
- 横向:单一向量的垄断正在被打破——知识图谱(GraphRAG)、把整页文档当图像理解的视觉检索(ColPali 这类)、迟交互(late interaction)等新思路层出不穷。
我想说的是:它既复杂——每个环节都有一堆要做对的细节,又年轻——整个领域还在以季度为单位快速演进,今天的"最佳实践"明年很可能被刷新。
面对这样一个领域,我们的策略是两条腿走路:先把当前阶段被反复验证有效的工程基本功扎扎实实落地——这正是本文后半部分要讲的解析、切块、混合检索、多模态;同时持续跟踪那些正在涌现的新方向——Agentic RAG、视觉检索、知识图谱等,等它们成熟、且确实适配我们的场景时再引入。没有银弹,我们能做的,就是把握好"把已知的做扎实"和"对未知保持开放"之间的平衡。
解析是整条链路的地基——地基歪了,后面切块再聪明、检索再精准都白搭("garbage in, garbage out"在知识库里体现得淋漓尽致)。
我们的解析层是可插拔的:内置一个零外部依赖的默认解析器作为基线,同时支持接入 自研的Fabarta Parser(能做版面和表格结构识别,支持多种文件类型)、Marker、MinerU、PaddleOCR、以及 DeepSeek-OCR、Dots-OCR 这类 VLM 解析器。选哪个,按"文件级指定 → 知识库级指定 → 按文件类型自动匹配 → 内置兜底"的优先级层层回退,既能让用户对特定文件钦点高精度解析器,又保证任何情况下都有解析器可用。
在这些可配置的外部解析器的基础上,我们还提供了轻量化的内置解析器作为兜底方案。我们的内置解析器支持了PDF、Word、PPT、Excel、HTML、图片、音视频等大部分常见文件类型的解析并做了一定程度的增强:
- Word 公式不能丢。Word 里的数学公式是一种叫 OMML 的 XML 格式,普通解析直接就丢了。我们写了一个递归转换器,把它转成 LaTeX,做了尽力还原公式。对技术文档、学术资料,公式往往是最重要的信息,我们希望默认解析器能够在轻量的前提下尽量保留更多信息。
- PDF 的"换行"是个陷阱。从 PDF 抽文本时,每个视觉换行都会插一个 \n,中文段落会被切得支离破碎——"知识库" 可能因为正好在行尾被拆成"知识"和"库"两段。我们做了 CJK 换行恢复:根据句末标点、是否是 Markdown 结构行、英文连字符断词等线索,判断这个换行到底该不该合并,中文字符之间合并时不加多余空格。
- PDF 没有"标题"这个概念。PDF 里只有"这段文字字号 18、加粗、在这个位置",没有"这是一级标题"。我们借鉴成熟做法,用字号比例(比正文大 1.4 倍算 H1,1.2 倍算 H2)、字重、列表符号等排版特征,把文档的层级结构推断出来,还原成带标题层级的 Markdown。同时识别并跳过那种铺满整页的背景装饰图。
- PDF layout 识别。文档中我们常见的两列文本,对人类来说,有这天然的顺序语义。然而对于代码来说,它读取的顺序可能跟我们眼中看到的顺序并不一致。同来来说,文档结构的识别需要OCR,但我们在内置解析器上还是尽量做了一些处理,尽量保留这种结构上的语义。
如果说解析决定了"文本干不干净",那切块决定了"模型每次能看到的最小知识单元长什么样"。切得好,召回才准。 这是整条链路上性价比最高的发力点。
核心矛盾在于:没有一种切法能适配所有内容。一段叙述性的文档、一张表格、一段代码、一份问答对、一篇带多级标题的长文,它们的"自然边界"完全不同。用固定长度一刀切,是最省事也最糟糕的做法——它会把表格切碎、把一句话斩断、把一个完整的代码函数拦腰截断。
所以我们没有用单一切法,而是做了一组可按文档类型和场景选择的切块策略:

这里有两个值得讲的工程细节:
一是"切多大"要按 token 算,不能按字符算。 不同语言、不同内容的 token 密度差很多,按字符切很容易超过 embedding 模型的上限。我们用真实的 token 计数来定边界,并且在 token 预算内回退去找最近的自然断点——既不超长,又尽量不破坏语义。
二是给超长块上"双保险"。 即便是高精度解析器给出的预切块,偶尔也会有一块特别长。我们会对超过阈值的块做二次递归切分,确保任何一块都不会撑爆 embedding 模型——同时在这个过程中只保留结构标注、不复制图片的原始数据,避免元数据膨胀。
切块这件事没有标准答案,但提供足够多的"对的工具",并让每种内容都能用上最合适的那把刀,是我们能做的最实在的事。
检索是用户能直接感知到效果的环节。我们这里有三个设计值得说。
第一,混合检索 + 两阶段排序。 前面说过,向量检索懂语义但对精确 token 不敏感,关键词检索(BM25)正好相反。我们让两路并行召回,再把结果融合——这里用的是 RRF(Reciprocal Rank Fusion,倒数排名融合)。RRF 的妙处在于它只看"排名"不看"绝对分数":向量的余弦相似度和 BM25 分数根本不在一个量纲、没法直接相加,而 RRF 把两边都换算成"第几名"再合并,干净利落地绕开了这个难题。
这背后其实是一个"召回—精排"的两阶段范式。第一阶段(混合检索)追求的是 recall——尽量别把相关的漏掉,宁可多召回一些候选;如果还要更高精度,第二阶段再上一个 reranker 模型做 precision——把真正最相关的排到最前面。两者分工很清楚:reranker 是 cross-encoder,它把"问题"和"每个候选"拼在一起送进模型做交叉注意力打分,比向量"各自编码、再算距离"要精细得多;代价是它没法扫全库,只能对第一阶段召回回来的几十个候选做精排。这套"向量 + BM25 + RRF(+ 可选 reranker)"的组合,是目前业界主流的模式——Anthropic 在他们的 Contextual Retrieval 方案里也是这个路子,且实测配上重排后能把检索失败率显著压低(8)。
第二,多源统一检索。 真实场景里,一次提问要检索的往往不止一个知识库——可能同时涉及企业知识库、用户当前会话里临时上传的文件、以及对接的外部知识库。我们用一个统一的检索抽象把这些源并发查询、再按相关性合并,对上层完全透明。这样无论知识来自哪里,模型都是一视同仁地使用。
第三,来源可追溯,且防止"张冠李戴"。 让模型基于检索结果回答还不够,还得让用户能验证"这句话到底出自哪"。我们给每一个检索结果都打上全局唯一的来源标识(文件ID:块ID),并通过统一的引用规范,要求模型在每个结论后面带上这个角标、且必须整段复制不许自己拼接——因为一旦模型把 A 文档的文件 ID 和 B 文档的块 ID 拼到一起,就会指向一个根本不存在或张冠李戴的来源。每个结论必须能在检索到的原文里找到直接支撑,不许用模型自己的知识补充,也不许编造占位的引用。这一条规范,是"可信"二字的底线。
3.4 多模态:让图片"显示不丢、检索尽力"——以及一个朴素的关键决定
文档里的图片、图表、扫描件,是整条知识库链路上最容易"丢"信息的地方。一张架构图、一张财报表格里的关键数字,纯文本管线直接就丢在地上了,于是模型面对"这张图说明了什么"只能回答"我没有足够的信息"。这不是小毛病:在图表密集的文档(财报、技术手册、幻灯片)里,纯文本检索存在一个任何切块策略都补不回来的天花板——有评测显示,同样的财报 PDF,纯文本召回率约 62%,而视觉检索方案能到 84%。所以多模态召回是刚需,不是锦上添花。
业界目前主要有三条路线:
- 描述并索引(caption-and-index):用视觉模型(VLM)或 OCR 把图、表转成文字,再当普通文本来索引。最简单,也最容易复用已有的文本检索栈。
- 统一多模态向量:用 Cohere Embed 4、voyage-multimodal-3.5 这类模型,把文字和图像编码进同一个向量空间。这类单向量方案正在快速追平专门的视觉检索模型。
- 整页当图 + 迟交互:ColPali / ColQwen 这类,跳过 OCR,直接对页面图像做 patch 级嵌入,最大限度保住版面和图表信息——代价是更吃 GPU、系统更复杂,泛化性也还在验证中。
我们目前做了一个尽力而为的降级链。图片要不要、以及怎么参与检索,取决于当前配置了哪些模型能力:有视觉 embedding 模型,就用图像原生向量;没有,就用视觉模型(VLM)生成的文字描述来做向量;连 VLM 都没有,就只存储不检索。但无论降到哪一档,图片的"显示"能力永远不降级——用户该看到图,永远能看到。这避免了很多系统"模型能力不足时图片直接消失"的尴尬。
另外,这里讲一个实现细节。我们解析出的图片,在文本里是以 Markdown 链接的形式存在的,类似 。但是那段 URL对人阅读有用、对向量化是纯噪声。它没有任何语义,却占着 token,还会把这个 chunk 的向量往一个奇怪的方向稀释,导致召回变差。
我们的做法是:同一个 chunk,存两份内容。
- 一份是给模型做向量化的"净化文本"——把图片链接剥掉,只留下真正有语义的文字。
- 一份是给用户展示的"原始内容"——完整保留图片链接,前端该显示图就显示图。
"用来检索的"和"用来展示的"本来就是两件事,没必要是同一份数据。这个想法不复杂,但它解决了一个实实在在拖累召回质量的问题,也和业界成熟工具(Docling、Unstructured 等)的做法殊途同归。
我们还做了统一的图片中间表示。 不同解析器抽出来的图片格式五花八门,我们用一个统一的数据结构把它们归一化。这解决了一个很隐蔽的痛点——换一个解析器,图片就莫名其妙全丢了。归一化之后,无论谁解析,图片都能被一致地处理和绑定。
目前,我们的知识库已经能稳定支撑生产了。但这仍是个快速演进的领域,我们很清楚它还有大量没做好、能做得更好的地方。这一节就聊聊我们看到的方向——既有具体的技术点,也有一个更大的视角。
先说那个更大的视角:提升召回,从来不只是知识库内部的事。 如果把"让模型拿到对的知识"看成一条完整链路,知识库(解析、切块、索引、混合检索)只是中间一段,链路的上下游还有很多可做的:
- 检索之前:用户的原话往往口语化、有歧义、和文档用词对不上,在检索前加一层"查询理解/改写"能明显提升召回(具体见下面第二点)。
- 检索之后:reranker 精排、上下文压缩、"先检索小块、再喂大块"等,提升的是结果的精度。
- 整个过程之上:编排。这就回到了前面提的"上下文工程"——知识库只负责"把对的知识放进窗口",而窗口里还有指令、历史、工具、记忆,它们如何协同是更上层的问题,也正是 Agentic RAG 的舞台(见第二点)。
带着这个全局视角,再看我们具体在发力的几个点:
一、更“聪明”的检索结果融合机制。 现在向量和关键词两路是等权融合的。但不同场景下两路的可信度并不一样——问错误码时关键词更重要,问概念时语义更重要;到了多模态场景就更明显:融合时文本几乎总会盖过图像,不按模态调权,图片就很难被召回。让融合权重可调、甚至能按查询类型或模态自适应,是一个明确的改进点。
二、从 “被动检索” 走向 “主动探索”(Agentic RAG)。传统 RAG 的交互方式,本质上仍然是一次性的:根据用户问题召回若干 Chunk,再把结果一次性交给模型。这种模式默认假设 “召回的 Chunk 就是答案的边界”,但真实世界里的知识并不是这样组织的。人查资料时不会只看搜索结果,而是会打开文档、继续阅读上下文、沿着目录和交叉引用不断深入,直到找到真正需要的信息。
Agentic RAG 的意义,并不仅仅是”让模型多检索几次”,而是把检索能力重新包装成一组可以自主调用的工具,例如 Search、Find、Open、Summarize:模型可以先搜索相关文档,再打开其中某一份继续阅读,根据文内结构跳转到附录或引用章节,必要时再发起新的搜索,形成类似人类研究资料的探索过程。
这意味着,未来知识库的核心资产将不再只是向量索引,还应该是可导航的知识空间。我们今天为了引用溯源建立的文档定位能力(例如 file_id + chunk_id),未来完全可以进一步演化为 Agent 的导航地址:支持打开原文、扩展相邻章节、沿着目录和交叉引用继续阅读,让 Chunk 从”答案载体”重新回归为”文档入口”。
而知识库未来的发展方向,也不是不断追求更复杂的检索算法,而是逐步构建一个完整的 “规划—检索—阅读/评估—验证—再检索” 闭环,让知识库从回答问题的搜索工具,真正演进为能够自主研究和探索信息的智能助手。
三、"预生成知识结构"与”知识自成长”的新思路。 传统的知识库检索对于文档/知识的处理,本质都是"把文档切碎、存进库、按相似度、匹配结果来捞信息"。但还有一条很不一样的路线正在兴起:先用 LLM 离线把整个知识库"读"一遍,提炼成一个结构化的产物——可能是一份层层展开的"wiki"、一棵递归摘要树(如 RAPTOR),或一张实体关系图谱(如 Gbrain)。检索时不再直接在碎片上算相似度,而是先在这个高层结构上"导航"或"推理",再下钻到具体内容——给代码库自动生成可问答 wiki 的 DeepWiki、用推理式检索替代向量的 PageIndex,都是这个思路的代表。它的好处是保住了文档的全局结构、特别适合需要跨多处归纳的问题,可以不断沉淀知识;代价是离线生成和更新的成本。在AI大浪潮时代,知识库不止局限于为了召回已有信息,更是为了产生新的内容。而这正是第二点Agentic RAG所期望的”可导航的知识空间“。
更进一步,我们认为知识库未来应该具备持续成长(Knowledge Evolution)的能力。今天,大多数知识库仍然是”文档导入—建立索引—等待查询”的静态模式;未来,Agent 在每一次检索、阅读、回答和反思过程中,都可能反过来推动知识的演化。例如自动沉淀 FAQ、生成章节摘要、构建专题 Wiki、发现知识缺口、标记过期内容,甚至根据用户真实查询不断优化知识结构,让知识围绕使用场景持续生长,而不仅仅依赖人工维护。
换句话说,未来知识库的价值,将不仅是检索已有知识,更是持续生产和演化知识。它既是 Agent 获取信息的来源,也会因为 Agent 的持续使用而不断变得更加完整、更易理解、更符合真实业务场景。
四、视觉检索这条新路。 也就是前面讲多模态时提到的第三条路线——ColPali 这类把整页当图像直接检索的方案。它在版式复杂、图表密集的文档(财报、论文)上潜力很大,但更吃算力、泛化性也还存疑(在一些较新的评测集上会掉点),所以我们把它列为"值得实测、不急于默认启用"的探索项。还有一个更轻量、几乎纯加法的改进:当一张图同时有图像向量和文字描述时,为两者都建索引、做双通道召回。
未来,知识库会成为 AI 智能体随时查阅的 “知识环境”,而我们当下沉淀的技术、踩过的坑、落地的方案,都将成为走向下一阶段的底气。不迷信银弹,把基础做深、把细节做透,同时不断吸收新的理念,谨慎应用,就是技术落地最好的答案。
|
|
更多推荐



所有评论(0)