如何评估 RAG:把检索和回答分开检查
用 Recall@k、证据支持与无答案用例定位 RAG 问题,用小数据集演示检索评估。
建立检索与回答分开的评测表,知道调参后应该回归哪些样本。
一个 RAG 答案不好,可能因为召回漏了资料、排序选错、上下文太杂,也可能是生成不忠于证据。只看最后一段文字,无法区分这些原因。
把链路分开评估,你才知道改动影响了哪一段,以及是否引入新的失败。
先测资料有没有找到
为一组查询标注可支持答案的资料 ID。Recall@k 表示前 k 个结果覆盖了多少已标注相关资料;它适合观察漏召回。
如果一个问题有多份有效资料,标注也应体现这一点。只标一个来源,可能把另一份正确证据误判成失败。还要明确按文档还是按块计算,避免混用粒度。
MRR 关注第一个相关结果的位置,适合观察排序是否让可用资料太靠后。它与 Recall@k 回答的是不同问题。
本地计算检索指标
下面使用人工构造的资料 ID。没有相关资料的问题返回空指标,随后单独评估“是否应该拒绝回答”,不把它混入召回率分母。
def retrieval_metrics(ranked, relevant, k):
if not relevant:
return {"recall": None, "mrr": None}
top = ranked[:k]
recall = len(set(top) & relevant) / len(relevant)
first = next((i for i, doc in enumerate(top, 1) if doc in relevant), None)
return {"recall": recall, "mrr": 1 / first if first else 0}
score = retrieval_metrics(["doc-c", "doc-b"], {"doc-a", "doc-b"}, k=2)
assert score == {"recall": 0.5, "mrr": 0.5}
assert retrieval_metrics(["doc-c"], set(), 1)["recall"] is None
print(score)
代码中的 MRR 限于前 k 个结果,真实报告应注明这个定义。多个查询的平均值,还要说明排除了哪些无标注或无答案样本。
再测回答是否使用了证据
检查答案中的陈述能否被提供的资料支持,引用是否指向对应位置,以及是否回答了用户真正的问题。有引用不代表引用正确。
可以借助模型辅助评分,但评分模型也可能出错。为评分规则保留人工样本,抽查不同问题类型,并观察评分是否与人类判断一致。
RAGAS 等工作将检索上下文、忠实性与回答质量拆成不同维度,适合作为设计评测表的参考,而不是一个不需要解释的总分。
无答案与权限用例不能少
准备资料库里没有答案的问题、资料过期的问题,以及用户无权访问的问题。期望结果可能是解释资料不足、询问澄清或停止访问,而不是生成一个完整长答案。
资料权限变动后,还应检查旧缓存和已保存的检索结果。权限正确不能只发生在首次建立索引时。
下一步
固定一小批查询,分别记录召回、排序、证据支持与最终回答。每次只改变一个关键变量,例如块大小或排序方式。
先检查失败类型,再决定改哪个组件。把真实发现的失败补进回归集,而不是只增加更多成功样本。
资料来源与延伸阅读
资料核验:2026-11-10。本文为原创工程讲解,教学示例不代表线上实测。