08RAG准确度评估

alex
1
2025-12-05

目录

  1. 检验的核心挑战

  2. RAG 三元评估体系

  3. 检索阶段评估指标

  4. 生成阶段评估指标

  5. 主流评估框架对比

  6. RAGAS 实战教程

  7. 评估数据集构建

  8. 生产环境落地策略

  9. 常见问题与解决方案


一、检验的核心挑战

1.1 为什么 RAG 结果难以检验?

RAG 系统由检索生成两个核心组件串联而成,任何一个环节出问题都会影响最终答案的准确性。

┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│  用户问题    │ -> │  检索模块    │ -> │  生成模块    │ -> │  最终答案    │
└──────────────┘    └──────────────┘    └──────────────┘
                           ↑                    ↑
                    可能召回无关内容      可能产生幻觉

核心难点

  • 答案没有唯一"标准答案",存在语义多样性

  • 幻觉问题:模型生成的内容不在检索到的上下文中

  • 检索与生成的耦合:检索好不一定生成好,检索差可能生成更差

1.2 检验的两个维度

维度

检验对象

核心问题

检索质量

召回的文档块

相关文档是否被召回?不相关文档是否混入?

生成质量

LLM 的回答

答案是否忠实于上下文?是否回答了问题?

1.3 核心检验方法:用 AI 评估 AI

当前业界最主流的方法是 LLM-as-a-Judge(大语言模型作为评判器),即用更强的大模型来评估你的 RAG 系统输出。实践证明,这种方法与人类判断具有良好的一致性。


二、RAG 三元评估体系

这是评估 RAG 系统最经典的框架,覆盖了从检索到生成的完整链路。

2.1 三元组构成

┌─────────────────────────────────────────────────────────────┐
│                    RAG 三元评估体系                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌─────────────────┐                                      │
│   │  上下文相关性   │  ← 检索质量:召回的文档与问题相关吗?   │
│   │ (Context Relevancy)│                                    │
│   └────────┬────────┘                                      │
│            ↓                                               │
│   ┌─────────────────┐                                      │
│   │   事实依据性    │  ← 生成质量:答案基于检索到的上下文吗? │
│   │  (Faithfulness) │         (核心:防幻觉)              │
│   └────────┬────────┘                                      │
│            ↓                                               │
│   ┌─────────────────┐                                      │
│   │   答案相关性    │  ← 生成质量:答案回答了用户问题吗?    │
│   │(Answer Relevancy)│                                      │
│   └─────────────────┘                                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2.2 各指标详解

指标一:上下文相关性(Context Relevancy)

定义:检索到的文档与用户问题的相关程度。

计算方式:通常通过 LLM 判断或语义相似度计算,输出 0-1 分数,越高越好。

典型问题

  • 检索到了大量不相关的内容(低精度)

  • 相关文档排名靠后(MRR 低)

指标二:事实依据性 / 忠实度(Faithfulness)

定义:生成的答案是否严格基于检索到的上下文,是否存在幻觉(Hallucination)。

计算方式

  1. 将答案拆解为多个"原子声明"(atomic claims)

  2. 逐一验证每个声明能否从检索到的上下文中推断出来

  3. 忠实度 = 可推断的声明数 / 总声明数

示例

上下文:中国成立于1949年10月1日,是社会主义国家。

答案:中国成立于1949年10月3日,是社会主义国家。

拆解为:
- 声明1:中国成立于1949年10月3日 → 无法从上下文推断 ✗
- 声明2:中国是社会主义国家 → 可从上下文推断 ✓

忠实度 = 1/2 = 0.5

指标三:答案相关性(Answer Relevancy)

定义:答案与用户问题的相关程度,越是不完整或包含冗余信息,得分越低。

计算方式:基于答案反向生成多个问题,计算这些生成的问题与原问题的相似度(取平均)。

示例

问题:中国的成立时间?

答案1:中国成立于1949年10月1日 → 相关性高
答案2:成立于1949年,是社会主义国家 → 包含冗余信息,相关性降低

三、检索阶段评估指标

检索阶段评估关注的是:系统找到了正确的文档吗?相关文档排在第几位?

3.1 核心指标

指标

全称

含义

计算方式

适用场景

Hit Rate@K

命中率

前K个结果中是否包含至少1个相关文档

包含相关文档的查询数 / 总查询数

快速判断检索是否有效

MRR

Mean Reciprocal Rank

首个相关文档排名的倒数平均值

1/rank 的平均值

强调第一个相关结果的位置

Precision@K

精确率@K

前K个结果中相关文档的比例

相关文档数 / K

关注检索结果的准确性

Recall@K

召回率@K

所有相关文档中被召回的比例

召回的文档数 / 总相关文档数

关注检索的全面性

MAP

Mean Average Precision

平均精度均值

综合考虑每个相关文档的排名

需要多个相关文档的场景

NDCG@K

归一化折损累积增益

考虑排名的整体排序质量

实际得分 / 理想得分

需要精细排序的场景

3.2 无参考检索指标(LLM-based)

传统指标需要人工标注"哪些文档是相关的",而新的 LLM-based 方法可以自动判断:

上下文精度(Context Precision):LLM 评估检索到的文档与问题的相关性,计算相关文档在排序中的位置得分。

上下文召回率(Context Recall):LLM 验证真实答案中的关键信息是否都能从检索到的上下文中找到。


四、生成阶段评估指标

生成阶段评估关注的是:答案质量如何?是否忠实、完整、有用?

4.1 核心指标

指标

含义

计算方式

说明

忠实度

答案是否基于上下文

原子声明验证

防幻觉的核心指标

答案相关性

答案是否回答了问题

反向生成问题+相似度

检测答非所问

答案正确性

答案与标准答案的匹配度

F1 + 余弦相似度 + LLM评分

需要人工标注的ground truth

上下文利用率

系统是否有效利用了检索内容

分析生成过程中使用的上下文比例

即使检索好,生成差也会导致低分

4.2 传统文本重叠指标(有局限)

指标

适用场景

局限性

ROUGE

摘要、翻译

仅关注n元语法重合,无法体现语义质量

BLEU

机器翻译

对与参考文本措辞不同但合理的表达会给出低分

⚠️ 注意:这些传统指标在 RAG 评估中作用有限,因为它们无法检测语义正确性和幻觉问题。


五、主流评估框架对比

目前业界最主流的 RAG 评估框架有三个:RAGAS、DeepEval、MLflow Evals

5.1 框架对比

框架

核心优势

指标数量

适用场景

学习曲线

RAGAS

检索评估专项优化,RAG 领域事实标准

8项核心指标

RAG 系统快速验证

⭐⭐

DeepEval

40+ 开箱即用指标,企业级全链路

40+

生产环境部署

⭐⭐⭐

MLflow Evals

MLOps 生态集成

基础指标

已有 MLflow 基建的团队

⭐⭐

5.2 选型建议

初创验证阶段 → RAGAS(快速定位检索瓶颈)
生产环境部署 → DeepEval(定制指标+持续监控)
混合架构场景 → MLflow(统一实验跟踪)

我的推荐:从 RAGAS 开始,它专门为 RAG 设计,指标最贴合业务需求。


六、RAGAS 实战教程

RAGAS(Retrieval-Augmented Generation Assessment)是目前最流行的 RAG 评估框架,本节提供完整的使用教程。

RAGAS的两阶段四指标总览

阶段

指标

核心问题

所需字段

检索阶段

上下文精度Context Precision

检索到的内容中,有多少是真正相关的?相关的内容排得靠前吗?

question, contexts, ground_truth

上下文召回率Context Recall

回答所需的信息,是否都被检索到了?

question, contexts, ground_truth

生成阶段

忠实度Faithfulness

生成的答案是否基于检索到的上下文?有没有胡说八道(幻觉)?

contexts, answer

答案相关性Answer Relevancy

生成的答案是否回答了问题?有没有冗余或跑题?

question, answer

6.1 安装

pip install ragas

如果需要使用测试集生成功能,额外安装:

pip install langchain-community langchain-openai datasets

6.2 评估数据集格式

RAGAS 需要以下格式的数据集:

from datasets import Dataset

data = {
    "question": [
        "中国的成立时间?",
        "谁赢得了最多的超级碗冠军?"
    ],
    "answer": [
        "中国成立于1949年10月1日",
        "新英格兰爱国者队"
    ],
    "contexts": [
        ["中华人民共和国成立于1949年10月1日,是工人阶级领导的社会主义国家"],
        ["新英格兰爱国者队赢得了创纪录的六次超级碗冠军,包装工队获得四次"]
    ],
    "ground_truth": [
        "中国成立于1949年10月1日",
        "新英格兰爱国者队"
    ]
}

dataset = Dataset.from_dict(data)

字段说明

  • question:用户问题

  • answer:你的 RAG 系统生成的答案

  • contexts:检索到的文档块(列表形式)

  • ground_truth:人工标注的标准答案(可选,用于答案正确性评估)

6.3 配置 LLM 和 Embeddings

RAGAS 默认使用 OpenAI,但你可以自定义:

from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import LangchainEmbeddingsWrapper
from langchain_openai import ChatOpenAI, OpenAIEmbeddings

# 使用 OpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

# 包装为 RAGAS 可用格式
ragas_llm = LangchainLLMWrapper(llm)
ragas_embeddings = LangchainEmbeddingsWrapper(embeddings)

使用自定义 LLM(如智谱、DeepSeek)

from langchain_community.chat_models import ChatZhipuAI
from langchain_community.embeddings import ZhipuAIEmbeddings
from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import LangchainEmbeddingsWrapper

# 配置智谱 AI
zhipu_chat = ChatZhipuAI(model='glm-4', api_key="your_key")
zhipu_embedding = ZhipuAIEmbeddings(model="embedding-3", api_key="your_key")

zhipu_llm = LangchainLLMWrapper(zhipu_chat)
zhipu_embeddings = LangchainEmbeddingsWrapper(zhipu_embedding)

6.4 运行评估

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

# 配置指标使用的 LLM
faithfulness.llm = zhipu_llm
answer_relevancy.llm = zhipu_llm
answer_relevancy.embeddings = zhipu_embeddings
context_precision.llm = zhipu_llm
context_recall.llm = zhipu_llm

# 运行评估
result = evaluate(
    dataset,
    metrics=[
        faithfulness,
        answer_relevancy,
        context_precision,
        context_recall,
    ]
)

# 查看结果
print(result)
df = result.to_pandas()
print(df.head())

6.5 完整评估代码示例

import os
from datasets import Dataset
from ragas import evaluate
from ragas.metrics import (
    faithfulness,
    answer_relevancy,
    context_precision,
    context_recall,
)
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import LangchainEmbeddingsWrapper

# 1. 准备评估数据集
def prepare_dataset():
    data = {
        "question": [
            "第一届超级碗是什么时候举行的?",
            "谁赢得了最多的超级碗冠军?",
            "超级碗在哪里举行?"
        ],
        "answer": [
            "第一届超级碗于1967年1月15日举行",
            "赢得最多超级碗冠军的是新英格兰爱国者队",
            "超级碗在不同城市轮流举行"
        ],
        "contexts": [
            ["第一届AFL-NFL世界冠军赛于1967年1月15日在洛杉矶纪念体育馆举行"],
            ["新英格兰爱国者队赢得了创纪录的六次超级碗冠军"],
            ["超级碗每年在不同城市举办,没有固定举办地"]
        ],
        "ground_truth": [
            "第一届超级碗于1967年1月15日举行",
            "新英格兰爱国者队",
            "超级碗每年在不同城市轮流举办"
        ]
    }
    return Dataset.from_dict(data)

# 2. 配置 LLM
llm = ChatOpenAI(model="gpt-4o-mini")
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
ragas_llm = LangchainLLMWrapper(llm)
ragas_embeddings = LangchainEmbeddingsWrapper(embeddings)

# 3. 配置指标
faithfulness.llm = ragas_llm
answer_relevancy.llm = ragas_llm
answer_relevancy.embeddings = ragas_embeddings
context_precision.llm = ragas_llm
context_recall.llm = ragas_llm

# 4. 运行评估
dataset = prepare_dataset()
result = evaluate(
    dataset,
    metrics=[
        faithfulness,
        answer_relevancy,
        context_precision,
        context_recall,
    ]
)

# 5. 输出结果
print("=" * 50)
print("评估结果汇总")
print("=" * 50)
print(f"忠实度 (Faithfulness): {result['faithfulness'].mean():.2f}")
print(f"答案相关性 (Answer Relevancy): {result['answer_relevancy'].mean():.2f}")
print(f"上下文精度 (Context Precision): {result['context_precision'].mean():.2f}")
print(f"上下文召回率 (Context Recall): {result['context_recall'].mean():.2f}")

# 6. 详细查看
print("\n详细结果:")
print(result.to_pandas())

6.6 高级功能:自动生成测试集

RAGAS 还支持从文档自动生成测试集,大幅降低人工标注成本:

from ragas.testset import TestsetGenerator
from langchain_community.document_loaders import DirectoryLoader

# 加载文档
loader = DirectoryLoader("path/to/documents")
documents = loader.load()

# 配置生成器
generator_llm = ChatOpenAI(model="gpt-4o")
critic_llm = ChatOpenAI(model="gpt-4o")
embeddings = OpenAIEmbeddings()

generator = TestsetGenerator.from_langchain(
    generator_llm,
    critic_llm,
    embeddings
)

# 生成测试集
testset = generator.generate_with_langchain_docs(
    documents,
    test_size=100,  # 生成100个问题
    distributions={
        "simple": 0.5,      # 简单问题占比50%
        "reasoning": 0.25,  # 推理问题占比25%
        "multi_context": 0.25  # 多上下文问题占比25%
    }
)

# 保存测试集
testset.to_dataset().save_to_disk("./my_testset")

⚠️ 注意:RAGAS 的测试集生成功能可能不稳定,尤其对中文支持有限。建议生产环境中优先使用人工标注的评估数据集。


七、评估数据集构建

7.1 黄金数据集的要求

一个高质量的评估数据集应具备:

要求

说明

覆盖全面

涵盖不同类型的问题(事实型、推理型、多跳型)

标准答案

每个问题都有高质量的人工标注答案

相关文档标注

标注每个问题对应的相关文档 ID

多样性

包含简单和复杂问题

7.2 构建方式对比

方式

优点

缺点

推荐场景

人工标注

质量最高,符合业务需求

成本高,耗时长

生产环境核心指标

自动生成(RAGAS)

成本低,速度快

质量不稳定,中文支持差

快速迭代验证

混合方式

平衡成本与质量

需要人工审核

推荐!

7.3 推荐:混合构建流程

步骤1:使用 RAGAS 自动生成 200 个问题
       ↓
步骤2:人工审核过滤低质量问题(保留约 100 个)
       ↓
步骤3:人工补充 50 个真实用户问题
       ↓
步骤4:统一标注标准答案和相关文档
       ↓
最终:150 条高质量评估数据集

八、生产环境落地策略

8.1 分层评估架构

┌─────────────────────────────────────────────────────────────┐
│                      分层评估架构                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  基础层(每次代码变更执行)                                  │
│  ├── 自动化指标测试(RAGAS)                                │
│  ├── 测试集大小:50-100 条                                  │
│  └── 阈值:忠实度 > 0.85,答案相关性 > 0.80                  │
│                                                             │
│  监控层(实时)                                              │
│  ├── 用户负反馈捕获                                         │
│  ├── 异常检测(指标突降 > 15%)                              │
│  └── 触发人工审核                                           │
│                                                             │
│  审计层(每周)                                              │
│  ├── 人工深度分析 50 条随机样本                              │
│  ├── 识别系统性问题                                         │
│  └── 更新评估标准                                           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

8.2 指标阈值建议

指标

可接受

良好

优秀

忠实度

> 0.80

> 0.90

> 0.95

答案相关性

> 0.70

> 0.85

> 0.90

上下文精度

> 0.70

> 0.85

> 0.90

上下文召回率

> 0.75

> 0.85

> 0.90

8.3 持续监控集成

# 将评估集成到 CI/CD 流程
# .github/workflows/evaluate.yml 示例

name: RAG Evaluation

on:
  pull_request:
    paths:
      - 'rag/**'

jobs:
  evaluate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run RAGAS evaluation
        run: |
          python scripts/evaluate_rag.py
      - name: Check thresholds
        run: |
          python scripts/check_thresholds.py \
            --faithfulness 0.85 \
            --answer_relevancy 0.80

九、常见问题与解决方案

9.1 检索指标好,但生成指标差

现象:上下文精度/召回率很高,但忠实度或答案相关性低。

可能原因

  • 检索到的内容虽然相关,但质量差(如 OCR 错误、格式混乱)

  • LLM 理解能力不足,无法从复杂上下文中提取信息

  • 提示词设计问题

解决方案

  • 优化提示工程,明确引导模型使用上下文

  • 尝试不同的解码策略(温度、top-p)

  • 对 LLM 进行领域微调

9.2 忠实度低(幻觉严重)

现象:答案中包含检索上下文中没有的信息。

可能原因

  • 模型过度依赖自身知识

  • 提示词未强调"仅基于上下文回答"

解决方案

  • 在提示词中加入严格的约束:"如果上下文没有相关信息,请直接说不知道"

  • 降低温度参数,减少随机性

  • 使用更强大的模型

9.3 答案相关性低

现象:答案质量高但答非所问。

可能原因

  • 问题理解错误

  • 检索到的上下文未能覆盖问题核心

解决方案

  • 使用查询重写(Query Rewriting)优化问题

  • 多轮检索或 HyDE 技术

9.4 LLM-as-Judge 的可靠性问题

挑战:用 LLM 评估 LLM 存在偏差和稳定性问题。

解决方案

  1. 人工验证:定期抽取 20% 样本进行人工验证

  2. 多模型评估:使用多个评估模型取平均

  3. 设置波动告警:指标变化 >15% 时触发人工审核


总结:检验 RAG 准确性的核心要点

必须做的三件事

  1. 建立黄金评估数据集:至少 50-100 条人工标注的问题-答案-文档三元组

  2. 采用 RAGAS 自动化评估:覆盖忠实度、答案相关性、上下文精度/召回率

  3. 分层持续监控:CI 测试 + 实时监控 + 人工审计

避坑指南

  • ❌ 不要只依赖 BLEU/ROUGE 等传统指标

  • ❌ 不要在真实用户场景直接用自动生成的测试集

  • ❌ 不要忽略检索质量的独立评估

  • ❌ 不要对 LLM-as-Judge 的结果过度自信

快速启动命令

# 1. 安装 RAGAS
pip install ragas datasets langchain-openai

# 2. 运行评估
python -c "
from datasets import Dataset
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy

data = {
    'question': ['你的测试问题'],
    'answer': ['你的RAG答案'],
    'contexts': [['检索到的上下文']],
    'ground_truth': ['标准答案']
}
dataset = Dataset.from_dict(data)
result = evaluate(dataset, metrics=[faithfulness, answer_relevancy])
print(result)
"

参考资源

动物装饰