RAG 系列(八):RAG 评估体系——用数据说话

为什么"感觉不错"不是标准?

前面七篇文章,我们搭起了一整套 RAG 流程:分块、Embedding、向量库、检索策略。系统跑起来了,你问它几个问题,回答看起来"还不错"。

但问题接踵而至:

  • 迭代后真的变好了吗? 你换了 Embedding 模型、调了 chunk_size、加了 MMR,但回答质量真的提升了吗?还是只是"感觉"变好了?
  • 问题出在哪里? 某个问题回答得很差,是检索阶段 没召回相关文档,还是生成阶段模型在胡说八道?
  • 怎么向老板汇报? "我觉得我们的 RAG 系统挺好的"------这句话在数据驱动的团队里毫无说服力。

RAG 系统的评估,不能靠感觉,必须靠数据。

本文会带你从零开始,用 RAGAS 框架建立一套可量化的 RAG 评估体系,让你清楚地知道系统好不好、哪里差、怎么改。


RAGAS 是什么?

RAGAS(Retrieval-Augmented Generation Assessment)是专为 RAG 系统设计的开源评估框架。它的核心思想很朴素:用 LLM 作为裁判,自动判断 RAG 系统的输出质量

为什么用 LLM 当裁判?因为传统的 NLP 评估指标(如 BLEU、ROUGE)只适合做翻译或摘要任务,它们通过字符串匹配来判断相似度,完全无法理解语义。而 RAG 的评估需要理解"这个答案是否基于上下文"、"这个回答有没有答非所问"------这正是 LLM 擅长的。

RAGAS 提出了 4 个核心指标,覆盖了 RAG 系统的两个关键阶段(检索 + 生成):


四个核心指标详解

1. Faithfulness(忠实度)

问题:答案有没有在胡说八道?

Faithfulness 衡量生成答案是否忠实于检索到的上下文。如果模型在回答中加入了上下文里没有的信息,就是"幻觉",Faithfulness 就会低。

通俗理解:考试时Faithfulness高 = 答案全是根据提供的参考资料写的,没有自己瞎编。

计算方式:LLM 被prompt要求逐句检查答案中的每个陈述,判断是否能从上下文中推断出来。可推断的陈述数 / 总陈述数 = Faithfulness。

2. Answer Relevancy(答案相关性)

问题:答案是不是在答非所问?

Answer Relevancy 衡量答案与问题的相关程度。即使答案内容是对的,但如果偏离了问题的核心,这个指标也会低。

通俗理解:你问"怎么学 Python",对方却给你讲了一通 Java 的历史------虽然内容本身没错,但完全跑题了。

计算方式:LLM 根据答案生成若干个问题变体,然后计算这些问题与原始问题的 Embedding 相似度,取平均。

3. Context Precision(上下文精确度)

问题:检索回来的东西里,有多少是垃圾?

Context Precision 衡量检索结果中相关文档片段的比例。如果召回的 4 条上下文里有 2 条完全不相关,Context Precision 就是 0.5。

通俗理解:去图书馆找资料,借了 4 本书,只有 2 本有用------你的检索精确度就是 50%。

计算方式:LLM 逐条判断每个上下文片段是否与问题相关,相关条数 / 总条数。

4. Context Recall(上下文召回率)

问题:该找的东西找到了吗?

Context Recall 衡量所有与问题相关的信息,有多少被成功检索到了。这是检索阶段最核心的指标。

通俗理解:考试复习时,考卷上有 10 个知识点,你的复习资料只覆盖了 6 个------召回率就是 60%。

计算方式:LLM 将标准答案(ground_truth)拆分成多个关键陈述,然后逐条判断这些陈述是否能从检索到的上下文中推断出来。能推断的陈述数 / 总陈述数 = Context Recall。


四个指标的关系

bash 复制代码
用户提问
    ├─→ Context Recall 低? → 检索阶段有问题(chunk/embedding/top-k)
    ├─→ Context Precision 低? → 检索混入了噪声
    ├─→ Faithfulness 低? → 生成阶段幻觉(上下文不足或模型不听话)
    └─→ Answer Relevancy 低? → 答案跑题了

这四个指标互相独立、互相补充,一起构成了 RAG 系统的"体检报告"。


评估的第一步:构建测试集

评估需要"考题"和"参考答案"。测试集的质量直接决定评估结果的可信度。

测试集长什么样?

一个标准的 RAG 测试样本包含四个字段:

json 复制代码
{
  "question": "RAGAS 框架包含哪四个核心评估指标?",
  "ground_truth": "RAGAS 四个核心指标是:Faithfulness、Answer Relevancy、Context Precision、Context Recall。",
  "contexts": ["...", "..."],
  "answer": "..."
}
  • question:用户问题
  • ground_truth:标准答案(人工编写,不依赖模型)
  • contexts:RAG 系统检索到的上下文(运行后自动填充)
  • answer:RAG 系统生成的答案(运行后自动填充)

两种构建方式

方式 优点 缺点 适用场景
手工标注 质量高、边界清晰 成本高、耗时长 核心测试集、生产验收
LLM 生成 效率高、可规模化 需人工抽检校正 快速构建、扩充覆盖面

本文的测试数据

我们用 8 篇 RAG 相关的技术文章作为知识库(涵盖向量数据库、Embedding、分块策略、混合检索等主题),并为每篇手工编写了 1 个 QA 对:

json 复制代码
[
  {"question": "什么是 RAG 技术,它主要解决什么问题?", "ground_truth": "RAG..."},
  {"question": "企业级应用应该选择哪种向量数据库?", "ground_truth": "Qdrant 和 Weaviate..."},
  {"question": "中文场景应该选择哪个 Embedding 模型?", "ground_truth": "BGE 系列..."},
  ...
]

完整数据见 data/knowledge_base.jsondata/manual_testset.json


代码实战(一):搭建可评估的 RAG 系统

在评估之前,我们需要一个可配置的 RAG Pipeline。为什么要可配置?因为我们要对比不同参数(chunk_size、top_k)下的评估结果。

rag_pipeline.py 核心结构

python 复制代码
class RAGPipeline:
    def __init__(self, chunk_size=512, chunk_overlap=50, top_k=4):
        self.chunk_size = chunk_size
        self.chunk_overlap = chunk_overlap
        self.top_k = top_k

    def build_index(self, docs, force_rebuild=False):
        # 1. 切分文档
        splitter = RecursiveCharacterTextSplitter(
            chunk_size=self.chunk_size,
            chunk_overlap=self.chunk_overlap,
            separators=["\n\n", "\n", "。", ";", " ", ""],
        )
        chunks = splitter.split_documents(docs)

        # 2. 构建向量索引
        self.vectorstore = Chroma.from_documents(
            documents=chunks, embedding=embeddings
        )

        # 3. 组装 LCEL Chain
        self.chain = (
            {"context": retriever | format_docs, "question": RunnablePassthrough()}
            | prompt | llm | StrOutputParser()
        )

    def query(self, question):
        contexts = self.retriever.invoke(question)
        answer = self.chain.invoke(question)
        return {"question": question, "answer": answer, "contexts": contexts}

关键设计:所有影响质量的参数都暴露为构造函数的参数,这样我们可以在诊断实验中轻松切换配置。


代码实战(二):运行 RAGAS 评估

evaluate.py 评估流程

python 复制代码
def main():
    # 1. 加载 8 条手工测试数据
    testset = load_testset("./data/manual_testset.json")

    # 2. 构建 RAG Pipeline(默认配置:chunk=512, overlap=50, top_k=4)
    pipeline = RAGPipeline(chunk_size=512, chunk_overlap=50, top_k=4)
    pipeline.build_index(force_rebuild=True)

    # 3. 对每条测试数据执行 RAG,收集 answer 和 contexts
    dataset = prepare_dataset(pipeline, testset)
    # dataset 格式:{question, answer, contexts, ground_truth}

    # 4. 运行 RAGAS 评估
    result = evaluate(
        dataset=dataset,
        metrics=[faithfulness, answer_relevancy, context_precision, context_recall],
        llm=ragas_llm,        # 评估用的裁判 LLM
        embeddings=ragas_emb, # 评估用的 Embedding
    )

    # 5. 打印并保存报告
    print_report(result, dataset)
    save_report(result, dataset, "./evaluation_report.json")

注意:评估用的 LLM 和 Embedding 可以与 RAG 系统本身使用的不同。RAG 系统可以用轻量级模型(如 glm-4-flash),而评估裁判可以用更强的模型(如 GPT-4)来获得更准确的判断。不过在实际项目中,为了节省成本,通常用同一个模型。

实际运行结果

bash 复制代码
$ python evaluate.py

输出:

yaml 复制代码
============================================================
 RAGAS 评估报告
============================================================

📊 总体得分:
   faithfulness          : 0.792 ███████████████
   answer_relevancy      : 0.406 ████████
   context_precision     : 0.583 ███████████
   context_recall        : 0.625 ████████████

   平均得分                  : 0.602

📋 逐题明细:
     # Question                        Faith AnsRel CtxPre CtxRec
   ---------------------------------------------------------------
     1 什么是 RAG 技术...                1.00   0.68   1.00   1.00
     2 企业级应用应该选择哪种...          0.33   0.09   0.33   0.00
     3 中文场景应该选择哪个...            1.00   0.78   1.00   1.00
     4 文档分块时 Chunk Size...          1.00   0.86   0.50   1.00
     5 RAGAS 框架包含哪四个...           1.00   0.64   1.00   1.00
     6 RRF 融合算法的公式是...            0.00   0.00   0.00   0.00
     7 HyDE 查询优化技术的...             1.00   0.13   0.00   0.00
     8 生产级 RAG 系统如何...             1.00   0.07   0.83   1.00

⚠️  最差指标: answer_relevancy (0.406)
============================================================

结果解读

看到这个报告,我们能立即定位问题:

  1. Faithfulness 较高(0.792):说明模型基本能基于检索到的上下文回答,不太会凭空编造。
  2. Answer Relevancy 很低(0.406):这是最大的问题!说明很多答案虽然基于上下文,但没有准确回答问题的核心。
  3. Context Recall(0.625)和 Context Precision(0.583)中等:检索阶段有提升空间。
  4. 第 6 题全面崩溃(0/0/0/0):问的是 RRF 公式,但系统完全没有召回相关文档------这是典型的检索失败案例。

没有这份报告,你只会觉得"第 6 题回答得不太好"。有了报告,你精确知道是检索出了问题,而不是生成出了问题。


代码实战(三):诊断实验------好配置 vs 差配置

评估最大的价值不是打分,而是诊断。下面我们故意制造一个"差配置",看看 RAGAS 能不能发现问题。

diagnose.py 设计思路

参数 好配置 差配置 预期问题
chunk_size 512 128 上下文碎片化,语义断裂
chunk_overlap 50 0 边界信息丢失
top_k 4 2 召回不足,遗漏相关信息
python 复制代码
# 好配置
good = RAGPipeline(chunk_size=512, chunk_overlap=50, top_k=4)

# 差配置:chunk 太小 + 无重叠 + 只召回 2 条
bad = RAGPipeline(chunk_size=128, chunk_overlap=0, top_k=2)

诊断对比结果

运行 python diagnose.py

diff 复制代码
============================================================
 诊断对比:好配置 vs 差配置
============================================================

  指标                         好配置        差配置         差异           诊断
  --------------------------------------------------------------------
  faithfulness                0.830      0.750     +0.080         ✓ 正常
  answer_relevancy            0.502      0.191     +0.312         ✗ 严重
  context_precision           0.583      0.375     +0.208         ⚠ 警告
  context_recall              0.625      0.250     +0.375         ✗ 严重
  --------------------------------------------------------------------
  平均得分                        0.635      0.391     +0.244
============================================================

  📋 诊断结论:
     → Context Recall 显著下降:检索阶段有问题(chunk 太小 / top-k 太少)
     → Context Precision 显著下降:检索结果中混入了噪声
     → Answer Relevancy 显著下降:答案偏离了问题

诊断结论分析

下降指标 差配置数值 诊断
Context Recall ↓↓ 0.625 → 0.250 chunk 太小导致语义断裂,top_k=2 导致大量相关信息未被召回
Context Precision ↓ 0.583 → 0.375 碎片化后,低质量片段更容易被错误地匹配到查询
Answer Relevancy ↓↓ 0.502 → 0.191 上下文不足 → 模型只能基于有限信息回答 → 答案偏离问题
Faithfulness ↓ 0.830 → 0.750 上下文碎片化后,模型有时不得不"脑补"来填补信息缺口

这个实验完美展示了 RAGAS 的诊断能力 :不是笼统地说"差配置更差",而是精确告诉你哪个环节 出了问题、严重到什么程度


完整代码

本文的完整代码已开源,包含:

  • rag_pipeline.py --- 可配置的 RAG Pipeline
  • evaluate.py --- RAGAS 评估主脚本
  • diagnose.py --- 好配置 vs 差配置诊断实验
  • generate_qa.py --- LLM 自动生成测试集
  • data/knowledge_base.json --- 8 篇知识库文档
  • data/manual_testset.json --- 8 条手工测试数据

源码地址:

github.com/chendongqi/...


适用场景与注意事项

什么时候需要做 RAGAS 评估?

  • 系统迭代后:更换 Embedding 模型、调整分块策略、升级 LLM 后,跑一遍评估看指标变化
  • 上线前验收:建立 baseline,确保系统达到可接受的质量门槛
  • 问题排查:用户投诉回答质量差时,用指标定位是检索问题还是生成问题

注意事项

  1. 评估成本不低:4 个指标 × N 条测试数据,每条都要调多次 LLM。8 条数据大约需要 3-5 分钟、几百次 API 调用。生产环境建议用异步批量处理。
  2. ground_truth 质量决定评估上限:如果参考答案本身写得不准确,Context Recall 等指标就会失真。
  3. 裁判模型与业务模型可以不同:评估可以用更强的模型(如 GPT-4),RAG 系统本身用轻量模型(如 glm-4-flash),这样评估更准确且成本可控。
  4. 定期更新测试集:知识库更新后,测试集也应同步更新,覆盖新增领域。

小结

本文带你从零建立了一套 RAG 评估体系:

  1. 为什么评估:"感觉不错"不可量化,迭代后不知道变好变坏
  2. RAGAS 四大指标:Faithfulness(防幻觉)、Answer Relevancy(防跑题)、Context Precision(减噪声)、Context Recall(保召回)
  3. 测试集构建:手工标注为主,LLM 生成为辅
  4. 代码实战:完整的 RAG Pipeline + RAGAS 评估 + 诊断对比实验
  5. 真实数据:好配置平均 0.635,差配置平均 0.391,差距一目了然

关键认知:RAG 优化不能拍脑袋。先用 RAGAS 跑一遍评估,找到最差的指标,再针对性优化------这是最高效的改进路径。


参考资料

相关推荐
landyjzlai2 小时前
蓝迪哥玩转Ai(8)---端侧AI:RK3588 端侧大语言模型(LLM)开发实战指南
人工智能·python
ZhengEnCi4 小时前
05-自注意力机制详解 🧠
人工智能·pytorch·深度学习
前端程序媛-Tian4 小时前
前端 AI 提效实战:从 0 到 1 打造团队专属 AI 代码评审工具
前端·人工智能·ai
weixin_417197054 小时前
DeepSeek V4绑定华为:一场飞行中换引擎的国产算力革命
人工智能·华为
Irissgwe5 小时前
LangChain之核心组件(输出解析器)
ai·langchain·llm·ai编程·输出解析器
翼龙云_cloud5 小时前
阿里云代理商:阿里云深度适配DeepSeek V4让中小企业 AI零门槛上云
人工智能·阿里云·云计算·ai智能体·deepseek v4
MATLAB代码顾问5 小时前
DeepSeek R1:国产开源推理大模型的崛起与实践
人工智能