Gainstop-RAG:failed

6 阅读6分钟

Gainstop-RAG:我们试图教会小模型"知道自己不知道"

失败实验系列 · 第一篇


做 RAG 系统的人大多遇到过这种情况:明明相关文档都找到了,答案却还是错的。我们花了相当长时间想把这个问题做成一个系统,最后发现问题本身的解法走错了方向。这篇是完整的复盘。


一个被所有 RAG 系统忽视的假设

所有的 RAG 系统,无论架构多复杂,底层都有一个从未被明说的假设:

语义上相关的内容,就是回答问题需要的内容。

这个假设在大多数场景下成立,所以没有人质疑它。但在实验里,我们反复观察到一个奇怪的现象:

Gold 文档覆盖率 = 100%   # 所有需要的文档都找到了
答案正确率     = 0%      # 答案还是错的

这说明一件事:相关 ≠ 足够

找到了文档,不代表找到了"足以回答问题"的文档组合。RAG 的失败不只是检索召回率的问题,还有一个更深层的问题:模型不知道自己什么时候已经收集到足够的信息。

这就是 Gainstop-RAG / SQCS 项目的起点。


SQCS:让模型自己判断"够了没有"

SQCS(Sufficiency-based Query Completion Signal)的核心想法很简单——

传统 RAG:

检索 N 轮(固定轮次)→ 把所有文档塞给模型 → 生成答案

SQCS 的想法:

检索一轮 → 模型判断"信息够了吗?"
         → 够了就停止
         → 不够就继续检索,直到够为止

这个设计直觉上有几个优势:它解决了"相关 ≠ 足够"的问题;简单问题一轮就停,节省计算;也符合人类查资料的认知方式——人在查资料时也会判断"知道的够不够了"。

项目有一个核心约束:零训练 + 弱模型(≤7B) + 可以在 CPU 上运行。这个约束来自工程可行性考虑——真实部署里,不是每家公司都有 GPU,也不是每个场景都允许调用昂贵的强模型 API。

这个约束后来证明是整个项目的命门。


实验:弱模型做不了这个判断

我们设计了最小化实验来验证核心假设:给弱模型一个具体的单跳子问题和一篇文档,让它判断"这篇文档回答了这个子问题吗"。

三种场景的结果:

场景任务准确率
场景1相关文档,答案直接在文档里~60%
场景2相关文档,答案需要推理得出~45%
场景3不相关文档(应判断"不够")~50%

结论是决定性的:弱模型的判断准确率接近随机水平。

它不是"做得不够好",而是根本无法完成这个任务。场景3几乎等同于抛硬币。


三次设计迭代,三次碰壁

我们没有在第一次失败后就放弃,而是尝试了几种变体。

迭代1:把问题拆得更细

不让模型判断"信息够不够",而是让它判断更具体的问题:"文档里有没有提到 X 实体?"

结果:实体存在性的判断准确率有所提升,但引入了新问题——如何确定"X 实体"是什么?这需要另一个推理步骤,又回到了原来的问题。

迭代2:用打分代替二分类

不让模型判断"够/不够",而是让它给文档相关性打分,设置阈值。

结果:打分的分布极度不稳定。同一篇文档在不同轮次得分差异可以很大。弱模型对"信息充分性"没有稳定的内部表示,打分结果近乎随机。

迭代3:用树状结构替代单一判断

把多跳问题分解成子问题树,判断"这个叶子节点解决了吗"比判断"整体够不够"更容易。

结果:叶子节点的判断确实稍微容易一些,但本质上还是同一个任务。而且构建子问题树本身也需要推理能力,弱模型同样做不好。


为什么这是一个根本性障碍

在尝试各种变体之后,我们意识到这不是工程问题,而是能力边界问题:

让弱模型判断"我知道的够不够了",本质上是让它做元认知。这个能力在 7B 以下的模型里系统性地缺失,不是通过 prompt 优化能解决的。

这个结论在文献里也有佐证。FLARE、Self-RAG、IRCoT 这些做"自适应停止"的工作,都需要强模型(13B 以上,或者微调过的模型)。没有任何一篇用 ≤7B 零训练模型做这件事的工作有可靠的结果。

我们撞到了一堵有充分理由存在的墙。


失败之后的关键转折

放弃 SQCS 之后,我们重新审视了失败的根本原因:

旧思路新思路
谁来判断弱模型在线判断强模型离线预判
什么时候每次查询时提前一次性完成
能不能做做不到可以做到

这个转折有一种事后看来很显然、当时却不容易想到的简洁性:

SQCS 想解决的问题(检索什么时候够了)是真实存在的。但解决它的方式不一定是"让弱模型在线判断"——也可以是"让强模型提前告诉弱模型路径"。后者绕开了弱模型的能力瓶颈。这就是 PRIOR-RAG 的起点。


这个项目教会了我们什么

元认知是弱模型的硬边界。 判断"我知道的够不够"、"这步推理完成了吗"——这类任务系统性地需要大模型。用弱模型做元认知判断是一个方向性错误,不是工程问题。

"相关 ≠ 足够"是 RAG 真正的核心问题。 这个洞察本身是正确的,只是 SQCS 选错了解决路径。后续 PRIOR-RAG 验证了:通过预计算关键实体,可以从另一个角度解决这个问题。

能力约束要在设计阶段就验证。 我们在设计 SQCS 时假设弱模型能做元认知判断,没有提前验证这个假设。如果先跑一个最小化实验,可以早两周知道方向不对。这个教训很便宜,但只有在踩过坑之后才真正记住。


对于想在这个方向继续做的人:如果你有强模型或者愿意做微调,自适应停止机制是一个真实有价值的问题;如果约束和我们一样(弱模型+零训练),建议直接跳过,去做检索路径规划而不是停止判断。