RAG 效果差,80% 的问题和模型无关

20 阅读8分钟

当你开始怀疑模型的时候,问题往往已经被带偏了

如果你真的在项目里落地过 RAG(Retrieval-Augmented Generation),你大概率经历过下面这个过程。

 

一开始,你很有信心。

Embedding 模型选了主流的,

向量库也搭好了,

Prompt 看起来也挺专业。

 

但一测效果,你开始皱眉。

  • 有些问题明明“库里有”,模型却答不出来

  • 有些答案看起来很像“胡说”,但你又说不清楚错在哪

  • 换了个更大的模型,好像也没好多少

 

这时候,一个非常自然的念头就会冒出来:

 

“是不是模型不够强?”

 

于是你开始换模型、调参数、加上下文长度,

但效果依然不稳定。

 

很多 RAG 项目,就是在这一步,被彻底带偏方向的

 

因为在绝大多数真实项目中:

RAG 效果差,问题真的很少出在模型上。

 

一个必须先认清的事实:RAG 是“检索系统”,不是“模型能力放大器”

这是理解 RAG 失败原因的第一步。

 

很多人潜意识里,会把 RAG 理解成这样一件事:

 

“模型本来不会的问题,只要把知识塞进去,它就会了。”

 

但 RAG 的本质其实更接近于:

 

一个以自然语言为接口的检索系统

 

模型在 RAG 里做的事情,非常有限:

  • 理解用户问题

  • 利用给定上下文生成答案

 

而真正决定 RAG 上限的,是:

你到底给模型检索到了什么。

 

如果检索阶段出了问题,

模型再强,也只能在“错误或无关的信息”上发挥。

 

第一个常见误判:把“答不好”当成“模型不会”

这是 RAG 实战中最容易出现、也最容易误导判断的一点。

 

很多时候,模型不是不会答,

而是根本没看到该看的内容

 

你可以做一个非常简单的自检:

在生成之前,把检索到的内容单独打印出来,自己读一遍。

 

你会非常频繁地发现:

  • 检索结果本身就不相关

  • 只命中了关键词,没命中语义

  • 真正关键的信息被挤在很后面

 

在这种情况下,模型答不好,是完全正常的。

 

切分(Chunking),是 RAG 翻车的第一大源头

如果让我在 RAG 里只选一个“最容易被低估,但杀伤力最大”的环节,那一定是:

文档切分

 

很多人切文档时,脑子里只有一个目标:

“切小一点,方便检索。”

 

于是你会看到:

  • 固定长度切分

  • 不管语义直接截断

  • 表格、列表被打散

  • 上下文依赖完全丢失

 

这样做的直接后果是:

检索出来的 chunk,本身就无法独立表达有效信息。

 

模型看到的,不是“知识片段”,

而是“信息残骸”。

 

一个非常常见的场景:答案就在库里,但永远检索不到

这是很多 RAG 项目里最让人崩溃的时刻。

 

你明明知道:

“这个问题,文档里绝对有。”

 

但检索就是命不中。

 

原因往往不是 embedding 不行,而是:

  • 问题和文档的表达方式差异太大

  • 文档是“说明式”,问题是“场景式”

  • 切分后,关键信息被拆散了

 

Embedding 模型不是魔法,它无法在信息本身已经被破坏的情况下,自动帮你“拼回语义”。

 

TopK 并不是“越大越好”

这是另一个非常典型的工程误区。

 

很多人发现 RAG 效果差,第一反应是:

“那我多给模型一点上下文。”

 

于是 TopK 从 3 → 5 → 10 → 20。

 

结果往往是:

  • 上下文越来越长

  • 噪声越来越多

  • 模型开始抓不住重点

 

因为模型并不会自动帮你判断“哪段最重要”。

 

在很多场景下:

TopK 变大,只是在稀释真正有用的信息。

 

21.png

TopK 增大导致信息密度下降示意图

 

检索“命中”≠ 检索“可用”

这是一个非常关键、但经常被混为一谈的概念。

 

很多系统在调试 RAG 时,只看一个指标:

有没有命中相关文档。

 

但真正重要的,是:

命中的内容,能不能直接支撑答案生成。

 

比如:

  • 命中了背景介绍,但缺少结论

  • 命中了定义,但缺少条件

  • 命中了局部描述,但缺少上下文

 

对模型来说,这些信息是“不完整的线索”,

而不是“可用的依据”。

 

为什么换更大的模型,RAG 也不一定会变好

这是很多团队花了最多钱、却收获最少的一步。

 

当 RAG 效果差时,换模型往往是性价比最低的优化路径

 

原因很简单:

  • 模型只能基于已有上下文发挥

  • 它不能凭空补全缺失的信息

  • 更大的模型,只会更“自信地胡说”

 

在检索质量不高的情况下,

模型能力提升,很可能只会放大错误输出的流畅度

 

Rerank:很多 RAG 项目“救回来”的关键一步

在真实工程中,Rerank 往往是 RAG 效果的分水岭。

 

初始向量检索,解决的是“快”和“召回”;

Rerank,解决的是“相关性排序”。

 

很多时候,你的库里其实有正确答案,

只是它排在第 7、第 8 个位置,

模型根本没机会看到。

 

加入 rerank 后,

你会突然发现:

模型“好像变聪明了”。

 

但实际上,是你终于把对的内容,放到了它面前。

 

一个最小可用的 RAG 排查流程(非常实用)

当 RAG 效果不理想时,我非常建议你按下面这个顺序排查,而不是直接怪模型。

 

第一步:

固定模型,不动生成参数

 

第二步:

单独检查检索结果是否可读、可用

 

第三步:

检查切分方式是否破坏语义

 

第四步:

减少 TopK,看效果是否反而变好

 

第五步:

再考虑 rerank 或 query rewrite

 

这是一个非常“反直觉”,但成功率极高的流程。

 

22.png

RAG 排查流程图

 

一个简单的调试技巧:把模型当“人”用一次

这是我个人非常常用的一个方法。

 

在调试 RAG 时,你可以做一件很简单的事:

 

把检索结果直接贴给一个人,让他回答问题。

 

如果这个人都觉得:

“信息不够”“看不懂”“缺关键条件”,

那模型答不好,真的不是模型的问题。

 

Query 本身,也可能是 RAG 的隐形短板

很多人会忽略:

用户问题,并不一定适合直接拿去做检索。

 

尤其是在真实应用中,用户问题往往:

  • 口语化

  • 信息不完整

  • 带有上下文依赖

 

在这种情况下,

简单地用原始问题做 embedding,很容易偏离真正的检索目标。

 

这也是为什么 query rewrite 在很多项目里是“隐形刚需”。

 

一个很容易被忽略的问题:RAG 的评估方式本身可能是错的

很多团队在评估 RAG 时,只看最终答案。

 

但这样做,会把所有问题都归因到“模型输出”。

 

更合理的评估方式,应该拆成三层:

  • 检索是否命中正确 chunk

  • 提供的上下文是否足以支撑答案

  • 模型是否合理使用了上下文

 

如果第一层就失败了,后面再讨论模型,毫无意义。

 

23.png RAG 分层评估结构图

 

为什么 RAG 的工程成本,远高于你的第一印象

这是一个你在教程里几乎看不到的事实。

 

RAG 看起来很简单:

“检索 + 生成”。

 

但在真实项目中,它涉及:

  • 文档治理

  • 数据版本管理

  • 检索质量监控

  • 切分策略演进

  • 评估体系搭建

 

模型,反而是其中最稳定的一环。

 

一个现实建议:先把 RAG 当“检索系统”做好

如果你只记住这一篇里的一句话,那应该是这句:

 

RAG 成功与否,80% 决定于检索系统,而不是模型能力。

 

当你真的把检索质量、数据结构、切分策略打磨好之后,

你会发现:

哪怕用一个不那么大的模型,效果也会明显提升。

在验证 RAG 架构和数据组织是否合理时,先用 LLaMA-Factory online 快速对比不同检索策略下的生成效果,比一开始就深度绑定某个模型方案更容易定位问题。

 

总结:RAG 效果差,通常不是模型“不行”,而是你没把该给的东西给它

写到最后,其实结论已经非常明确了。

 

模型在 RAG 里,并不是主角。

它更像是一个“阅读理解能力很强的执行者”。

 

如果你给它的是:

  • 破碎的内容

  • 无关的信息

  • 排序混乱的上下文

 

那它能给你的,也只能是一个看起来很像答案的东西

真正成熟的 RAG 实战,不是不断换模型,而是反复打磨:你到底在让模型读什么。