AI-使用DeepEval评测自己构建的RAG系统(一)

一、先理解RAG和DeepEval的底层逻辑

1.DeepEval是一个LLM评估框架,类似于"AI版的Pytest",专门用于测试和评估LLM应用的输出质量。它支持评估AI回答的准确性、幻觉程度、相关性等指标。

项目地址:https://deepeval.com/docs/getting-started-rag

2.一个典型的RAG系统有两个核心组件:

  • 检索器(Retriever):根据用户问题从知识库中检索相关文本块

  • 生成器(Generator):基于检索到的上下文生成最终答案

DeepEval的评测思路是分别评估这两个组件,因为最终答案的质量取决于"检索到的上下文"和"基于上下文的生成"两个环节。

DeepEval提供了5个专门用于RAG评测的指标,其中最核心的是RAG三元组(RAG Triad):

指标评估对象含义低分意味着什么
Answer Relevancy 生成器 答案是否与用户问题相关 需要优化提示词模板
Faithfulness 生成器 答案是否基于检索到的上下文(无幻觉) 需要换更强的LLM模型
Contextual Relevancy 检索器 检索到的上下文是否与问题相关 需要优化分块策略/embedding模型

 

这三个指标组合使用,可以全面诊断RAG系统的瓶颈。

二、环境准备

1. 安装DeepEval

pip3 install -U deepeval

2.配置API密钥(可选但推荐)

DeepEval默认使用OpenAI模型作为"评测员"(Judge),你也可以换成其他模型:

from deepeval.models import OllamaModel

使用本地部署的DeepSeek作为评测模型

model = OllamaModel("deepseek-r1")
answer_relevancy = AnswerRelevancyMetric(model=model)

DeepEval支持多种模型后端:OpenAI、Anthropic、Gemini、Ollama、Azure OpenAI等.

三、构建一个简单的RAG系统

首先,你需要有一个可以评测的RAG系统(如果已有,可跳过此步骤)。这里以LlamaIndex为例构建一个最简单的RAG应用:

# 安装依赖,LlamaIndex 默认使用 OpenAI 的 gpt-3.5-turbo。请将 API 密钥设置为环境变量:OPENAI_API_KEY=XXXXX,确保您的代码可以使用它。
# 这是用LlamaIndex构建的典型检索增强生成(RAG)流程。整个过程分为两步:第一步是检索,第二步生成结果,会调用LLM;
# 1)检索:首先,系统会将你的查询问题在向量库中进行相似性搜索,找到最相关的几个信息块。这一步只进行向量计算,不会调用LLM。
# 2)生成:然后,系统会将上一步找到的信息块和你的问题一起打包成一个提示(Prompt),发送给LLM。LLM会根据这些信息来理解和生成一个自然语言的答案。

# pip install llama-index

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader

加载本地文档(假设有一些txt/md/pdf文件在./data目录)

documents = SimpleDirectoryReader("./data").load_data()

构建索引

index = VectorStoreIndex.from_documents(documents)

创建查询引擎

query_engine = index.as_query_engine()

def my_rag_pipeline(question: str):
"""封装RAG调用,返回答案和检索到的上下文"""
response = query_engine.query(question)

提取检索到的上下文,

    # 简化的相似度搜索(实际项目中会用向量数据库和embeddingmodel)
  retrieved_contexts = [] 
  if hasattr(response, 'source_nodes'):
    retrieved_contexts = [node.text for node in response.source_nodes]
  return str(response), retrieved_contexts

关键点:DeepEval评测需要检索到的上下文作为输入,所以RAG函数必须同时返回答案和检索到的文本块。

四、创建测试数据集

评测需要一组测试问题。你可以有以下三种方式构建:

  1. 使用真实用户问题(最理想)

  2. 人工编写覆盖不同场景的问题

  3. 用DeepEval自动生成合成测试数据

  • 这里展示如何人工创建测试数据集:
from deepeval.dataset import EvaluationDataset, Golden

创建goldens(每个golden包含一个问题,可选包含期望答案)

goldens = [
Golden(input="什么是检索增强生成?", expected_output="检索增强生成(RAG)是一种..."),
Golden(input="RAG和微调有什么区别?"),
Golden(input="如何评估RAG系统的质量?")
]

dataset = EvaluationDataset(goldens=goldens)

保存数据集供后续使用

dataset.save_as(file_type="json", directory="./rag_evals")

如果你没有期望答案,也可以只提供问题,DeepEval会基于上下文自动判断答案质量。

  • 自动使用deepeval生成测试数据
from deepeval.synthesizer import Synthesizer

synthesizer = Synthesizer()

基于你的文档生成QA对

goldens = synthesizer.generate_goldens_from_docs(
documents=["doc1.txt", "doc2.pdf"],
num_goldens=20
)

  

五、定义评测指标

选择你要使用的RAG评测指标:

from deepeval.metrics import (
    AnswerRelevancyMetric,
    FaithfulnessMetric,
    ContextualRelevancyMetric,
    ContextualPrecisionMetric,
    ContextualRecallMetric
)

RAG三元组 - 无需期望答案

answer_relevancy = AnswerRelevancyMetric(threshold=0.7)
faithfulness = FaithfulnessMetric(threshold=0.8)
contextual_relevancy = ContextualRelevancyMetric(threshold=0.7)

如果需要更细粒度的检索评估(需要期望答案)

contextual_precision = ContextualPrecisionMetric(threshold=0.7)
contextual_recall = ContextualRecallMetric(threshold=0.7)

每个指标都有一个threshold(阈值),得分低于阈值表示测试未通过。

六、运行评测

现在将测试数据、RAG系统和评测指标串联起来:

from deepeval import evaluate
from deepeval.test_case import LLMTestCase

加载测试数据集

dataset = EvaluationDataset()
dataset.add_goldens_from_json_file(
file_path="./rag_evals/dataset.json",
input_key_name="input",
expected_output_key_name="expected_output" # 可选
)

为每个golden创建test case

test_cases = []
for golden in dataset.goldens:
# 调用RAG系统
actual_output, retrieved_contexts = my_rag_pipeline(golden.input)

创建test case

test_case = LLMTestCase(
input=golden.input,
actual_output=actual_output,
retrieval_context=retrieved_contexts,
expected_output=golden.expected_output # 可选
)
test_cases.append(test_case)

运行评测

results = evaluate(
test_cases=test_cases,
metrics=[answer_relevancy, faithfulness, contextual_relevancy], #指标列表
hyperparameters={
"model": "gpt-3.5-turbo",
"top_k": 3,
"chunk_size": 512
}
)

查看结果

for idx,test_case in enumerate(test_cases):
print(f"问题: {test_case.input}")
print(f"答案: {test_case.actual_output[:100]}...")

   print(f"答案: {test_case.expected_output[:100]}...")
for metric in results.test_results[idx].metrics_data:
      print(f"{metric.name}: {metric.score}")

  相关指标分数结果可参考如下:

image

 

七、分析结果并迭代优化

这是最关键的一步——根据评测结果诊断问题并优化系统。

常见问题模式及解决方案

 
问题模式指标表现可能原因优化方向
答案不相关 Answer Relevancy低 提示词模板不佳 优化prompt,增加few-shot示例
答案幻觉 Faithfulness低 LLM能力不足 换更强的模型(如gpt-4→o1)
检索不相关 Contextual Relevancy低 检索策略问题 调整chunk_size/top_k,换embedding模型
相关文档排名靠后 Contextual Precision低 排序策略问题 引入重排序器(reranker)
漏检相关文档 Contextual Recall低 检索召回不足 增加top_k,尝试混合检索(BM25+向量)

 

迭代优化示例

假设第一次评测发现Faithfulness得分很低(0.32),说明模型存在幻觉。你可以尝试换不同的LLM模型:

# 重新评测
from llama_index.core import Settings
from llama_index.llms.openai import OpenAI

models_to_try = ["gpt-3.5-turbo", "gpt-4", "gpt-4o"]

for model_name in models_to_try:
# 用新模型重新构建RAG
Settings.llm = OpenAI(model=model_name)
query_engine = index.as_query_engine()

重新评测

test_cases = []
for golden in dataset.goldens:
response = query_engine.query(golden.input)
retrieved = [n.text for n in response.source_nodes]
test_cases.append(LLMTestCase(
input=golden.input,
actual_output=str(response),
retrieval_context=retrieved
))

results = evaluate(test_cases, [faithfulness])

for test_result in results.test_results:

      for metric in test_result.metrics_data:
      print(f"{model_name}:{metric.name}={metric.score}")

通过这种"评测→分析→优化→再评测"的循环,你可以系统地找到最适合你场景的配置。

 

posted @ 2026-03-12 10:47  sunshine_coast  阅读(350)  评论(0)    收藏  举报