调 RAG 时,我见过一种很容易误判的情况:检索结果里明明有正确文档,而且就在 Top-5,模型最后还是答错。
团队的第一反应常常是“模型不够强”或“提示词还要改”。但打开完整链路后才发现,正确段落虽然被召回,却在重排序后掉到末尾;或者被上下文预算截断;或者和三段冲突文档挤在一起,模型引用了错误版本。
Retrieved 不等于 Ranked,Ranked 不等于 Visible,Visible 不等于 Supported,Supported 也不自动等于 Correct。
Top-5 只说明证据曾经进入候选集,不说明它真的抵达了答案。
1. 把“检索到了”拆成五个状态
为了让问题可以定位,我会为一条金标准证据记录五个状态:
- Retrieved
:正确 chunk 是否进入候选集; - Ranked
:它是否排在足够靠前的位置; - Visible
:组装、去重和截断后,模型最终是否看见; - Supported
:回答中的关键结论是否能被可见证据支持; - Correct
:回答是否满足任务的事实、范围和格式要求。

一旦有了这条状态链,“RAG 答错了”就能变成更具体的故障:召回失败、排序失败、上下文组装失败、生成不忠实,或者评测标准错误。
这五类问题的修复方向完全不同。召回失败要看 query、切块和索引;排序失败要看 reranker 与特征;组装失败要看预算和位置;生成失败才轮到提示词、引用约束和模型。
2. Top-k 召回率,只回答了第一层
如果 gold evidence 没有进入候选集,后面再强的模型也无从作答。这里可以测 Recall@k、命中文档率和命中 chunk 率,但要先定义什么叫 gold。
我会为一小批高价值问题人工标注:答案、最小支撑段落、文档版本和允许的同义证据。不是只标一个 URL,因为同一文档可能有多个相邻 chunk 都能支撑答案。
检索层常见问题包括:
查询里有缩写、版本号或实体别名,索引没有对齐; chunk 太大混入噪声,太小又丢失限定条件; 只做向量检索,精确编号和专有词匹配变弱; 索引仍是旧版本,正确答案已经更新。
BEIR 的结果提醒我们,不存在跨所有异构任务都天然占优的单一检索方法。BM25 仍是值得保留的稳健基线;向量、混合检索与重排序需要在自己的问题集上比较,同时计入计算与延迟。
3. 正确证据进来了,也可能在组装时消失
候选集通常还要经过 rerank、去重、权限过滤、版本过滤和 token 截断。每一步都可能把 gold evidence 处理掉。
最常见的三个问题是:
排序位置不对。 正确段落在第 5 名,但前四段内容更长、更像答案,模型先被错误叙事锚定。
上下文预算不对。 系统按字符或 token 截断,留下了标题,删掉真正包含数值和限定条件的后半段。
证据位置不对。 “Lost in the Middle”说明,长上下文模型对信息位置存在敏感性,相关信息在开头或结尾时往往比在中间表现更好。把 gold evidence 塞进上下文,不代表模型能同等利用它。
因此我会保存两份列表:retrieved_chunks 和 visible_chunks。前者记录检索器给了什么,后者记录模型真正收到什么。没有这两份快照,组装错误很容易被误诊为生成错误。
还应在每个 chunk 上带版本、时间、权限和来源。遇到冲突时,先按业务规则决定哪一版有效,不要让模型仅凭语言流畅度“投票”。
4. 看见证据,不代表回答被证据支撑
生成层至少要分开测三件事:
- 答案正确性
:结论是否回答了问题; - 证据忠实度
:结论是否能由提供的上下文推出; - 引用准确性
:引用是否指向真正支撑该句的段落。
一个回答可能事实碰巧正确,却引用了无关文档;也可能忠实复述了一份过期文档,因此业务上仍然错误。RAGAS 等工作正是试图把 RAG 的上下文与生成质量拆成多个维度,而不是只给一个“答对率”。
我还会做一个非常有效的对照:oracle context 测试。直接把 gold evidence 放在清晰、短小的上下文里让模型回答。
oracle context 仍答错:优先查问题表达、生成约束和模型能力; oracle context 答对、线上答错:优先查检索、排序和组装; 去掉冲突文档后答对:优先查版本与冲突消解。

这个对照能迅速缩小范围,比从头到尾反复改 prompt 更省时间。
5. 一次请求,至少留下这份证据日志
query_id / user_query / rewritten_query
index_version / retrieval_method / top_k
retrieved_chunk_ids + scores
reranked_chunk_ids + scores
visible_chunk_ids + order + token_span
document_version / permission_filter / truncation_reason
answer / sentence_level_citations
retrieval_label / faithfulness_label / correctness_label
离线评测时,这些字段可以聚合成每一层的通过率。线上出现投诉时,也能回到当时的索引和实际上下文,而不是用今天的索引重放昨天的问题。
更重要的是,优化目标要匹配失败层:
6. 对 Agent 和机器人,证据链还要约束动作
在普通问答里,证据丢失可能产生一句错话;在能调用工具或控制设备的 Agent 里,它可能触发错误动作。
因此,高风险动作不只要问“模型给了什么答案”,还要问:决策依赖哪条证据、证据版本是什么、是否满足动作前置条件、冲突是否已经解决。证据不足时,系统应该请求更多信息或转人工,而不是用语言自信填补空白。
RAG 的工程目标不是把文档塞进上下文,而是让可验证证据完整走到结论和动作。
下次看到“正确文档已经在 Top-5”,先别急着换模型。沿着 Retrieved、Ranked、Visible、Supported、Correct 五个状态查一遍,答案通常会比“大模型不够聪明”具体得多。
你们现在的 RAG 日志,能看见模型最终收到的 chunk 顺序吗?
参考:RAG 原始论文、BEIR、Lost in the Middle 与 RAGAS。文中的五状态证据链和排障日志是我的工程整理。
夜雨聆风