Skip to content

RAG 评估体系

提出问题

RAG(检索增强生成)是目前最广泛落地的 LLM 应用架构之一,但一个常见迷思是:上线后看用户反馈就够了,为什么要专门做评估?实际上,RAG 系统的质量痛点非常隐蔽——检索返回了 10 篇文档,LLM 只用了其中 1 篇,剩下 9 篇被忽略,但 LLM 自己编了一段"看起来合理"的回答。这种幻觉在日志里几乎无法被自动化检测,只能靠人工逐步排查。更棘手的是,检索质量下降和生成质量下降的症状可能相同(都是回答变差),但根因完全不同,修复方向也截然相反。因此,RAG 评估的核心价值在于:把检索和生成的质量拆开度量,让问题定位从"感觉不对"变成"具体哪项指标掉分了"

真实场景:一个典型的 RAG 质量事故

某知识库问答系统上线后,用户反馈"回答越来越不准确"。运维团队的第一反应是"LLM 模型不行了",准备换模型。但实际排查后发现:检索召回率从 0.85 掉到了 0.62,原因是 Embedding 服务在上周灰度发布时换了版本,新版本的向量分布没对齐,导致相关文档排到了 Top-10 末尾。LLM 侧没有做任何修改,但检索到的信息变少了,LLM 被迫用更少的信息来回答,自然就开始编造。

如果当时有 RAG 评估体系,会看到 Context Recall 指标从 0.85 跌到 0.62,而 Faithfulness 可能反而还正常(因为 LLM 确实基于检索到的内容回答了,只是检索到的内容不够)。定位就直接指向检索层,而不是 LLM 层。

分析问题

检索层评估:命中率、精确率与上下文召回

检索层的核心指标衡量的是"系统有没有把正确答案找回来"。常见的评估维度包括:

  • Context Precision(上下文精确率):检索结果中,真正有用的文档占所有检索结果的比例。高精确率意味着检索结果噪声少,LLM 不容易被无关信息干扰。
  • Context Recall(上下文召回率):正确答案中有多少被检索结果覆盖了。高召回率意味着关键信息没有漏掉。
  • Hit Rate(命中率):Top-K 结果中是否包含正确答案,典型的二元指标。

在实践中,高精确率 + 低召回率通常意味着检索策略过于保守(只返回最相关的 1-2 条),而低精确率 + 高召回率则意味着检索粒度太宽或 Embedding 区分度不够。两者需要根据业务场景平衡——问答类场景更看重精确率避免干扰,而摘要类场景更看重召回率确保信息完整。

检索指标对比

指标计算公式典型值影响链
Context Precision有用文档数 / 检索文档总数0.7-0.9低 → LLM 被噪声干扰,编造可能性↑
Context Recall被覆盖的有用信息 / 全部有用信息0.6-0.85低 → LLM 信息不足,答案不完整
MRR(Mean Reciprocal Rank)第一个正确答案的倒数排名均值0.5-0.9低 → 正确答案在末尾,Reranker 不行
NDCG带位置权重的排序质量0.6-0.9综合排序质量,受 Reranker 影响

生成层评估:忠实度、相关性与答案完整性

生成层评估关注的是"LLM 有没有用好检索结果":

  • Faithfulness(忠实度):答案是否基于检索到的文档,而不是模型凭空编造。这是 RAG 最关键的指标,也是 RAG 区别于纯 LLM 的核心价值。
  • Answer Relevance(答案相关性):回答是否针对用户问题,而不是答非所问或泛泛而谈。
  • Answer Correctness(答案正确性):答案与标准答案的匹配程度,需要 ground truth 支持。

其中忠实度的评估方法比较成熟:将答案拆解为原子声明(Claim),然后逐一验证每个声明是否能从检索到的文档中推导出来。如果某个声明没有任何文档支撑,则判定为幻觉。可以用 LLM-as-Judge 自动执行这个过程,也可以用人工标注做更精确的评估。

Faithfulness 的 Fine-grained 判定流程

输入:用户问题 Q + 检索文档集合 D + LLM 回答 A

        步骤 1:将 A 拆解为原子声明
                A → {claim₁, claim₂, ..., claimₙ}

        步骤 2:对每个 claim_i,在 D 中检索证据

        步骤 3:LLM 判断 claim_i 是否可从 D 中推导

                ├── 全部可推导 → Faithfulness = 1.0
                ├── 部分可推导 → Faithfulness = 可推导数 / 总数
                └── 全部不可推导 → Faithfulness = 0.0

踩坑记录:拆解粒度决定了 Faithfulness 分数的稳定性。按句子拆(粗粒度)时,一个句子包含 3 个事实,其中 1 个是幻觉,但整句判定为"可信"会漏掉问题。按短语拆(细粒度)时,评估结果敏感但成本高,且评判模型容易把"可推导"的边界判断错误。推荐的折中方案:按逗号/分号分隔的独立子句拆,每个子句包含一个完整的事实。

二阶段评估流程:从指标到行动

RAG 评估不能只看分数,要看分数变化后的根因排查。我整理了一个二阶段排查流程:

阶段一:指标监控(自动触发告警)
  Context Recall 震荡 → 检索引擎/Embedding 问题
  Faithfulness 震荡 → LLM 或 Prompt 问题
  Answer Relevance 持续偏低 → Prompt 模板或 Reranker 排序问题

阶段二:根因分析(人工介入)
  ↓ Context Recall 低
  ├── 检查 Embedding 版本是否变更
  ├── 检查索引库是否新增了脏数据
  └── 检查分块策略是否合理(块大小、重叠度)

  ↓ Faithfulness 低
  ├── 检查 LLM 的 system prompt 是否要求"只基于检索内容回答"
  ├── 检查检索到的上下文是否被截断(超 Token 限制)
  └── 检查 Reranker 是否把无关文档排到了前面

RAGAS 框架与 LLM-as-Judge

RAGAS 是目前最流行的开源 RAG 评估框架,它把上述指标系统化,核心思路是 端到端评估,无需人工标注

python
from ragas import evaluate
from ragas.metrics import (
    faithfulness,
    answer_relevancy,
    context_precision,
    context_recall,
)
from datasets import Dataset

# 构造评测数据:question + answer + contexts + ground_truth
data = {
    "question": ["RAG 评估为什么要分开衡量检索和生成?"],
    "answer": [
        "因为检索质量下降和生成质量下降的症状可能相同,"
        "但根因不同,分开衡量才能精确定位问题。"
    ],
    "contexts": [[
        "RAG 评估的核心价值在于把检索和生成的质量拆开度量。"
        "检索质量下降和生成质量下降的症状可能相同(都是回答变差),"
        "但根因完全不同,修复方向也截然相反。"
    ]],
    "ground_truth": ["检索和生成的质量需要分开度量,便于定位问题根因。"]
}

dataset = Dataset.from_dict(data)
result = evaluate(dataset, metrics=[
    faithfulness,
    answer_relevancy,
    context_precision,
    context_recall,
])

print(result)
# {'faithfulness': 0.95, 'answer_relevancy': 0.88, ...}

RAGAS 的底层依赖 LLM-as-Judge,即用另一个 LLM 打分。这也意味着评估结果受评判模型的能力影响——如果评判模型本身也分不清忠实度的边界,评估结果就会失真。

LLM-as-Judge 的选型踩坑

实测不同评判模型对 Faithfulness 评分的影响(某企业内部知识库场景,100 条测试集):

评判模型Faithfulness 均值人工一致率单条评估耗时
GPT-4o0.8792%3.2s
GPT-4o-mini0.8484%1.1s
Claude-3.5-Sonnet0.8890%2.8s
本地 7B 模型0.7865%8.5s

8 年 Java 后端转型的面试官可能会问:"你们用 RAGAS 评估,结果可靠吗?" 回答要点:RAGAS 的 Faithfulness 分数是相对值,不是绝对值——同一个模型、同一个评测集,跑 A/B 版本看分数变化方向,比看绝对值更有意义。绝对值的意义取决于评判模型和人工标注的一致性。

组件级评估与评测集构建

除了 RAGAS 的端到端评估,组件级评估同样重要:

  • Embedding 评估:对检索结果做 Recall@K / MRR 评估,看 Embedding 模型在领域数据上的检索质量。
  • Reranker 评估:看 Reranker 是否能将正确答案排到更靠前的位置。
  • LLM 生成评估:单独看 LLM 在给定上下文下的生成质量,排除检索的影响。

评测集的构建方法也有讲究:

方法做法适用场景成本覆盖率
人工标注专家标注 question + ground_truth精确度要求高的场景
合成数据用大模型生成 QA 对冷启动、快速迭代
用户反馈回流从日志中提取用户不满意的问答生产环境持续监控
黄金文档从已有文档按段落生成对应问题知识库类 RAG 系统

评测集维护的常见坑

  1. 测试集与训练集同分布:如果用 LLM 生成用于训练的文档,又用同一批 LLM 生成测试 QA,评测结果会虚高。至少切换模型或 Prompt 模板来生成测试集。
  2. 测试集过时:知识库每周更新,但测试集还是三个月前的版本。新的高频问题没有被覆盖。
  3. 只有一个正确答案:很多问题可能有多个正确答案路径,测试集只覆盖了其中一条,导致 LLM 换了一种正确说法但被判定为错误。建议对开放式问题允许多个 ground truth。

生产环境持续评估的架构设计

RAG 评估不应该只在离线做,线上同样需要持续监控。推荐一种生产级架构:

用户请求 → API Gateway → RAG Pipeline → 响应

                             监控 Agent(异步)
                                ├── 周期性采样用户请求
                                ├── 调用 LLM-as-Judge 打分
                                ├── 写入指标存储(Prometheus/InfluxDB)
                                └── 指标阈值告警 → 值班群通知

关键设计点:

  • 采样率:全量评估成本太高,5% 采样 + 阈值告警触发时补全量聚合。
  • 延迟容忍:评估是异步的,不阻塞线上响应。
  • 指标存储:至少保留 7 天粒度,方便回溯版本发布前后的指标变化。

总结

RAG 评估的核心是分离检索质量与生成质量,否则根因定位就是瞎猜。RAGAS 提供了 Faithfulness/Context Precision/Context Recall 等成熟指标,配合 LLM-as-Judge 可以自动化端到端评估。但自动化评估不等于完美——评判模型的质量、评测集的覆盖度、指标阈值的设定,都需要根据业务场景调优。上线后建议用用户反馈做长尾兜底,因为再好的指标也无法覆盖所有用户预期。

最后给 Java 后端转型的同学一个面试建议:面试官问你 RAG 评估,不要只说 RAGAS 有哪些指标。要说清楚指标之间的关联——比如 Context Recall 下降会导致 Faithfulness 跟着下降(因为 LLM 信息不足),但反过来不一定成立。能讲清楚这个因果关系,说明你真正理解 RAG 的评估体系。

参考

参考:RAGAS GitHub · RAGAS 论文 · LangChain RAG 评估指南

手撕 → 框架 → 生产化,一步步把 AI Agent 工程化搞透。