RAG 评估:检索指标 + 生成指标

一句话:RAG 评估分两层——检索层看”找得准不准”(Recall/Precision/MRR/NDCG),生成层看”答得好不好”(Faithfulness/Relevance)。两层拆开测,才能定位问题根因。


1.1 混在一起测 = 盲人摸象

RAG 系统 = **检索器(Retriever)**检索器(Retriever) + **生成器(Generator)**生成器(Generator)。一条 Fail 的用例,可能是:

  • 检索没召回对内容(检索层问题)
  • LLM 没用好召回的片段(生成层问题)
  • 两者都有问题

混在一起只能得到模糊结论混在一起只能得到模糊结论,无法指导优化方向。

1.2 分层评估的诊断价值

症状检索层指标生成层指标问题定位
回答完全错误Recall 低Faithfulness 低检索没召回
回答部分正确但有幻觉Recall 高Faithfulness 低LLM 编造
回答正确但不完整Recall 中Faithfulness 高TopK 太小
回答跑题Recall 高Relevance 低Prompt 问题

Note

90% 的 RAG 问题出在检索环节。如果 Hit@3 < 0.8,先修 embedding 或 chunk 策略。


一、检索层指标详解

检索层的核心问题:**给定 query,系统能否从文档库中召回最相关的片段?**给定 query,系统能否从文档库中召回最相关的片段?

1.1 混淆矩阵基础

在信息检索中,我们把结果分为四类:

实际相关实际不相关
被系统检索TP(真正例)FP(假正例)
未被检索FN(假负例)TN(真负例)

1.2 核心检索指标

Note

📌 ① Precision(精确率 / 查准率)

定义定义:检索到的文档中,有多大比例是真正相关的?

公式公式:Precision = TP / (TP + FP)

通俗理解通俗理解:你抓回来 10 条结果,有几条是真的有用的?

RAG 场景意义RAG 场景意义:Precision 低 = 大量无关片段被召回,干扰大模型,易产生幻觉。必须加 Rerank 过滤。

理想标准理想标准:≥ 70%


Note

📌 ② Recall(召回率 / 查全率)

定义定义:所有相关文档中,成功检索到了多大比例?

公式公式:Recall = TP / (TP + FN)

通俗理解通俗理解:库里有 20 条相关内容,你找回来几条?

RAG 场景意义RAG 场景意义:Recall 低 = chunk 切割不合理、Embedding 能力弱、缺少关键词检索。

理想标准理想标准:≥ 90%


Note

📌 ③ Precision@K / Recall@K

定义定义:只看 Top-K 结果中的 Precision 和 Recall。

RAG 场景意义RAG 场景意义:K 通常取 3 或 5(因为 LLM 上下文有限)。Recall@K 是 RAG 检索评估的核心指标Recall@K 是 RAG 检索评估的核心指标。


Note

📌 ④ F1-Score

定义定义:Precision 和 Recall 的调和平均数。

公式公式:F1 = 2 × (Precision × Recall) / (Precision + Recall)

适用场景适用场景:需要平衡精确率和召回率时。单一指标看 F1,避免”偏科”。

理想标准理想标准:≥ 0.8


Note

📌 ⑤ Hit@K / Hit Rate(命中率)

定义定义:有多大比例的查询,在前 K 个结果中至少检索到了一个相关文档?

公式公式:Hit@K = 至少有一个相关文档出现在 TopK 的查询数 / 查询总数

通俗理解通俗理解:用户提问后,前 K 条结果里有没有”正确答案”?

适用场景适用场景:快速验证检索器是否有基本召回能力。


Note

📌 ⑥ MRR(Mean Reciprocal Rank,平均倒数排名)

定义定义:第一个相关文档的排名的倒数,取平均值。

公式公式:MRR = (1/|Q|) × Σ(1/rank_i)

其中 rank_i 是第 i 个查询的第一个相关文档的排名。

通俗理解通俗理解:第一个正确答案平均排在第几位?排第 1 得 1 分,排第 2 得 0.5 分,排第 3 得 0.33 分…

RAG 场景意义RAG 场景意义:问答场景中,通常第一个片段命中最重要。MRR 越高,说明正确答案越靠前。

rank得分
11.0
20.5
30.33
40.25
50.2

Note

📌 ⑦ NDCG(Normalized Discounted Cumulative Gain,归一化折损累积增益)

定义定义:综合衡量排序质量,考虑相关性的”分级”(不是简单的是/否)。

计算步骤计算步骤:

  1. CG@KCG@K(Cumulative Gain):前 K 个结果的相关性得分累加
  2. DCG@KDCG@K(Discounted CG):排名越靠后,权重越低(折损)
  • 公式:DCG@K = Σ((2^rel_i - 1) / log2(i + 1))
  1. IDCG@KIDCG@K(Ideal DCG):最优排序下的 DCG
  2. NDCG@KNDCG@K = DCG@K / IDCG@K

适用场景适用场景:搜索结果需要分级相关性(如:不相关=0,部分相关=1,完全相关=2)。

Note

💡 注意注意:如果只标相关/不相关(0/1),NDCG 退化为简单的排序评估。


1.3 检索指标对比速查表

指标关注重点适用场景公式复杂度是否需要分级标注
Precision结果纯度控制噪声传入 LLM简单
Recall结果覆盖确保不遗漏关键信息简单
F1平衡性综合评估检索能力简单
Hit@K是否有正确答案快速验证召回能力简单
MRR正确答案位置问答场景简单
NDCG排序质量搜索结果排序复杂

1.4 检索常见问题诊断

指标异常可能原因优化方向
Recall 低chunk 过大/过小、Embedding 弱、无关键词检索调 chunk_size、换 Embedding 模型、加 BM25 混合检索
Precision 低大量无关片段召回加 Rerank、调相似度阈值、优化 query 改写
MRR 低正确答案排名靠后换更强的 Rerank 模型、调向量检索参数
Hit@3 < 0.8检索器基础能力不够重新选型检索方案

二、生成层指标详解

生成层的核心问题:**基于召回的上下文,LLM 生成的回答是否忠实、相关、有用?**基于召回的上下文,LLM 生成的回答是否忠实、相关、有用?

2.1 生成评估的难点

  • 没有参考答案没有参考答案:同一问题可以有多种正确回答
  • 语义理解语义理解:文字相似不代表语义正确
  • 幻觉检测幻觉检测:LLM 可能编造不存在的信息

解决方案解决方案:LLM-as-Judge(用大模型当裁判打分)


2.2 核心生成指标

Note

📌 ① Faithfulness(忠实度 / 真实性)

定义定义:回答中的每个陈述,是否都能被检索到的文档支持?

通俗理解通俗理解:LLM 有没有”胡说八道”?

评估方式评估方式:

  1. 声明提取声明提取:把回答拆成一个个事实声明
  2. 证据匹配证据匹配:逐个检查声明是否能在 context 中找到支持
  3. 打分打分:支持的声明数 / 总声明数

RAG 场景意义RAG 场景意义:最核心的生成指标最核心的生成指标。回答可以不完整,但不能编造。

理想标准理想标准:≥ 0.9(生产环境要求幻觉率 ≤ 5%)

Note

Faithfulness 是 RAG 的第一生成指标。优先级:Faithfulness > Answer Relevance > Context Utilization。


Note

📌 ② Answer Relevance(答案相关性)

定义定义:回答是否贴合用户的问题?有没有答非所问?

评估方式评估方式:

  1. 把回答反向生成问题(Reverse Query Generation)
  2. 比较生成的问题和原始问题的语义相似度
  3. 或者用 LLM 直接判断”这个回答是否解决了用户的问题”

RAG 场景意义RAG 场景意义:检测”跑题”现象——虽然用了正确的文档,但回答方向偏了。


Note

📌 ③ Answer Correctness(答案正确性)

定义定义:回答与参考答案(Ground Truth)的一致性。

评估方式评估方式:

  • 语义相似度语义相似度:用 Embedding 计算回答与参考答案的相似度
  • LLM 判断LLM 判断:让 LLM 对比回答和参考答案,给出 0~1 的分数

适用场景适用场景:有参考答案的测试集(如考试题、FAQ)。

Note

💡 注意注意:无参考评估时不能用这个指标,需要依赖 Faithfulness + Relevance。


Note

📌 ④ Context Precision(上下文精确度)

定义定义:检索到的上下文中,相关片段的比例。反映检索结果的整体相关性密度。

RAGAS 版本RAGAS 版本:用 LLM 判断每个片段是否与 query 相关,计算比例。


Note

📌 ⑤ Context Recall(上下文召回率)

定义定义:参考答案所需的参考信息,有多少被检索到了?

评估方式评估方式:

  1. 把参考答案拆成关键事实点
  2. 逐个检查这些事实点是否能在检索到的 context 中找到
  3. 计算比例

2.3 生成指标对比速查表

指标评估对象是否有参考核心用途评估方式
Faithfulness回答 vs Context无参考防幻觉LLM-as-Judge
Answer Relevance回答 vs Query无参考防跑题LLM-as-Judge
Answer Correctness回答 vs Ground Truth有参考测准确性Embedding/LLM
Context PrecisionContext vs Query无参考测检索纯度LLM-as-Judge
Context RecallContext vs Ground Truth有参考测检索覆盖LLM-as-Judge

2.4 幻觉检测专项

幻觉类型幻觉类型:

类型定义示例
事实性幻觉编造不存在的事实”公司成立于2010年”(实际是2015年)
逻辑性幻觉推理过程错误”A>B, B>C, 所以 C>A”
引用性幻觉声称引用文档但文档无此内容”根据第3条…”(实际没有)

幻觉率计算幻觉率计算:幻觉率 = 含幻觉的样本数 / 总测试样本数 × 100%

生产要求生产要求:幻觉率 ≤ 5%


4.1 RAGAS 简介

RAGAS(Retrieval-Augmented Generation Assessment)是 RAG 评估的行业标准框架,提供无参考评估无参考评估能力。

核心指标核心指标:

指标类别说明
context_precision检索上下文精确度
context_recall检索上下文召回率
faithfulness生成忠实度
answer_relevancy生成答案相关性
answer_correctness生成答案正确性(需参考)

4.2 安装与基础使用

from ragas import evaluate
from ragas.metrics import (
    context_precision,
    context_recall,
    faithfulness,
    answer_relevancy,
    answer_correctness
)
from datasets import Dataset
 
# 构造测试数据
data = {
    "question": ["公司年假最多可以休几天?", "如何申请报销?"],
    "answer": ["正式员工每年最多休10天年假", "需要填写报销单并提交发票"],
    "contexts": [
        ["员工手册规定正式员工年假上限10天"],
        ["报销流程:填写报销单 → 提交发票 → 部门审批 → 财务打款"]
    ],
    "ground_truth": ["正式员工年假每年最多10天", "填写报销单并提交发票即可申请报销"]
}
 
ds = Dataset.from_dict(data)
 
# 执行评估
result = evaluate(
    ds,
    metrics=[
        context_precision,
        context_recall,
        faithfulness,
        answer_relevancy,
    ]
)
 
print(result)
#  'faithfulness': 0.88, 'answer_relevancy': 0.85}

4.3 手写评估指标计算

核心指标的纯 Python 实现:

import numpy as np
from typing import List, Dict
 
# ========== 检索层指标 ==========
 
def precision_at_k(retrieved_ids: List[str], relevant_ids: List[str], k: int) -> float:
    """Precision@K:前 K 个检索结果中有多少是相关的?
 
    Args:
        retrieved_ids: 检索返回的文档 ID 列表(已排序)
        relevant_ids: 标注的相关文档 ID 列表
        k: 只看前 K 个结果
 
    Returns:
        精确率,范围 [0, 1]
    """
    retrieved_k = retrieved_ids[:k]                          # 取前 K 个
    tp = len(set(retrieved_k) & set(relevant_ids))           # 相关且被检索 = 真阳性
    return tp / k if k > 0 else 0.0                          # 除以 K 归一化
 
 
def recall_at_k(retrieved_ids: List[str], relevant_ids: List[str], k: int) -> float:
    """Recall@K:所有相关文档中,有多少被检索到了前 K?
 
    Args:
        retrieved_ids: 检索返回的文档 ID 列表
        relevant_ids: 标注的相关文档 ID 列表
        k: 只看前 K 个结果
 
    Returns:
        召回率,范围 [0, 1]
    """
    retrieved_k = retrieved_ids[:k]                          # 取前 K 个
    tp = len(set(retrieved_k) & set(relevant_ids))           # 相关且被检索
    return tp / len(relevant_ids) if relevant_ids else 0.0   # 除以总相关数
 
 
def hit_at_k(retrieved_ids: List[str], relevant_ids: List[str], k: int) -> float:
    """Hit@K:前 K 个里是否至少命中一个相关文档?(二元的)
 
    Returns:
        1.0 表示命中,0.0 表示未命中
    """
    retrieved_k = set(retrieved_ids[:k])
    return 1.0 if retrieved_k & set(relevant_ids) else 0.0   # 有交集即命中
 
 
def mrr(retrieved_ids: List[str], relevant_ids: List[str]) -> float:
    """MRR(Mean Reciprocal Rank):第一个相关文档排名的倒数
 
    排第 1 得 1.0,排第 2 得 0.5,排第 3 得 0.33...
    """
    for rank, doc_id in enumerate(retrieved_ids, start=1):
        if doc_id in relevant_ids:                           # 找到第一个相关文档
            return 1.0 / rank                                # 返回其排名倒数
    return 0.0                                               # 没找到 → 0
 
 
def f1_score(precision: float, recall: float) -> float:
    """F1-Score:精确率和召回率的调和平均"""
    if precision + recall == 0:
        return 0.0
    return 2 * (precision * recall) / (precision + recall)
 
 
# ========== 生成层指标(LLM-as-Judge 简化版) ==========
 
def faithfulness_simple(answer: str, context_chunks: List[str]) -> float:
    """忠实度简化计算:检查回答中的句子能否在上下文中找到支撑
 
    生产环境建议用 RAGAS 的 faithfulness(基于声明提取+证据匹配),
    这里给一个简化版说明原理。
 
    Args:
        answer: LLM 生成的回答
        context_chunks: 检索到的上下文片段列表
 
    Returns:
        忠实度分数,范围 [0, 1]——有支撑的句子占比
    """
    import re
    # 按句号/分号/换行拆分回答为独立声明
    claims = [s.strip() for s in re.split(r'[。;\n]', answer) if len(s.strip()) > 5]
    if not claims:
        return 0.0
 
    context_text = ' '.join(context_chunks)                  # 拼接所有上下文
    supported = 0
    for claim in claims:
        # 简化判断:声明中的关键词是否在上下文中出现
        # 生产环境应用 embedding 相似度或 LLM 逐条判断
        keywords = [w for w in claim if len(w) >= 2]         # 取长度≥2的词
        match_count = sum(1 for kw in keywords if kw in context_text)
        if len(keywords) > 0 and match_count / len(keywords) > 0.3:
            supported += 1                                   # 关键词覆盖超 30% → 有支撑
 
    return supported / len(claims)                           # 有支撑声明占比
 
 
# ========== 使用示例 ==========
if __name__ == "__main__":
    # 模拟一次检索
    retrieved = ["doc_3", "doc_1", "doc_7", "doc_2", "doc_5"]  # 检索返回的排序
    relevant = ["doc_1", "doc_2", "doc_9"]                     # 人工标注的相关文档
 
    k = 3
    print(f"Precision@{k}: {precision_at_k(retrieved, relevant, k):.3f}")
    print(f"Recall@{k}:    {recall_at_k(retrieved, relevant, k):.3f}")
    print(f"Hit@{k}:       {hit_at_k(retrieved, relevant, k):.3f}")
    print(f"MRR:           {mrr(retrieved, relevant):.3f}")
    print(f"F1:            {f1_score(precision_at_k(retrieved, relevant, k),
                                      recall_at_k(retrieved, relevant, k)):.3f}")
 
    # 模拟生成评估
    answer = "正式员工每年最多休10天年假。需要填写报销单并提交发票。"
    contexts = [
        "员工手册规定正式员工年假上限10天。",
        "报销流程:填写报销单 → 提交发票 → 部门审批。",
    ]
    print(f"Faithfulness:  {faithfulness_simple(answer, contexts):.3f}")

Pipeline 架构

Note

📈 [Mermaid 图表] flowchart TD A[测试数据集<br/>question + ground_truth + reference_chunks] --> B[检索模块] B --> C[检索层指标<br/>Recall@K / Precision@K / MRR / NDCG] B --> D[召回的 Contexts] D --> E[生成模块<br/>LLM生成Answer] E --> F[生成层指标<br/>Faithfulness / Relevance / Correctness] C --> G[评估报告] F --> G G --> H{指标达标?} H -->|Yes| I[通过评估] H -->|No| J[诊断根因] J --> K[优化检索 / 优化生成] K --> A


行业参考标准

指标合格线优秀线说明
Recall@K≥ 80%≥ 90%关键信息不能漏
Precision@K≥ 60%≥ 75%噪声控制
F1-Score≥ 0.7≥ 0.85综合平衡
Hit@3≥ 0.7≥ 0.85基础召回能力
MRR≥ 0.6≥ 0.8正确答案位置
Faithfulness≥ 0.85≥ 0.95防幻觉核心
Answer Relevance≥ 0.8≥ 0.9贴合问题
Hallucination Rate≤ 10%≤ 5%越低越好

诊断矩阵

Note

📈 [Mermaid 图表] quadrantChart title RAG 问题诊断四象限(Recall vs Faithfulness) x-axis Low Recall --> High Recall y-axis Low Faithfulness --> High Faithfulness quadrant-1 检索强 + 生成弱:调 Prompt / 换模型 quadrant-2 双高:理想状态,保持监控 quadrant-3 双低:先修检索,再调生成 quadrant-4 检索弱 + 生成强:优化 Embedding / Chunk / 检索策略

象限RecallFaithfulness问题定位优化优先级
第一象限LLM 没用好文档 / Prompt 问题调 Prompt、加约束
第二象限理想状态保持监控
第三象限检索器根本不行换检索方案
第四象限检索召回不够调 chunk、加混合检索


七、参考资料

来源链接内容
CSDN - RAG测评系统全链路搭建指南https://blog.csdn.net/m0_58868237/article/details/162827441检索+生成指标详解与代码实现
CSDN - RAG评估指标理论篇https://blog.csdn.net/ngadminq/article/details/147857146指标公式与定义
CSDN - RAG项目完整效果评估体系https://blog.csdn.net/2501_92990656/article/details/162809923三层评估体系与 RAGAS 实战
CSDN - RAGAS 框架详解https://blog.csdn.net/u013538542/article/details/158312178RAGAS 指标原理与使用
51CTO - LLM-as-Judge 实现https://www.51cto.com/article/816568.htmlLLM 评估系统实践
RAGAS 官方文档https://docs.ragas.io/官方指标定义与 API

Note

💡 关联笔记关联笔记:

Note

Note

Note

▶ 对应原理:10-LLM幻觉与可靠性

▶ 对应原理:22-RAG评估指标

速记卡(面试闪卡)

Q1:一句话讲清「RAG 评估:检索指标 + 生成指标」到底是什么? A:RAG 评估分两层:检索层看找得准不准,生成层看答得好不好,分层才能定位根因。

Q2:一、为什么分两层 —— 怎么理解? A:RAG = 检索器 + 生成器。答错可能是没召回对内容,或 LLM 没用好片段。混测像盲人摸象,只知”不行”不知改哪。分开测:Recall 低修检索,Faithfulness 低管幻觉。

Q3:二、检索层指标 —— 怎么理解? A:Precision 看抓回的有用比例(低了加 Rerank),Recall 看相关找回多少(低了调 chunk/换 Embedding),MRR 看正确答案排第几,NDCG 看排序质量。90% 的 RAG 问题出在检索。

Q4:三、生成层指标 —— 怎么理解? A:Faithfulness(忠实度)是头号指标:每句话能否在 context 找到支撑,可不完整但不能编。Answer Relevance 防跑题,Answer Correctness 需参考答案。无参考时用 LLM-as-Judge 打分。

Q5:四、RAGAS 与评估流水线 —— 怎么理解? A:RAGAS 是行业标准,提供无参考评估(context_precision/recall、faithfulness、answer_relevancy)。Pipeline:测试集→检索指标→生成指标→报告→不达标诊断根因。合格线:Recall@K≥80%、幻觉率≤5%。

Q6:核心速记主线有哪些?

  • 分层:检索层 + 生成层
  • 检索:Precision/Recall/MRR/NDCG
  • 生成:Faithfulness 为首,防幻觉
  • RAGAS 无参考;Recall@K≥80%、幻觉≤5%

口诀 A:RAG 评估分两层,召回生成各问症; 检索不准先去整,忠实不编是死坑。 达标线记心间,幻觉五个点莫轻; 分层定位好下手,优化不偏方向明。

相关链接


技术学习路线图 > RAG

相关链接