ELL3N HSU

Available in Chinese only.

← 文章

RAG 答错了,先查检索还是生成?

以版本化技术文档问答为例,沿文档、切块、召回、重排与生成定位错误,并用证据替换实验区分检索和回答能力。

假设一个技术文档助手被问到:“2.4 版本出现 ERR_AUTH_EXPIRED,应该怎么处理?”它给出了流畅的步骤,却用了旧版本的重启方案。只改提示词要求“准确回答”,并不能告诉我们错误发生在哪里。

先别急着换模型。沿着这次回答往回看:模型看到的是哪一版文档?正确段落有没有被检索出来?如果拿到过,它又是在哪一步被过滤或截掉的?把这条路径查清楚,才能确定应该改索引、排序,还是模型使用证据的方式。

把一个失败样例变成可检查的记录

先为这个问题保存一份最小判定依据:目标版本、相关文档 ID、支持结论的段落,以及答案必须保留的条件。例如“仅适用于 2.4;刷新凭据;不能把重启当作凭据续期”。这些是测试夹具,不必要求最终回答逐字一致。

同时记录实际召回列表、重排分数、最终上下文、回答与引用。只有回答文本时,无法区分“没有拿到证据”和“拿到了却没有正确使用”。

依次检查有效文档、召回与上下文中的证据,缺失时分别检查入库、检索和重排组装,证据完整后检查生成与引用。依次检查有效文档、召回与上下文中的证据,缺失时分别检查入库、检索和重排组装,证据完整后检查生成与引用。
RAG 排障示意:沿证据流定位第一个缺口;一条请求可能同时存在多个问题。

宽图可横向滚动。查看原图查看原图

图中的检查顺序可以缩小范围,但不保证一次只存在一个故障。修正检索后,还要重新检查生成,不能把第一个修复当作整条链路已经通过。

切块先保留解释错误码的条件

在这个错误码例子里,假设“仅适用于 2.4”在小节开头,刷新凭据的步骤在下一段。若按固定字符数切块,两部分可能被分到不同候选中,模型就只看到步骤,看不到适用条件。因此,技术文档通常更适合保留带标题路径的段落、完整步骤组,或连同表头一起保存表格行。

每个 chunk 除了文本,还应保存文档 ID、版本、章节路径、更新时间和访问范围。检索返回后,才有办法区分同名功能的不同版本、合并相邻片段并跳回原文。重叠切块能缓解边界断裂,但会增加重复候选与上下文占用;提高 overlap 不会自动修复丢失的表头和条件。

文档更新也不只意味着插入新向量。旧 chunk 是否删除、索引何时可见、回答缓存是否仍引用旧内容,都需要纳入更新流程。否则检索模型再好,也可能稳定返回一份过期答案。

精确标识符与自然语言需要不同信号

ERR_AUTH_EXPIRED、配置键和类名适合用词项匹配保留精确性;“凭据突然不能用了”这类改写则需要语义召回。混合检索可以分别取得候选,再融合排名。

稀疏和向量检索的原始分数通常不能直接相加。RRF 使用排名计算融合分数,对文档 dd:

RRF⁡(d)=∑j: d∈Rj1c+rank⁡j(d)\operatorname{RRF}(d)=\sum_{j:\,d\in R_j}\frac{1}{c+\operatorname{rank}_j(d)}

排名从 1 开始,cc 是正的平滑常数;不在某个候选列表中,就不贡献该项。例如仅作演算取 c=10c=10,文档 A 在两个列表中排名 1 和 4,分数约为 0.1620.162;文档 B 排名 2 和 2,约为 0.1670.167。B 因两路都靠前而略高。

RRF 不需要把两路原始分数校准到同一量纲,但它仍受候选窗口、文档去重和检索质量限制。若精确版本过滤漏掉了正确文档,融合无法凭空补回它。

重排提升顺序,不能突破候选的上限

重排器可以结合问题与候选内容,更细致地区分相关性;成本通常随候选数与文本长度增加。先召回较宽的集合,再重排取少量上下文,是一种计算分配方式。

但正确证据没有进入候选时,重排没有机会选中它。因此需要分开测召回集和最终上下文的覆盖率:前者低,先改切块、过滤或召回;前者高而后者低,检查重排与截断。

塞更多 chunk 也不是无成本补救。重复内容会挤掉关键条件,长上下文增加延迟,并可能让模型忽略相关位置。最终组装要保留版本与章节信息,限制重复片段;引用应指向实际提供给模型的证据。

用证据替换实验检查生成

现在直接把已确认的 2.4 版处理段落交给模型,替换本次检索结果,问题和生成配置保持不变。如果它这次答对了,就有理由继续检查原来的检索和上下文组装;如果仍然答错,还要看它如何理解证据。这是排障时的对照实验,不能作为正常检索链路的生产成绩。

对照结果可以缩小的范围仍需检查
替换后正确原检索或上下文组装存在问题的可能性增加是否有噪声、冲突版本、截断
替换后仍错生成可能没有理解或遵守证据问题歧义、模型能力、判定标准
两种上下文都正确但引用错回答正确性与引用对齐分离引用 ID、引用是否支持具体断言

评估时,检索可以看 Recall@k:相关证据中有多少进入前 k 个候选;相关集合不完整时,这个指标也只对已标注范围成立。回答则分开看事实正确性、证据支持程度和引用准确性。一个答案可能符合现实却没有被给定材料支持,也可能忠实复述一份过期文档;这两种错误需要不同处理。

“没有找到支持材料”也应是允许的结果。对于版本不明、文档缺失或相互冲突的情况,明确缺口比补出一套看似完整的操作步骤更有用。

把权限与更新也放进回归集

权限过滤应在检索和上下文交付的可信边界内执行,不能先把越权内容交给模型再要求它保密。共享索引、缓存与重排服务都需要携带访问范围;用户权限变化后,旧缓存不能继续绕过检查。

回归集除了正常问答,还应包含旧版本同名段落、错误码改写、缺失证据、冲突资料、越权文档和文档更新。每次失败保留第一个证据缺口,再回到对应环节修复。

这样的排障方法可以继续用于有检索工具的 Agent。区别是 Agent 还会决定何时检索、怎样重试,需要再检查行为与副作用;这部分见 Agent 评估与回归。