Skip to content

7.1.1 为什么召回到了内容,模型还是答不好? ​

先给结论:因为“召回到了”只说明候选集中出现了相关内容,但这并不保证模型最终真的会看到它、优先使用它、或者在冲突和噪声中正确使用它。

这也是很多 RAG 系统里最常见的一种错觉:

  • 结果里明明有对的内容
  • 但最终答案还是不稳

问题通常不在“完全没找到”,而在:

  • 找到了以后怎么排、怎么选、怎么组织

第一种常见情况:对的内容在候选里,但没排到前面 ​

模型最终能不能用上某条内容,前提通常是:

  • 这条内容得先进入最终上下文

如果相关候选排在很后面,而系统又只取前几条,结果就是:

  • 相关内容虽然存在
  • 但根本没机会进入模型视野

这时你会感觉系统“明明找到了还是答错”,其实根因更像:

  • 找到了,但没选上

第二种常见情况:候选里混进了太多噪声 ​

即使正确内容在里面,如果同时还混进:

  • 重复块
  • 旧版本
  • 边缘相关块
  • 模板噪声

模型也可能被干扰。

因为生成阶段面对的不是“唯一正确证据”,而是一组质量参差不齐的上下文。

如果上下文太杂,模型经常会出现:

  • 抓错重点
  • 混合多个候选
  • 过度概括

第三种常见情况:相关内容太碎,模型拿不到完整证据 ​

有时问题不是没有相关块,而是:

  • 相关信息分散在多个块里
  • 每个块只覆盖了一部分条件

如果系统没有把这些块组织好,模型就会看到:

  • 每块都像有点用
  • 但没有一块单独足够回答

这时最终答案很容易表现成:

  • 半对半错
  • 缺条件
  • 只回答了局部

第四种常见情况:候选之间存在冲突 ​

例如同时召回到了:

  • 新版本规则
  • 旧版本规则

或者:

  • 主规则
  • 例外条款

如果系统没有继续做排序、去重、版本控制和结果精选,模型就只能自己在冲突里做判断。

而这往往是高风险的。

因为它不是在“单一证据上回答”,而是在“冲突证据里猜哪条更该用”。

一个更直观的最小示意 ​

python
candidates = [
    {"text": "退款规则 v2:定制类商品支持无理由退货。", "rank": 1},
    {"text": "页面模板说明......", "rank": 2},
    {"text": "退款规则 v3:定制类商品不支持无理由退货。", "rank": 5}
]

final_context = candidates[:3]

这段代码想说明的问题是:

  • 正确内容可能已经在候选里
  • 但如果它没排进最终上下文,模型依然答不好

为什么这件事不能简单归因给模型 ​

很多人看到最终回答不好,第一反应是:

  • 模型理解错了

有时确实如此,但更常见的情况是:

  • 模型拿到的证据集合本来就不理想

也就是说,生成质量并不只取决于模型本身,还取决于:

  • 最终送给模型的是哪几条内容
  • 这些内容顺序如何
  • 是否存在冲突、冗余和噪声

一个更稳的排查顺序 ​

如果你发现“明明召回到了,还是答不好”,更稳的排查顺序通常是:

  1. 先确认正确内容是否真的进入最终上下文
  2. 再看它前面有没有更强噪声或错误候选
  3. 再看是否存在版本冲突和重复块
  4. 最后才看 Prompt 和生成模型本身

这样更容易把问题定位在真正出错的层上。

一个常见误区 ​

很多人会把“召回到了”理解成:

  • 后面就只是生成问题了

这通常是误判。

更准确的理解是:

  • 召回成功只是获得了候选资格
  • 候选还要继续经过排序、精选和组织,才会变成可用上下文

一句话总结 ​

召回到了内容,模型还是答不好,是因为候选存在不等于候选会被优先看到、正确使用和稳定组织。很多问题不是“没找到”,而是“找到了但没排好、没选好、没组织好”。