最完整RAG评估指南:用DeepEval构建可靠检索增强生成系统
你是否曾遇到过这样的困境:辛辛苦苦构建的RAG(检索增强生成)系统在测试时表现出色,但上线后却频繁出现回答不准确、甚至编造信息的情况?法律合同中的一个错误条款引用,可能导致重大合规风险;客户服务中的一个错误回答,可能失去宝贵的客户信任。这些问题的根源往往不在于模型本身,而在于缺乏系统化的评估方法。本文将带你全面了解如何使用DeepEval构建端到端的RAG评估体系,读完你将能够:- 自动生成...
最完整RAG评估指南:用DeepEval构建可靠检索增强生成系统
你是否曾遇到过这样的困境:辛辛苦苦构建的RAG(检索增强生成)系统在测试时表现出色,但上线后却频繁出现回答不准确、甚至编造信息的情况?法律合同中的一个错误条款引用,可能导致重大合规风险;客户服务中的一个错误回答,可能失去宝贵的客户信任。这些问题的根源往往不在于模型本身,而在于缺乏系统化的评估方法。
本文将带你全面了解如何使用DeepEval构建端到端的RAG评估体系,读完你将能够:
- 自动生成高质量的测试数据,摆脱手动标注的繁琐
- 从检索到生成,全面评估RAG系统的每个组件
- 通过CI/CD集成实现持续评估,确保系统长期可靠
- 优化检索器和生成器的关键参数,显著提升系统性能
RAG系统评估的核心挑战
RAG系统的性能评估远比传统软件复杂,主要面临三大挑战:首先,缺乏高质量的测试数据,手动创建问题-答案对既耗时又昂贵;其次,评估维度多样,需要同时关注检索质量和生成质量;最后,系统动态变化,文档更新和模型迭代都可能导致性能波动。
DeepEval作为专门为LLM应用设计的评估框架,提供了全面的解决方案。它不仅包含多种开箱即用的评估指标,还能自动生成测试数据,实现持续评估。接下来,我们将从检索器评估开始,逐步构建完整的RAG评估流程。
检索器评估:RAG系统的基石
检索器是RAG系统的基础,如果检索到的上下文不相关或不完整,即使最先进的生成模型也难以产生高质量的回答。DeepEval提供了三个关键指标来评估检索器性能:
- Contextual Relevancy(上下文相关性):检索到的内容与查询的相关程度
- Contextual Recall(上下文召回率):检索到的内容覆盖所有相关信息的比例
- Contextual Precision(上下文精确率):检索到的内容中相关信息的比例
自动生成测试数据
评估检索器的首要问题是获取高质量的测试数据。DeepEval的Synthesizer模块可以从原始文档中自动生成问题-答案对(称为goldens),大大减少了手动标注的工作量。
from deepeval.synthesizer import Synthesizer
synthesizer = Synthesizer()
goldens = synthesizer.generate_goldens_from_docs(
document_paths=["document.txt"], chunk_size=500, chunk_overlap=50
)
这段代码会从document.txt中提取文本块,并生成相应的问题和答案。生成的goldens可以直接用于后续的评估。相关实现可以参考deepeval/synthesizer/目录下的代码。
评估检索器性能
有了测试数据,我们就可以开始评估检索器了。以下代码展示了如何使用DeepEval的三个检索指标来评估一个基于FAISS的简单检索器:
from deepeval.test_case import LLMTestCase
from deepeval.metrics import (
ContextualRelevancyMetric,
ContextualRecallMetric,
ContextualPrecisionMetric,
)
# 初始化评估指标
relevancy = ContextualRelevancyMetric()
recall = ContextualRecallMetric()
precision = ContextualPrecisionMetric()
# 评估每个测试用例
for golden in goldens:
retrieved_docs = retriever.retrieve(golden.input)
context_list = [doc.page_content for doc in retrieved_docs]
test_case = LLMTestCase(
input=golden.input,
actual_output=golden.expected_output,
expected_output=golden.expected_output,
retrieval_context=context_list
)
relevancy.measure(test_case)
recall.measure(test_case)
precision.measure(test_case)
print(f"问题: {golden.input}")
print(f"相关性分数: {relevancy.score}, 召回率: {recall.score}, 精确率: {precision.score}")
上述代码中,retriever是我们要评估的检索器实例。通过循环遍历每个golden,我们获取检索结果,构建测试用例,并使用三个指标进行评估。详细的指标实现可以在deepeval/metrics/目录中找到。
优化检索器性能
初始评估后,我们通常需要优化检索器的参数。以下是一个参数优化的示例,比较了不同分块大小、嵌入模型和向量存储对检索性能的影响:
# 示例配置
chunking_strategies = [500, 1024, 2048]
embedding_models = [
("OpenAIEmbeddings", OpenAIEmbeddings()),
("HuggingFaceEmbeddings", HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")),
]
retriever_models = [
("FAISS", FAISS),
("Chroma", Chroma)
]
# 迭代不同配置
for chunk_size in chunking_strategies:
for embedding_name, embedding_model in embedding_models:
for retriever_name, retriever_type in retriever_models:
print(f"评估配置: 分块大小={chunk_size}, 嵌入模型={embedding_name}, 检索器={retriever_name}")
# 初始化检索器
retriever = SimpleRetriever(
document_path="document.txt",
chunk_size=chunk_size,
chunk_overlap=50,
embedding_model=embedding_model,
vector_store_class=retriever_type
)
# 评估代码...
通过这种系统性的参数搜索,我们可以找到最适合特定数据集的配置。实验表明,使用HuggingFaceEmbeddings和FAISS,配合1024的分块大小,通常能获得较好的性能。
上图展示了DeepEval检索器评估的完整流程,从数据准备到参数优化,再到结果分析。
生成器评估:确保回答质量
检索到相关上下文后,生成器的任务是基于这些上下文生成准确、相关的回答。DeepEval提供了多个指标来评估生成器性能,关键指标包括:
- Faithfulness(忠实度):回答是否忠实于检索到的上下文,没有编造信息
- Answer Relevancy(回答相关性):回答是否紧扣问题,没有偏离主题
- GEval:通用评估指标,可以自定义评估标准,如回答的专业性、格式正确性等
生成器评估实践
以下代码展示了如何使用DeepEval评估生成器的性能:
from deepeval.metrics import FaithfulnessMetric, AnswerRelevancyMetric, GEval
from deepeval.test_case import LLMTestCase, LLMTestCaseParams
# 硬编码查询和预期答案
query = "兼职员工有哪些福利?"
expected_answer = "兼职员工享受按比例的健康保障、灵活的带薪休假,并有资格获得健康补贴。"
# 运行RAG流程
retrieved_docs = retriever.retrieve(query)
context = [doc.page_content for doc in retrieved_docs]
generated_answer = generator.generate(query)
# 创建测试用例
test_case = LLMTestCase(
input=query,
actual_output=generated_answer,
expected_output=expected_answer,
retrieval_context=context,
)
# 初始化指标
metrics = [
FaithfulnessMetric(),
AnswerRelevancyMetric(),
GEval(
name="Tone",
criteria="回答是否专业?",
evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT],
strict_mode=True,
),
GEval(
name="Citations",
criteria="回答是否引用或参考了源文档?",
evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT, LLMTestCaseParams.CONTEXT],
strict_mode=True,
),
]
# 评估
for metric in metrics:
metric.measure(test_case)
print(f"{metric.name}: {metric.score} | {metric.reason}")
这段代码评估了生成回答的忠实度、相关性、专业性和引用质量。通过自定义GEval指标,我们可以灵活地评估几乎任何维度的生成质量。详细的指标定义和实现可以在deepeval/metrics/目录中找到。
生成器优化策略
生成器的性能受多个因素影响,包括模型选择、提示词设计、上下文窗口大小等。以下是一个优化示例,比较了不同提示词模板和模型对生成质量的影响:
# 提示词模板变体
prompts = [
"你是一名HR助理。仅使用提供的文档回答问题。\n\n{context}\n\n问题: {query}\n回答:",
"仅使用以下内部政策回答问题。\n\n{context}\n\n问题: {query}\n回答(需引用来源):",
"提供完整、有法律依据的回答,引用以下文档中的内容。\n\n{context}\n\n客户问题: {query}\n回答:",
]
# 模型变体
models = [
("ollama", Ollama(model="llama3")),
("openai", OpenAI(model_name="gpt-4")),
("huggingface", HuggingFaceHub(repo_id="google/flan-t5-large")),
]
# 评估不同组合
for i, prompt_template in enumerate(prompts, 1):
for model_name, model in models:
print(f"提示词变体 {i} | 模型: {model_name}")
generator = Generator(
retriever=retriever,
llm=model,
prompt_template=prompt_template
)
generated_answer = generator.generate(query)
# 评估代码...
实验表明,明确要求引用来源并使用更专业的提示词模板,配合GPT-4等高性能模型,通常能获得更高的忠实度和相关性分数。
持续评估:CI/CD集成
构建可靠的RAG系统不仅需要初始评估,还需要持续监控性能变化。通过将DeepEval测试集成到CI/CD流程中,可以在每次代码或文档更新时自动运行评估,及时发现性能退化。
动态生成测试数据
法律合同和公司政策是动态变化的,静态的测试数据很快会过时。DeepEval支持在CI过程中动态生成测试数据,确保评估始终基于最新文档:
# 动态生成测试数据
synthesizer = Synthesizer()
goldens = synthesizer.generate_goldens_from_docs(
document_paths=["document.txt"], chunk_size=1024, chunk_overlap=50
)
dataset = EvaluationDataset(goldens=goldens)
# 创建测试用例
for golden in goldens:
query = golden.input
expected_answer = golden.expected_output
# 检索相关文档
retrieved_docs = retriever_instance.retrieve(query)
context_list = [doc.page_content for doc in retrieved_docs]
# 生成回答
generated_answer = generator_instance.generate(query)
dataset.add_test_case(
LLMTestCase(
input=query,
actual_output=generated_answer,
expected_output=expected_answer,
retrieval_context=context_list,
)
)
定义评估指标和阈值
在CI流程中,我们需要明确定义评估指标和通过阈值,确保系统性能符合要求:
# 定义带阈值的指标
metrics = [
FaithfulnessMetric(threshold=0.7),
AnswerRelevancyMetric(threshold=0.7),
ContextualRelevancyMetric(threshold=0.7),
GEval(
name="Professional Tone Check",
criteria="回答是否专业,适合法律环境?",
evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT],
strict_mode=True,
threshold=0.8,
),
]
# 使用pytest参数化运行测试
@pytest.mark.parametrize("test_case", dataset.test_cases)
def test_rag_application_performance(test_case: LLMTestCase):
assert_test(test_case, metrics)
GitHub Actions配置
最后,我们需要配置CI流程,在每次代码推送时自动运行评估测试。以下是GitHub Actions的配置示例:
name: RAG DeepEval Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python3 -
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install Dependencies
run: poetry install --no-root
- name: Run DeepEval Unit Tests
run: poetry run deepeval test run test_rag_app.py
通过这种配置,每次代码提交都会自动运行DeepEval测试,如果任何指标未达到阈值,CI流程将失败,防止低质量的代码合并到主分支。完整的CI/CD集成指南可以参考docs/evaluation-unit-testing.mdx。
总结与最佳实践
使用DeepEval构建RAG评估系统的核心步骤包括:
- 自动生成测试数据:利用Synthesizer从文档中生成高质量的问题-答案对,减少手动工作
- 检索器优化:通过系统评估不同分块策略、嵌入模型和向量存储,找到最佳配置
- 生成器评估:关注忠实度和相关性等关键指标,优化提示词和模型选择
- 持续评估:通过CI/CD集成,实现文档和代码变更时的自动评估
实验数据表明,经过系统优化后,RAG系统的关键指标可以得到显著提升:
| 指标 | 初始检索器 | 优化后检索器 |
|---|---|---|
| 相关性 | 0.52 | 0.82 |
| 召回率 | 0.75 | 0.92 |
| 精确率 | 0.64 | 0.89 |
这些改进直接转化为更准确、更可靠的RAG系统,显著降低业务风险。
DeepEval作为一个全面的LLM评估框架,不仅支持RAG系统评估,还提供了对话系统、智能体等多种LLM应用的评估能力。通过官方文档和示例代码,你可以进一步探索DeepEval的强大功能,构建更可靠的AI系统。
记住,评估不是一次性任务,而是持续的过程。随着文档的更新和模型的迭代,定期重新评估和优化RAG系统,才能确保其长期可靠地服务于业务需求。
要开始使用DeepEval,只需克隆仓库并按照快速入门指南进行设置:
git clone https://gitcode.com/GitHub_Trending/de/deepeval
cd deepeval
poetry install
立即开始构建更可靠的RAG系统,让AI真正成为业务的助力而非风险来源。
更多推荐

所有评论(0)