RAG 系统评估——指标、数据集与落地方法
RAG 系统的评估方法。提出分层指标体系,说明黄金 QA 集的构建要点与评估方法,归纳常见失败模式与诊断流程,可供搭建可复跑的评测流程。
一 为什么 RAG 需要专门评估
RAG 系统的失败是级的:检索返回了错文档(检索失败)、返回了正确文档但模型没用到(生成失败)、或文档被截断 / 排序靠后导致关键信息丢失(上下文管理失败)。传统"问答题准确率"只能看到最终结果,定位不到是哪个环节出的问题。RAG 评估的核心方法论:分层归因——把"回答对不对"拆成"检索对不对 + 生成对不对 + 上下文传递对不对"三层分别度量。
二 分层指标体系
| 层 | 指标 | 定义 | 回答什么 |
|---|---|---|---|
| 检索层 | Recall@k / P@k / MRR | 相关文档在 top-k 结果中的召回 / 精度 / 平均倒数排名 | 检索找得到吗 |
| 检索层 | Fairness@k(多文档覆盖度) | 一条问题所需的全部相关文档是否都被检索到(搜索可能分散在多个 doc) | 是否"全找到" |
| 生成层 | Faithfulness(忠实度) | 答案中的每一句是否都能在检索上下文里找到依据(逐步检查,LLM-judge 判定) | 模型是否"编" |
| 生成层 | Answer Relevance(答案相关性) | 答案是否直接回答了问题(与 ground truth 语义对齐 + 无跑题) | 答到点上了吗 |
| 端到端 | Overall Accuracy / NDCG | 对照人工标注答案的整体质量分(1-5 分制)或排序相关性 | 用户视角的"好不好" |
| 鲁棒性 | 拒答正确率(abstention) | 库中无答案的问题,系统是否正确拒答而不是硬编 | 不编的能力 |
| 鲁棒性 | 漂移敏感度 | 同一问题换措辞(同义改写 x5),答案一致性如何 | 系统是否稳定 |
注意区分"检索指标"与"生成指标":检索好但忠实度低 = 模型在检索结果之外加私货;检索差但忠实度高 = 模型老实(只说检索到的)但回答不完整。两类指标的组合诊断出不同病灶,不能只看端到端准确率。
三 数据集:评估的命门
- 黄金问答集(golden QA):100-500 条(问题,期望答案,相关文档 ID,相关性判定)四元组。期望答案人工写(而非从库中原句抄——库是动态的,抄原句等于"背答案");相关文档 ID 人工标(哪些 doc 对回答是必要的,哪些是干扰项)。
- 文档覆盖度检查:每条问题检查"库中是否确实存在答案"(可答性标注)——不可答的问题单独统计拒答率,不能混入准确率统计,否则指标被"硬编"污染。
- 分层抽样:按文档类型(手册 / 论文 / 代码注释 / 邮件)与问题类型(事实查询 / 流程请求 / 对比 / 计算 / 多文档综合)分层构建,每层至少 20 条,防止"简单问题占 80%,指标虚高"。
- 对抗子集:干扰文档(库中有关键文档,但 top-1 是干扰项,测排序);跨文档综合(答案分散在 3+ 个文档,测多文档聚合);近义改写(同一问题 3-5 种措辞,测稳定性);时间敏感(库有新旧两版答案,测时效性)。
数据集的更新节奏:每次知识库大更新(新文档批量入库)后,补 20-50 条新样本进黄金集;每季度做一次全量复审(部分文档已失效的样本要移除或更新期望答案)。
四 评估方法:从"跑一遍"到"可持续"
| 方法 | 做法 | 时机 |
|---|---|---|
| 离线批量评估 | 黄金集全量跑,LLM-judge 打分(忠实度 / 相关性各一道题),人工抽样 10% 校准 | 每次变更(索引 / 提示词 / 模型)后 CI 必跑 |
| 分层诊断 | 检索差 → 查 top-k 是否含相关 doc(召回)/ 是否排在前面(排序);生成差 → 查忠实度是否低 / 上下文是否被截断 | 发现指标退化时的定位工具 |
| 在线 A/B | 同一流量双路(新旧配置)影子运行,比较用户反馈(赞踩 / 重新生成率 / 会话完成率) | 有真实流量后,离线通过 → 在线验证 → 全量 |
| 周期性对抗注入 | 每月把"对抗子集"单独跑一遍,检查漂移与鲁棒性退化 | 常规巡检 |
LLM-judge 的校准是持续工作:每月抽 30 条人工双盲标注,计算 judge 与人工的分歧率(Cohen's Kappa),Kappa < 0.6 说明 judge 的 rubric 要重写。judge 不是免费的裁判,是"需要定期校准的测量仪器"。
五 常见 RAG 失败模式与诊断
| 症状 | 典型根因 | 修复方向 |
|---|---|---|
| 检索 0 命中(库里明明有) | 嵌入空间不匹配(query 与 doc 领域差异大)/ 分块把关键内容切散 | query 改写 + 混合检索(BM25+向量);调分块策略 |
| 召回正确 doc 但排序靠后 | 向量相似度对术语 / 数字不敏感;重排未启用 | 加 cross-encoder 重排(top-50 → top-10) |
| 忠实度低(模型在加私货) | 提示词未约束"仅基于上下文回答";上下文过长模型"忘了"约束 | 提示词加约束 + 上下文分段 / 缩短;拒答兜底提示 |
| 多文档问答不完整 | top-k 只取 3 条,答案分散在 5 条里;模型未做综合 | 加大 k + 改提示为"综合以下所有信息";或分步问答 |
| 时效性问题答旧 | 库中新旧两版,嵌入相似度无法区分新旧 | 文档打版本号 + 时间衰减权重 / 检索后按时间过滤 |
| 简单问题也答长(信息冗余) | 提示词无"简洁"约束;上下文全塞入 | 提示词加"只回答所问,不展开" |
诊断流程固定为三步:① 跑分层指标,确定退化在哪一层;② 取该层失败样本 10-20 条人工读,归纳共性根因;③ 修复 → 回归同一组样本,确认修复不引入其他退化(防止"修了 A 坏了 B")。
六 评估工具链
- RAGAS / ARES / DeepEval:开源 RAG 评估框架,内置忠实度 / 相关性 / 上下文精度指标,LLM-judge 驱动,可接 CI。选一个深度用,不要三个都浅尝。
- LangSmith / Langfuse 评估模块:与 tracing 集成,线上采样自动评估,离线评估一键回放。
- 自建脚本:黄金集 YAML / JSON 存 git,评估脚本在 CI 里跑(每次 prompt / 模型 / 索引变更触发),结果写 PR 评论。最小集一天可搭,覆盖"忠实度 + 相关性 + 端到端准确率"三指标即可起步。
七 落地清单
- 第 1 周:建 100 条黄金 QA 集(含可答性标注 + 相关doc ID + 分层抽样),存 git
- 第 2 周:接 RAGAS(或自建脚本)跑通离线评估基线;记录当前忠实度 / 相关性 / 端到端三指标数值
- 第 3 周:CI 集成——每次 prompt / 索引 / 模型变更自动跑黄金集,退化 > 2 个点阻断合并
- 第 4 周:线上采样评估(1% 请求进评估管道),用户反馈(赞踩)与离线指标对齐验证
- 持续:每月 judge 校准(Kappa < 0.6 重写 rubric);每季度黄金集全量复审
一句话收束:RAG 评估的价值在于"让每次变更有数字可看、每次退化可定位"。黄金集是地基(没有它一切评估都是玄学),分层指标是诊断工具(知道哪里坏了),judge 校准是持续工作(测量仪器会漂)。三者齐了,RAG 系统才从"能跑"进化到"可维护"。
八 一个最小可运行的评估脚本骨架
很多人卡在"评估框架太重、跑不起来"。最小版其实就是一个循环:读黄金集(YAML 列表,每条问题 + 期望答案 + 相关 doc ID)→ 对每条问题跑自己的 RAG 管线拿到(检索结果,最终答案) → 送三个 LLM-judge 提示词(忠实度:答案每句是否都有上下文依据;相关性:答案是否切题;上下文精度:top-k 中相关文档占比)各打 1-5 分 → 汇总成 mean + 方差,退化超过 2 分报警。整个脚本 200 行内能写完,CISI 跑一次十分钟,关键不是框架而是黄金集的质量——先把 100 条黄金集建好,评估才有意义。