DeepEval 怎么评估 RAG 应用的检索器与生成器两个组件
【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval
RAG 应用的答案质量差时,一个端到端分数没法告诉你:坏答案是因为检索回来的上下文不对,还是因为生成器没用好上下文。DeepEval 的组件级评估(component-level evaluation,也叫 step-wise evals)解决这个问题——它给@observe过的检索器和生成器函数各自的 span 上挂指标,把两个组件分开打分,测试单元仍然是LLMTestCase,但挂在单个 span 上而不是整条 trace 上。这条路径要求你能修改流水线代码(可加 tracing);如果你只是黑盒测试已部署系统,只能走端到端指标,做不了组件级分离。
为两个组件选哪些指标
DeepEval 提供 5 个 RAG 指标,按组件归属分为两组(见 RAG Evaluation 指南 与 RAG Evaluation Quickstart/getting-started-rag.mdx)):
| 组件 | 指标 | 评什么 | 测试用例额外需要的字段 |
|---|---|---|---|
| 检索器 | ContextualRelevancyMetric | 检索上下文对 input 的相关性(信噪比),对应 chunk 大小、top-K | input、actual_output、retrieval_context |
| 检索器 | ContextualPrecisionMetric | reranker 是否把相关节点排在无关节点之前 | 另需expected_output |
| 检索器 | ContextualRecallMetric | 检索结果是否覆盖期望答案所需信息 | 另需expected_output |
| 生成器 | AnswerRelevancyMetric | 回答相对 input 的相关性,对应 prompt 模板质量 | input、actual_output |
| 生成器 | FaithfulnessMetric | 回答是否与retrieval_context事实一致、不矛盾 | input、actual_output、retrieval_context |
指南的建议:检索器三个指标配合使用才能同时检查“取回的信息量、排序、信噪比”;如果你没有标注过的expected_output,可用无参考(referenceless)的三个指标AnswerRelevancyMetric+FaithfulnessMetric+ContextualRelevancyMetric(即 RAG triad)先跑起来。不确定某个指标是否适合你的场景时,可运行deepeval recommend metrics查询。
所有指标都是 LLM-as-a-judge 且自带解释:include_reason默认为True,会输出分数原因;threshold默认0.5,低于阈值判为不通过,设为None则只打分不判过。
准备环境
pip install -U deepeval[inspect][inspect]子模块是可选项,会增大包体积,文档建议只在开发环境带上它;生产环境安装deepeval即可。安装后执行:
deepeval logindeepeval login把本地运行接入 Confident AI 平台,用于保存、标注和共享结果。不登录也能本地评估——每次运行都会快照到磁盘,可用deepeval inspect查看(见下文“查看结果”)。
给检索器和生成器挂指标
用@observe(metrics=[...])分别包住检索器和生成器,函数内部用update_current_span(...)向当前 span 报告输入、输出或检索上下文。下面是 RAG Evaluation Quickstart/getting-started-rag.mdx) 中 “Evaluate Retriever & Generator” 一节的 Python 示例,代码里的["..."]与"..."处需要替换成你自己的检索逻辑和 LLM 调用:
from deepeval.dataset import EvaluationDataset, Golden from deepeval.tracing import observe, update_current_span from deepeval.metrics import ContextualRelevancyMetric, AnswerRelevancyMetric @observe(metrics=[ContextualRelevancyMetric()]) def retriever(query: str) -> list[str]: chunks = ["..."] # your retrieval logic here update_current_span(input=query, retrieval_context=chunks) return chunks @observe(metrics=[AnswerRelevancyMetric()]) def generator(query: str, chunks: list[str]) -> str: answer = "..." # your LLM call here update_current_span(input=query, output=answer) return answer @observe() def rag_pipeline(query: str) -> str: chunks = retriever(query) return generator(query, chunks)要点:
- 挂哪个指标由你决定:检索器 span 上放检索器指标,生成器 span 上放生成器指标。示例里检索器挂了
ContextualRelevancyMetric,生成器挂了AnswerRelevancyMetric。 - 如果要在生成器 span 上跑
FaithfulnessMetric(它同时需要actual_output和retrieval_context),按 Component-Level LLM Evaluation 的写法,把完整测试用例注册到 span 上:
@observe(metrics=[FaithfulnessMetric()]) def generate(query: str, chunks: list[str]) -> str: response = "..." # call your LLM here with `query` and `chunks` update_current_span( test_case=LLMTestCase(input=query, actual_output=response, retrieval_context=chunks), ) return response- 不想手写 tracing 的话,DeepEval 对 LangChain、LangGraph、LlamaIndex、Pydantic AI、CrewAI 等框架有原生集成,可以把组件指标挂到框架自动发出的 span 上,无需手动插桩。
- TypeScript 侧能力等价:
observe({ type: "retriever", metrics: [...] })/observe({ type: "llm", metrics: [...] })加updateCurrentSpan(...),再配合evalsIterator()循环。
准备数据集并运行评估
组件级运行和单轮端到端评估用的是同一套 iterator + tracing 结构,差别只在指标挂在哪里。用EvaluationDataset存放Golden(评估时的输入),循环调用流水线即可:
dataset = EvaluationDataset(goldens=[Golden(input="How do I reset my password?")]) for golden in dataset.evals_iterator(): rag_pipeline(golden.input)运行逻辑是:evals_iterator()打开一个 test run 并逐个产出 golden;每调用一次应用,产生一条 trace;trace 里挂了指标的 span 各自被当作一个测试用例打分,最后 trace、各 span 测试用例和分数一起上传为同一个 test run。evals_iterator()的可选参数中,metrics是 trace 级(端到端)指标——纯组件级运行留空即可,想同时要端到端总分就把指标传进去,trace 级与 span 级分数在同一个 test run 中共存。
查看结果与判断问题归属
本地查看用 trace-tree TUI:
deepeval inspect它会展示每条 trace 的 span 树,每个 span 上带分数和指标原因。执行deepeval login后,同样的 trace 和组件分数还会渲染到 Confident AI 的云端 UI,便于团队查看是哪个 span 挂了并跟踪变化。
分数低时,文档给出的判断方向(来自各指标页 FAQ):
ContextualRelevancyMetric低而答案本身切题:说明retrieval_context里无关内容太多,是检索器(chunk 大小 / top-K)的问题;- 上下文干净但回答跑题或不基于上下文:问题在生成器(prompt 或模型),对应
AnswerRelevancyMetric/FaithfulnessMetric低分。
调试单个用例时也可以脱离 test run 直接跑:
metric.measure(test_case) print(metric.score, metric.reason)文档提示这只适合调试或自建评估流程,拿不到evaluate()与deepeval test run提供的测试报告、缓存与并发等优化。
可选:在 CI/CD 中断言组件分数
把循环换成 pytest 测试即可在每次 push / PR 时跑同样的组件级评估,指标仍然挂在 span 上,断言只需要当前 golden(Component-Level LLM Evaluation 的 “In CI/CD” 一节):
import pytest from deepeval import assert_test from deepeval.dataset import Golden from your_app import my_ai_agent # traced; spans carry metrics @pytest.mark.parametrize("golden", dataset.goldens) def test_my_ai_agent(golden: Golden): my_ai_agent(golden.input) assert_test(golden=golden)deepeval test run test_my_ai_agent.py指标分数不达标时测试失败,构建随之失败。
限制与注意
- 组件级评估目前仅支持单轮(single-turn),多轮组件级评估在 roadmap 上;多轮 RAG 需要改用
TurnFaithfulnessMetric、TurnContextualRelevancyMetric等指标,属于另一条路径。 ContextualPrecisionMetric和ContextualRecallMetric必须提供expected_output,没有标注数据的场景只能跑其余三个无参考指标。- 组件级评估要求你能给流水线加 tracing(手动
@observe或用框架集成);完全黑盒的系统只能做端到端评估,无法分离检索器与生成器的分数。 - 需要对比不同超参(chunk 大小、top-K、embedding 模型、LLM、prompt 模板)的效果时,可用
@deepeval.log_hyperparameters把配置值记录到每次 test run,在 Confident AI 上按配置对比分数。
相关文档:RAG Evaluation Quickstart/getting-started-rag.mdx)、Component-Level LLM Evaluation、RAG Evaluation 指南、Contextual Relevancy/metrics-contextual-relevancy.mdx)、Faithfulness/metrics-faithfulness.mdx)、Answer Relevancy/metrics-answer-relevancy.mdx)、Contextual Precision/metrics-contextual-precision.mdx)、Contextual Recall/metrics-contextual-recall.mdx)。
【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考