LLM评估体系中的DeepEval框架。你将学习DeepEval的评估指标设计、测试用例管理、自动化评估流程、与TruLens/RAGAS对比、CI集成,以及如何利用DeepEval构建系统化的LLM应用评估体系保障输出质量,适合AI测试工程师学习。
需要学习DeepEval评估框架,安全需要融入工程流程(DevSecOps),工程化能力是基础。本篇涵盖MLOps/LLMOps、模型部署、CI/CD、版本管理,帮助你实现AI工程化交付。
目录
可视化演示
展示DeepEval的评估流水线(数据集→LLM→指标评估→报告)与CI/CD集成,以及与TruLens/RAGAS的雷达图多维度对比,理解LLM应用系统化评估体系。
本节配有交互动效(进入视口后自动加载,约 3KB)。
DeepEval评估流水线 数据集(DS): 测试用例管理,含golden答案与边界用例 LLM推理生成输出,进入评估阶段(EVAL) 四维指标评估: FTH忠实/REL相关/PRC精确/REC召回 Pipeline: Dataset → LLM → Metrics(FTH+REL+PRC+REC) → Report → CI/CD
DeepEval框架架构与核心设计理念
DeepEval采用pytest插件架构将LLM评估融入Python测试体系。就像给工厂生产线装上了自动质检机器人,每个产品出厂前自动检测是否合格,不合格直接拦截。DeepEval的核心设计理念是将LLM评估用例化,使评估像单元测试一样可自动执行、可版本管理和可集成CI流水线。团队开发了一个法律咨询RAG应用,每次更新检索策略后都需要人工抽检100条问答验证质量,耗时三天且标准不统一,回归缺陷频发——DeepEval正好解决RAG应用评估的自动化和标准化问题。
DeepEval将LLM评估封装为可复用的测试用例,支持参数化和数据驱动。每个评估用例包含输入、实际输出、期望输出和上下文等字段,通过断言(assert)语法评估指标是否达标。测试用例可以参数化——同一个评估逻辑用不同数据运行多次,也可以数据驱动——从CSV或JSON文件批量加载测试数据。这种设计使评估用例可以像代码一样版本管理,团队可以追踪评估标准的变化历史。
DeepEval提供命令行工具和Web仪表盘双模式查看评估结果和趋势。命令行工具通过pytest命令运行评估,输出结果摘要和详细报告。Confident平台(DeepEval的云端服务)提供Web仪表盘,可视化展示评估结果的趋势变化、历史对比和回归分析。团队可以设置评估阈值,当指标低于阈值时CI流水线自动阻断部署,确保质量回归被及时发现。
from deepeval import evaluatefrom deepeval.test_case import LLMTestCasefrom deepeval.metrics import FaithfulnessMetric test_case = LLMTestCase( input="What is the statute of limitations for contract disputes?", actual_output="The statute of limitations is 6 years.", expected_output="The statute of limitations for contract disputes is 6 years under UCC.", retrieval_context=["UCC Section 2-725: An action for breach must be commenced within 6 years."])metric = FaithfulnessMetric(threshold=0.7)evaluate([test_case], [metric])
评估指标体系与自定义指标开发
DeepEval内置指标覆盖忠实度、答案相关性和上下文召回率等RAG核心维度。好比体检报告的各项指标,血压、血糖、肝功能各有标准,DeepEval的指标体系就是LLM应用的体检报告。忠实度(Faithfulness)衡量生成答案是否忠于检索到的上下文,不编造信息。答案相关性(Answer Relevancy)衡量答案是否直接回答了用户问题。上下文召回率(Contextual Recall)衡量检索是否找全了回答问题所需的上下文。
自定义指标继承Metric基类实现measure方法和score属性。内置指标主要针对RAG场景设计,对于对话、代码生成等场景需要开发自定义指标。自定义指标通过继承Metric基类,实现measure方法(执行评估逻辑并计算分数)和score属性(返回评估结果)。自定义指标可结合LLM-as-Judge(用LLM评估LLM输出)和确定性规则(如正则匹配、关键词检查)两种评估模式的混合使用,兼顾灵活性和确定性。
指标支持LLM-as-Judge和确定性规则两种评估模式的混合使用。LLM-as-Judge模式用另一个LLM评估输出质量,适合评估主观维度如流畅度、有用性,但成本高且有不确定性。确定性规则模式用代码规则检查如关键词存在、格式正确、长度限制等,成本低结果确定但覆盖面有限。混合模式先用规则快速过滤明显问题,再用LLM-as-Judge精细评估剩余用例,兼顾成本和质量。
from deepeval.metrics import BaseMetricfrom deepeval.test_case import LLMTestCase class CitationAccuracyMetric(BaseMetric): def __init__(self, threshold=0.8): self.threshold = threshold self.score = 0.0 def measure(self, test_case): citations = test_case.expected_output.split('; ') actual = test_case.actual_output correct = sum(1 for c in citations if c.strip() in actual) self.score = correct / len(citations) if citations else 0.0 self.success = self.score >= self.threshold return self.score async def a_measure(self, test_case): return self.measure(test_case) def is_successful(self): return self.success @property def __name__(self): return "Citation Accuracy" tc = LLMTestCase(input="q", actual_output="See Art.1; Art.3", expected_output="Art.1; Art.3; Art.5", retrieval_context=[])m = CitationAccuracyMetric(threshold=0.7)score = m.measure(tc)print(f"Citation Accuracy: {score:.2f}, Pass: {m.is_successful()}")
测试用例管理与数据集构建
DeepEval使用LLMTestCase类封装输入、实际输出、期望输出和上下文等字段。如同考试题库管理,按知识点分类存储题目,每次考试从中抽取相应题目组卷,还可以自动生成新题补充。LLMTestCase包含input(用户输入)、actual_output(LLM实际输出)、expected_output(期望输出)、retrieval_context(检索到的上下文)和context(生成上下文)等字段,完整封装了一个评估用例的所有信息。
支持从CSV和JSON文件批量导入测试用例实现数据集快速构建。测试数据集可以按场景分组(如法律咨询、客服对话、代码生成),每组包含相关的测试用例。数据集文件可以版本管理,团队可以追踪测试数据的变更历史。从CSV导入时每行一个测试用例,列对应LLMTestCase的字段。从JSON导入支持更复杂的嵌套结构如retrieval_context列表。批量导入使团队能快速构建数百条测试用例覆盖各种场景。
合成数据生成器利用LLM自动生成边缘场景用例补充测试覆盖。人工编写测试用例容易遗漏边缘场景(如极端长输入、多语言混合、对抗性提示),合成数据生成器通过LLM自动生成这些难以预见的测试用例。生成器可以指定生成策略(如生成对抗性用例、生成特定主题用例、生成边界值用例),并自动过滤低质量生成结果。团队为客服RAG应用构建DeepEval评估套件,包含200条测试用例覆盖忠实度、答案相关性和上下文召回率三个指标,集成到GitHub Actions中每次PR自动运行。
from deepeval.test_case import LLMTestCasefrom deepeval.dataset import EvaluationDataset dataset = EvaluationDataset()cases = [ LLMTestCase(input="合同纠纷诉讼时效?", actual_output="6年", expected_output="根据UCC第2-725条,合同纠纷诉讼时效为6年", retrieval_context=["UCC 2-725: 6年时效"]), LLMTestCase(input="侵权诉讼时效?", actual_output="2年", expected_output="根据民法典第188条,侵权诉讼时效为3年", retrieval_context=["民法典188条: 3年时效"])]for tc in cases: dataset.add_test_case(tc)print(f"Dataset size: {len(dataset.test_cases)}")for i, tc in enumerate(dataset.test_cases): print(f" Case {i+1}: {tc.input} -> {tc.actual_output}")
自动化评估流程与CI/CD集成
DeepEval通过pytest命令行集成CI/CD流水线,支持评估阈值门控和失败阻断部署。pytest命令行集成使评估自动嵌入GitHub Actions等CI流水线——每次代码提交或PR创建时自动运行评估用例。评估阈值门控在指标低于设定值时自动阻断部署流程,如忠实度低于0.85时阻断合并。团队为客服RAG应用构建评估套件集成到GitHub Actions中,每次PR自动运行,当忠实度低于0.85时自动阻断合并,上线后回归缺陷发现率提升60%。
评估结果可上传Confident平台进行趋势追踪和回归分析。Confident平台提供Web仪表盘可视化展示评估结果的趋势变化——指标随时间的变化曲线、不同版本的对比、回归用例的详细分析。团队可以设置告警阈值,当指标恶化时自动通知。趋势追踪帮助团队理解模型迭代对质量的影响,回归分析帮助定位哪次变更导致了质量退化。
CI/CD集成中的质量门控策略需要平衡严格性和开发效率。过严的门控(如所有指标阈值都很高)会导致频繁阻断开发流程,过松的门控则无法有效拦截质量回归。实践中通常分级设置门控:核心指标(如忠实度)设高阈值严格门控,次要指标(如答案相关性)设中等阈值,辅助指标(如响应格式)设低阈值只警告不阻断。这种分级策略既保护核心质量又不过度阻碍开发效率。
DeepEval与TruLens及RAGAS对比
DeepEval侧重测试框架化与CI集成,TruLens侧重生产环境实时监控与追踪,RAGAS专注RAG管道评估指标设计,三者各有侧重可组合使用。DeepEval优势在pytest集成和CI门控适合开发阶段回归测试。TruLens优势在生产实时追踪和Token级别成本监控适合运维。RAGAS优势在RAG专项指标设计如忠实度和上下文利用率评估。实际项目中常需组合使用而非相互替代。
DeepEval与TruLens的定位差异体现在使用场景上。DeepEval是开发阶段的测试框架,在CI流水线中运行批量评估用例,关注功能质量回归。TruLens是生产环境的监控工具,实时追踪每次LLM调用的质量指标和成本,关注线上质量波动。一个完整的LLM应用质量保障体系应该同时使用两者:开发阶段用DeepEval做回归测试,上线后用TruLens做实时监控。两者数据可以打通形成从开发到生产的全链路质量追踪。
RAGAS在RAG专项指标设计上有独特优势。RAGAS的忠实度指标将答案分解为独立声明再逐一验证是否忠于上下文,比DeepEval的忠实度计算更精细。RAGAS的上下文利用率指标衡量检索上下文中有多少信息被实际用于生成答案,帮助优化检索策略减少冗余。实际项目中可以用RAGAS的指标设计思路指导DeepEval自定义指标开发,将RAGAS的精细评估能力融入DeepEval的测试框架和CI集成流程中,形成互补的评估体系。
AI 应用场景
RAG应用质量持续评估门控
阶段:监控运维
解决的问题:RAG应用在检索策略或生成模型迭代时缺乏自动化质量验证手段,导致回归缺陷难以及时发现
具体案例:团队为客服RAG应用构建DeepEval评估套件,包含200条测试用例覆盖忠实度、答案相关性和上下文召回率三个指标,集成到GitHub Actions中每次PR自动运行,当忠实度低于0.85时自动阻断合并,上线后回归缺陷发现率提升60%。
Python 演示
import jsonfrom dataclasses import dataclass, fieldfrom typing import List, Optional @dataclassclass LLMTestCase: input: str actual_output: str expected_output: str = "" retrieval_context: List[str] = field(default_factory=list) class BaseMetric: def __init__(self, threshold=0.7): self.threshold = threshold self.score = 0.0 self.success = False def measure(self, test_case): raise NotImplementedError def is_successful(self): return self.success @property def __name__(self): return self.__class__.__name__ class FaithfulnessMetric(BaseMetric): def measure(self, test_case): if not test_case.retrieval_context: self.score = 0.0 self.success = False return self.score context = ' '.join(test_case.retrieval_context).lower() output_words = set(test_case.actual_output.lower().split()) context_words = set(context.split()) supported = len(output_words & context_words) total = len(output_words) self.score = supported / total if total > 0 else 0.0 self.success = self.score >= self.threshold return self.score class AnswerRelevancyMetric(BaseMetric): def measure(self, test_case): input_words = set(test_case.input.lower().replace('?', '').split()) output_words = set(test_case.actual_output.lower().split()) overlap = len(input_words & output_words) self.score = overlap / len(input_words) if input_words else 0.0 self.success = self.score >= self.threshold return self.score class EvaluationDataset: def __init__(self): self.test_cases = [] def add_test_case(self, test_case): self.test_cases.append(test_case) def evaluate(self, metrics): results = [] for tc in self.test_cases: case_results = {} for metric in metrics: score = metric.measure(tc) case_results[metric.__name__] = { 'score': round(score, 4), 'passed': metric.is_successful() } results.append(case_results) return results class CIGate: def __init__(self, thresholds): self.thresholds = thresholds def check(self, dataset_results): all_passed = True for i, result in enumerate(dataset_results): for metric_name, data in result.items(): if not data['passed']: print(f" FAIL: Case {i+1} {metric_name} score={data['score']} < threshold") all_passed = False return all_passed tc1 = LLMTestCase(input="合同纠纷诉讼时效", actual_output="合同纠纷诉讼时效为6年根据UCC", expected_output="6年", retrieval_context=["UCC第2-725条规定合同纠纷诉讼时效为6年"])tc2 = LLMTestCase(input="侵权诉讼时效", actual_output="侵权诉讼时效为3年", expected_output="3年", retrieval_context=["民法典第188条规定侵权诉讼时效为3年"])tc3 = LLMTestCase(input="商标注册有效期", actual_output="商标注册有效期为10年可续展", expected_output="10年", retrieval_context=["商标法规定注册有效期为10年"])dataset = EvaluationDataset()for tc in [tc1, tc2, tc3]: dataset.add_test_case(tc)metrics = [FaithfulnessMetric(threshold=0.5), AnswerRelevancyMetric(threshold=0.3)]results = dataset.evaluate(metrics)for i, result in enumerate(results): print(f"Case {i+1}: {result}")gate = CIGate(thresholds={'FaithfulnessMetric': 0.5, 'AnswerRelevancyMetric': 0.3})passed = gate.check(results)print(f"\nCI Gate: {'PASSED' if passed else 'FAILED - blocking deployment'}")
@dataclass使用dataclass装饰器简化LLMTestCase的数据类定义,自动生成init等方法class LLMTestCase:LLMTestCase封装评估用例的输入、实际输出、期望输出和检索上下文等字段retrieval_context: List[str] = field(default_factory=list)retrieval_context是检索到的上下文列表,用于忠实度评估时验证答案是否忠于上下文class BaseMetric:指标基类,定义measure方法和is_successful接口供自定义指标继承def measure(self, test_case):measure方法执行评估逻辑计算分数,子类必须实现此方法class FaithfulnessMetric(BaseMetric):忠实度指标:衡量生成答案中的词汇有多少能在检索上下文中找到支持supported = len(output_words & context_words)计算输出词汇与上下文词汇的交集大小,即被上下文支持的词汇数self.score = supported / total if total > 0 else 0.0忠实度分数=被支持词汇数/输出总词汇数,分数越高说明答案越忠于上下文class AnswerRelevancyMetric(BaseMetric):答案相关性指标:衡量答案中的词汇与问题词汇的重叠程度class EvaluationDataset:评估数据集类,管理多个测试用例并批量运行指标评估def evaluate(self, metrics):对数据集中所有测试用例运行所有指标,返回每个用例的评估结果class CIGate:CI门控类,检查评估结果是否全部通过阈值,不通过则阻断部署all_passed = True默认所有用例通过,发现任一指标未达标则标记为Falsepassed = gate.check(results)运行CI门控检查,根据结果决定是否允许部署
常见问答
DeepEval的内置指标可以直接用于所有LLM应用场景吗?
DeepEval评估通过就说明LLM应用可以安全上线吗?
DeepEval可以完全替代TruLens和RAGAS吗?
DeepEval如何集成到CI/CD流水线中?
LLM-as-Judge和确定性规则两种评估模式有什么区别?
常见误区
误区DeepEval的内置指标可以直接用于所有LLM应用场景
正解内置指标主要针对RAG场景设计,对于对话、代码生成等场景需要开发自定义指标,直接套用内置指标可能导致评估结果与业务目标脱节
为何常见:DeepEval提供开箱即用的指标容易让人误以为这些指标适用于所有LLM应用类型
误区DeepEval评估通过就说明LLM应用可以安全上线
正解DeepEval评估覆盖的是功能质量维度,不包含安全性和隐私合规等维度,上线前还需进行红队测试和合规审查等补充评估
为何常见:CI门控通过给人一种质量已验证的安全感,容易忽略评估框架覆盖范围的局限性
误区DeepEval可以完全替代TruLens和RAGAS
正解三者的侧重点不同,DeepEval擅长开发阶段测试,TruLens擅长生产监控,RAGAS擅长RAG指标设计,实际项目中常需组合使用而非相互替代
为何常见:DeepEval功能全面且生态活跃,容易让人误以为一个工具可以覆盖所有评估需求
参考来源
- docDeepEval DocumentationDeepEval官方文档,涵盖框架架构、指标体系、测试用例管理和CI/CD集成
- webpageDeepEval GitHub RepositoryDeepEval开源仓库,包含源代码、示例和社区讨论
- paperRAGAS: Automated Evaluation of Retrieval Augmented GenerationRAGAS论文,描述RAG评估指标设计方法,可与DeepEval对比参考