老板说:“咱们的 RAG 知识库怎么老报错啊?”我说:“我测试挺好的呀?”老板说:“你自己看看!!”
2026/8/31 10:07:22 网站建设 项目流程

很多同学在搭建 RAG 知识库的时候都会有一个误区,那就是:只要把公司文档扔进向量数据库,再让大模型根据检索结果回答问题,一个企业知识库就算完成了。

这是完全不对的。

最近有部分同学就遇到了这样的情况。

我总结了一下,大致可以分为以下 4 种:

  • 第一:知识库里明确存在的信息,但是模型找不到
  • 第二:知识库里不存在的信息,模型会出现幻觉
  • 第三:好不容易搜到了信息,但却是旧的规则
  • 第四:资料明确需要人工审核的信息,模型却说会自动完成

那么这些问题到底是什么原因导致的呢?

咱们一点点来看。

RAG 并没有让模型学会你的资料

先把 RAG 的基本原理捋一下。

大模型原本不知道公司的内部规则、业务资料和产品文档。

RAG 要做的事情,就是在模型回答问题之前,先从知识库里找出与用户问题相关的资料,再把这些资料放进当前请求的 Context 里。

整个过程大概是这样的:

所以,RAG 本身是没有把公司的资料重新训练到模型里面的。

它只是每次回答问题之前,临时帮模型找几份参考资料。

举个例子,我直接问大模型:

我今天学习了什么知识?

大模型肯定不知道。

但是,如果我这样问大模型:

1.我今天学习了 RAG 知识库。 2.我今天学习了什么知识?

大模型是不是肯定就知道了。

“我今天学习了 RAG 知识库。” 这段文字,就是给大模型的临时参考资料。

但是这种临时参考资料可能会很多,因此,咱们不能每次都自己输入,对不对。

因此,咱们就得有个「知识库(类似数据库)」的东西,让大模型在这个「知识库」里面进行检索。

这也意味着,一个 RAG 系统想要给出正确答案,至少需要连续完成两件事:

  1. 找到正确资料
  2. 根据资料生成正确答案

因此,当大模型回答内容出错的时候,就不能只说一句:"模型不行,换个更强的模型吧。"

模型确实可能有问题。

但是在此之前,还有一长串地方值得检查。

第一:知识库里有,但是模型没有找到

举个例子。

现在咱们给一套企业数据平台搭建了知识库。

最新的数据导出规则中明确写着:

单次导出超过 50 万行的数据,需要由数据管理员进行审批。

然后用户问:

“我这张表有 80 万行,能不能直接拉下来?”

人一看就知道,这两句话讨论的是同一个问题。

但是,对于检索系统来说,两边的表达方式并不完全一样。

文档里写的是:

1.单次导出 2.超过 50 万行 3.数据管理员审批

用户说的是:

1.80 万行 2.能不能直接拉下来

如果只使用简单的关键词检索,用户的问题里压根没有“导出”和“审批”这两个词,相关资料就可能被漏掉。

这也是为什么 RAG 中经常需要用到向量检索

什么是向量检索

向量数据库本身并不能理解文字。

真正负责把文字转换成语义数据的,是Embedding模型。

Embedding 模型会把用户问题和知识库里的每一个 Chunk,都转换成一串数字。

比如,用户的问题:

我这张表有 80 万行,能不能直接拉下来?

经过 Embedding 模型处理以后,可能会变成:

[0.72, 0.18, -0.35, 0.61, ...]

知识库里的规则:

单次导出超过 50 万行的数据,需要由数据管理员审批。

也会变成一个向量:

[0.69, 0.21, -0.31, 0.65, ...]

真实的向量通常会有几百甚至几千个维度。

这里写四个数字,只是方便大家理解。

接下来,向量数据库会计算这两个向量之间的相似程度。

最常见的一种计算方式,就是余弦相似度

公式长这样:

复制

Cosine Similarity = A · B / (||A|| × ||B||)

看着有点复杂,但是其实很简单,看下图就明白了:

上面的内容就大白话来说,就是:可以把两个向量想象成两根箭头。

两根箭头指向越接近,余弦相似度就越高,也就说明两段文字在语义上越接近。

通常情况下:

  • 分数越接近1,语义越相似
  • 分数越接近0,相关性越弱
  • 分数越接近-1,方向越相反

不过这里要注意一个小细节。

  • 有些向量数据库返回的是“相似度”,分数越高越接近。
  • 有些返回的是“距离”,数值越低反而越接近。

这个得看清楚对应向量数据库的文档。

完整的向量检索过程大概是这样的:

比如,TopK = 5,就是从知识库里找到最相似的五个 Chunk。

但问题也就出在这里。

余弦相似度高,只能说明两段文字的语义比较接近,不代表这份资料一定可以回答用户的问题。

比如,知识库里可能同时存在:

1.大数据量导出规则 2.普通数据下载规则 3.报表异步生成规则 4.历史数据归档规则 5.管理员权限说明

这些资料都和 数据、下载、导出 有关。

它们的向量相似度可能都不低。

但真正能够回答 “80 万行数据能不能直接导出” 的,只有第一份。

余弦相似度并不知道:哪份资料是最新的、哪份资料已经废弃 了

所以,向量检索解决的是:

从大量资料里找出一批可能相关的候选内容。

什么是文档分块

除了向量相似度以外,文档怎样分块,也会直接影响检索结果。

比如原始规则是:

1.单次导出超过 50 万行的数据,需要由数据管理员进行审批。 2.审批通过以后,系统会异步生成下载文件。

结果在分块的时候,正好从中间切开了:

Chunk 1:单次导出超过 50 万行的数据 Chunk 2:需要由数据管理员进行审批。审批通过以后……

第一块只有限制条件,没有处理方式。

第二块只有处理方式,却不知道什么情况下需要审批。

检索系统即使把其中一块找回来,交给模型的也是残缺的信息。

所以,知识库里明明有答案,模型却没有找到时

应该优先检查:文档是否解析完整,Chunk 有没有被错误切分

什么是 Query Rewrite

Query Rewrite的作用,是:把用户口语化、依赖上下文的问题,改写成一条可以独立检索的查询。

比如,把:

80 万行能直接拉下来吗?

改写成:

单次导出 80 万行数据时,是否需要审批?

Multi-Query则会把同一个问题扩展成多个检索角度:

大数据量导出是否需要管理员审批? 超过 50 万行的数据应该如何下载? 80 万行报表的导出流程是什么?

然后分别检索一次,提高正确资料被召回的概率。

他们俩解决的问题是:应该找到的资料,到底有没有找回来。

第二:知识库里没有,模型开始瞎编

第二种情况正好反过来。

知识库里压根没有相关资料,但是模型依然给出了答案。

继续使用刚才的数据平台举例。

用户问:

“平台支持把数据直接导出成 Parquet 文件吗?”

知识库里只写了 CSV 和 Excel 的导出方式,根本没有提到 Parquet。

但是,向量数据库执行查询以后,通常还是可以返回几份“最相似”的资料。

注意,是最相似。

不代表真的相关。

它可能返回:

  • CSV 导出说明
  • Excel 下载规则

这些资料都提到了“导出”和“文件”,所以余弦相似度可能不低。

模型拿到这些内容以后,如果系统还强制要求它回答,就可能结合 “自己的常识” 补出一句:“平台支持 Parquet 格式,可以在导出设置中进行选择。”

PS:这种情况现在很多企业的 Agent 项目都会遇到,哪怕是大厂。

但是,问题是,知识库里从来没有这条信息。

这就是典型的生成幻觉。

很多人的解决方式,是在 Prompt 里增加一句:

只能根据知识库内容回答,不允许编造。

这句话可能会有点用,但是说实话:也不大管用。

因为 Prompt 依然只是交给模型的一条要求,不是程序级别的强制约束。

更可靠的方案,是把拒答能力明确设计出来。

第一种情况,完全没有检索到可用 Chunk。

程序可以直接返回:

暂时没有找到能够回答该问题的资料。

第二种情况,检索到了资料,但是这些资料不足以支持答案。

这时可以让模型返回结构化结果:

{ "status": "insufficient_evidence", "answer": "", "sourceChunkIds": [] }

应用程序识别到insufficient_evidence以后,再进入统一的拒答流程。

而不是继续逼着模型从三份不相关的资料里凑出一个答案。

另外,还可以给检索结果设置最低相关性阈值。

如果所有候选资料的分数都过低,就不继续进入答案生成。

不过,固定阈值也不能解决所有问题。

不同问题、不同资料和不同 Embedding 模型的分数分布并不完全一样。

所以,更稳妥的方案通常是:相似度阈值 + 模型判断证据是否充分 + 程序统一处理拒答

PS:在这里有详细的案例:商用知识库实战

很多知识库演示时看起来特别聪明,就是因为它什么问题都敢回答。

可一旦放到真实业务里,这反而是最危险的地方。

不知道的时候明确说不知道,本身就是系统能力。

第三:资料搜到了,却搜到了旧规则

第三种情况比较麻烦。

资料找到了,内容也能回答问题。

但是,它已经过期了。

假设公司的数据导出规则经历过一次调整。

旧规则是:

单次最多导出 10 万行数据,超过限制需要拆分任务。

新规则变成了:

单次最多导出 100 万行数据,超过 50 万行需要管理员审批。

如果新旧两份文档同时存在于知识库中,那么它们和“80 万行数据能不能导出”这个问题的语义都非常接近。

余弦相似度不会主动判断哪一份已经过期。

它只知道:这两份资料都在讨论大数据量导出。

如果旧规则的标题、正文与用户问题更加接近,它甚至可能排在新规则前面。

这时候,单纯依靠向量检索或者 Rerank,并不能彻底解决问题。

因为“语义最接近”和“业务上仍然有效”,根本就是两回事。

更靠谱的做法,是在文档入库时就保存完整 Metadata:

{ "documentId": "export-policy", "version": "2026.08", "status": "active", "effectiveFrom": "2026-08-01", "department": "data-platform", "permissionScope": "internal" }

检索的时候先通过 Metadata Filter 过滤:

status = active effectiveFrom <= 当前时间 用户拥有对应权限

先把已经废弃、尚未生效或者没有权限查看的资料排除掉,再进行向量检索和排序。

这比把新旧规则全部交给模型,再让它自己判断谁更新,要可靠得多。

因为模型可能判断错。

程序里的过滤条件则是确定的。

当然,文档更新时也要处理版本问题:

  • 新文档入库以后,旧文档是否要标记为失效
  • 原文更新以后,旧 Chunk 是否要删除
  • 文档版本变化后,是否需要重新生成 Embedding
  • 缓存中的旧答案什么时候失效
  • 多份资料冲突时,应该相信哪一个来源

这些才是企业知识库真正麻烦的地方。

第四:资料说需要人工审核,模型却说会自动完成

现在来看第四种情况。

知识库已经正确检索到了最新规则:

单次导出超过 50 万行的数据,需要由数据管理员人工审批。

用户问:

“我这张表有 80 万行,帮我导出来。”

结果模型回答:

“好的,导出任务已经自动提交,文件生成后会通知你。”

问题是,系统压根没有提交任何任务。

就算真的接入了导出 Tool,这个操作也不应该绕过人工审批。

这里已经不只是 RAG 检索的问题了。

而是:

模型把“知道业务规则”,误认为了“拥有执行权限”。

RAG 负责提供知识。

它可以告诉模型,超过 50 万行需要人工审核。

但真正控制任务能不能执行的,必须是应用程序。

如果当前系统只是一个知识问答助手,那么它应该回答:“该数据量需要先提交管理员审批,审批通过后才能生成导出任务。”

不能假装自己已经完成了操作。

如果系统已经接入了数据导出 Tool,那么 Runtime 也应该在执行前检查:导出行数是否超过 50 万 + 是否已经获得管理员批准

超过限制时,任务进入Human-in-the-loop流程,暂停执行,等待管理员确认。

模型可以提出:

我建议创建一个数据导出任务。

但是,最终能不能执行,不能让模型自己决定。

所以,企业 Agent 里很重要的一条原则就是:

模型可以提出动作,但是动作能不能执行,必须由 Agent 应用控制才可以。

怎么判断问题到底出在哪?

说到这里,大家应该能发现:虽然最终表现都是“模型回答错了”,但背后的原因完全不同。

那么当 Agent 的回答出现一些错误的时候,咱们怎么判断问题到底出在哪里呢?

有几种方式

第一种:Recall@K

Recall@K 关心的是:应该找到的资料,有没有进入前 K 个检索结果?

如果Recall@K很低,说明问题主要发生在召回阶段。

优先检查:文档分块、Embedding、 向量相似度配置

第二种:MRR

它的意思是:第一份正确资料排在第几名?

如果 Recall@K 不低,但是 MRR 很低,说明正确资料已经找到,只是排名太靠后。

这个时候应该检查混合检索权重、RRF 和 Rerank。

Faithfulness

他指的是:模型回答中的结论,有多少能够被检索资料支持?

如果召回和排序都正常,但是 Faithfulness 很低,问题更可能出在答案生成阶段。

最后

所以,一个完整的企业 RAG 知识库,远远不只是:向量数据库 + 大模型

它至少包含下面这条链路:

其中任何一层出错,最后展示给用户的答案都有可能会出错的。

资料展示
下面是我整理的AI大模型学习资料和工具包预览,适合收藏后按主题逐步学习

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询