DeepEval+Ragas自动化评测部署实战:从安装到CI/CD全流程配置
一、开篇:为什么需要DeepEval+Ragas双框架评测
我们花 10 分钟讲清楚一件事:为什么单靠一个评测框架,RAG 项目会在研究阶段和生产阶段之间掉链子。读完本节,你会明确 Ragas 与 DeepEval 各自管什么、什么时候该用谁,以及我们推荐的双框架落地顺序。这套组合已经经过我们多个 RAG 项目从 0 到 1 的验证,结论先说:两者不是替代关系,而是接力关系。
- 用 Ragas 做 RAG 核心质量摸底(faithfulness、answer relevancy、context precision),快速定位知识库与生成策略问题
- 用 DeepEval 做工程化测试:pytest 集成、阈值门禁、CI/CD 发布拦截
- 研究阶段用 Ragas 探索诊断,上线前用 DeepEval 卡点拦截,双框架接力覆盖全链路
- 把 DeepEval 的失败用例接入 Confident AI 或本地报告,让线上 trace 持续反哺评测集
Ragas 的定位非常清晰:它是 RAG 系统的体检工具,专注核心质量指标。我们用它跑 faithfulness、answer relevancy、context precision 这类指标,一轮离线实验几分钟就能出分。它的工作方式类似 pandas 做数据分析——轻量、快速、适合在 Jupyter 里反复迭代。代价是它本身不提供发布门禁,你得到的分数不会自动阻止一个坏版本上线。
DeepEval 的设计目标完全不同:它面向工程工作流,提供 40 余个可插拔指标、一流的 pytest 集成和阈值拦截能力。我们把评测写成测试用例,低于阈值直接抛 AssertionError,CI 流水线就会拦住这次发布。它还原生对接 Confident AI 平台,支持 A/B 回归测试、可共享的测试报告,以及把线上失败的 trace 变成下一批评测用例。它的短板是 RAG 专项指标的专注度不如 Ragas,研究探索阶段的灵活性也弱一些。
所以我们的结论是双框架接力:Ragas 负责研究探索阶段的质量诊断,DeepEval 负责生产落地阶段的工程卡点。典型流程是先用 Ragas 在离线数据集上摸底、调优检索与生成策略,达到预期后再把核心指标迁移到 DeepEval 的测试套件里。这样研究阶段的洞察不会丢失,生产阶段的发布又有硬性门禁。我们不推荐二选一,因为单框架方案会在探索和落地两个环节各留下一个盲区。
# 阶段一:Ragas 离线摸底(研究探索)
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy
result = evaluate(dataset, metrics=[faithfulness, answer_relevancy])
print(result)
# 输出示例: {'faithfulness': 0.82, 'answer_relevancy': 0.75}
# 用途:定位知识库覆盖不足或生成漂移问题,不拦截任何发布
# 阶段二:DeepEval 工程卡点(CI 集成)
from deepeval import assert_test
from deepeval.test_case import LLMTestCase
from deepeval.metrics import FaithfulnessMetric
test_case = LLMTestCase(
input="公司的报销流程是什么?",
actual_output="员工需在每月 5 日前提交发票...",
retrieval_context=["报销制度第三章:发票提交截止日期为每月 5 日"]
)
metric = FaithfulnessMetric(threshold=0.7)
assert_test(test_case, [metric])
# 行为:actual_output 与 retrieval_context 一致性 ≥ 0.7 则通过;
# 低于 0.7 抛出 AssertionError,CI 流水线直接拦截该版本发布
| 方案 | 优势 | 代价 | 适用场景 |
|---|---|---|---|
| 仅 Ragas | RAG 核心指标开箱即用,离线迭代快 | 无原生 CI 门禁,发布拦截需自建 | 研究探索、论文级质量摸底 |
| 仅 DeepEval | pytest 原生集成,阈值拦截与回归测试完善 | RAG 专项指标专注度不及 Ragas | 生产发布卡点、回归测试 |
| Ragas + DeepEval 双框架 | 研究到生产全链路覆盖,指标互补 | 需维护两套脚本并对齐指标口径 | RAG 项目从 0 到 1 再到规模化 |
tags), each with at least 3 sentences 4. At least 1 code block (
...) with input example and output explanation
5. At least 1 comparison table (| 方案 | 优势 | 代价 | 适用场景 |
|---|---|---|---|
| venv(标准库) | 无需额外安装,Python自带 | 功能简单,缺少依赖锁定 | 个人快速验证 |
| conda | 支持非Python依赖管理 | 体积庞大,占用磁盘多 | 数据科学混合环境 |
| poetry | 依赖锁定与发布一体化 | 学习成本较高 | 团队协作项目 |
| pip + requirements.txt | 简单直接,CI集成方便 | 需手动维护版本 | 轻量级自动化流水线 |
我们推荐使用venv配合requirements.txt的方案起步,这个组合学习成本最低且能覆盖90%的评测场景。我们下一步应该执行python -m pip freeze > requirements.txt来锁定当前环境依赖,然后将该文件提交到版本仓库,确保团队其他成员能够一键复现相同的评测环境。
三、DeepEval安装与基础配置
我们通过 pip install deepeval 这一条命令就能完成核心安装,整个过程不需要额外配置复杂的运行时环境。安装完成后我们在终端执行 pip show deepeval 验证版本号,确认包体已经正确进入当前 Python 环境。我们建议在项目根目录使用虚拟环境隔离依赖,避免与现有测试框架的包版本发生冲突。
DeepEval 最打动我们的设计是它对 pytest 的原生支持,我们完全可以把 LLM 评测写成标准的单元测试用例。我们用 assert_test 函数传入测试用例与指标列表,断言失败时 pytest 会像普通测试一样抛出清晰的错误信息。我们在 CI 流水线里直接运行 pytest 命令,就能把答案相关性、忠实度这些指标变成部署前的门禁条件。
在指标层面,DeepEval 采用可插拔的模块化设计,我们按需引入 AnswerRelevancyMetric、FaithfulnessMetric、G-Eval 等 40 余个内置指标。每个指标都可以独立设置阈值、模型与采样参数,我们由此拼装出适合自己业务的评测流水线。我们还可以继承 Metric 接口编写自定义规则,把业务特有的校验逻辑无缝接入既有测试套件。
# test_deepeval.py(输入示例)
from deepeval import assert_test
from deepeval.test_case import LLMTestCase
from deepeval.metrics import AnswerRelevancyMetric
metric = AnswerRelevancyMetric(threshold=0.7)
test_case = LLMTestCase(
input="DeepEval 怎么安装?",
actual_output="执行 pip install deepeval 即可完成安装。",
retrieval_context=["DeepEval 支持通过 pip 安装。"]
)
assert_test(test_case, [metric])
# 终端运行命令
# pytest test_deepeval.py -v
# 预期输出说明
# test_deepeval.py::test_answer_relevancy PASSED
# 当指标得分高于阈值 0.7 时用例显示 PASSED;
# 低于阈值时 pytest 报 FAILED,并在错误详情中
# 列出指标名称、实际得分与阈值,方便我们直接定位问题。
| 方案 | 优势 | 代价 | 适用场景 |
|---|---|---|---|
| DeepEval 本地 pytest 模式 | 零外部依赖,评测即单元测试,CI 集成简单 | 需要自行管理指标模型调用与结果存储 | 中小团队快速搭建评测门禁 |
| DeepEval + Confident AI 平台 | 自带可分享测试报告、A/B 回归对比与生产追踪回灌 | 需要注册云端服务并维护 API 配置 | 需要向干系人汇报评测结果的生产团队 |
| Ragas 独立脚本模式 | 轻量专注 RAG 核心质量指标,上手快 | 缺少 pytest 原生集成与自定义规则扩展能力 | 一次性实验评估与离线分析 |
我们推荐新项目直接采用 DeepEval 本地 pytest 模式起步,先把答案相关性与忠实度两个指标接入现有测试套件。我们的下一步行动是:在本周内完成 pip install deepeval 与虚拟环境搭建,写出第一个可运行的评测用例,并将其加入 CI 的 pytest 执行命令中。当用例稳定通过后,我们再评估是否接入 Confident AI 平台以获取可分享的测试报告。
四、Ragas安装与RAG指标配置
我们安装 Ragas 的方式非常直接,在项目虚拟环境中执行 pip install ragas 即可拉取核心评测包。安装完成后,我们建议同时确认 OpenAI 或本地模型的 API Key 已正确配置,因为 Ragas 的多数指标底层依赖 LLM 打分。我们把 Ragas 定位为 RAG 系统的"体检工具",它的核心职责是围绕检索增强生成链路给出可量化的质量分数。
在指标配置环节,我们重点使用 faithfulness(忠实度)与 answer relevancy(答案相关性)这两项核心指标。faithfulness 衡量生成答案是否完全基于检索到的上下文,帮助我们识别幻觉问题;answer relevancy 则检查答案与用户原始问题的匹配程度。我们还可以按需引入 context precision、context recall 等指标,构建覆盖检索与生成双环节的完整评估矩阵。
Ragas 与 LangChain、ChromaDB 等主流框架的集成十分顺畅,我们无需改造现有 RAG 管线即可接入评测。我们只需把 LangChain 的检索结果与最终答案整理成标准的 dataset 格式,Ragas 就能直接消费这些数据完成打分。这种设计让我们在原型验证阶段快速迭代,在生产环境持续监控 RAG 质量变化。
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy
from datasets import Dataset
# 输入示例:构造评测数据集
data = {
"question": ["公司年假政策是什么?"],
"answer": ["员工入职满一年后可享受5天年假。"],
"contexts": [["员工入职满一年享受5天年假,满十年享受15天。"]],
"ground_truth": ["入职满一年5天年假,满十年15天年假"]
}
dataset = Dataset.from_dict(data)
# 执行评测
result = evaluate(dataset, metrics=[faithfulness, answer_relevancy])
print(result)
# 输出示例:{'faithfulness': 0.95, 'answer_relevancy': 0.88}
# 输出说明:faithfulness 得分 0.95 表示答案与检索上下文高度一致,
# answer_relevancy 得分 0.88 表示答案紧扣原始问题,两项均高于 0.8 的常用验收阈值。
| 指标配置方案 | 优势 | 代价 | 适用场景 |
|---|---|---|---|
| 仅 faithfulness | 专注幻觉检测,接入成本最低 | 无法发现答非所问问题 | 生成内容准确性优先的场景 |
| faithfulness + answer relevancy | 覆盖事实性与相关性两个维度 | LLM 调用次数增加,评测成本上升 | 通用 RAG 系统的日常体检 |
| 全量指标(含 context precision/recall) | 评估覆盖检索与生成全链路 | 数据标注要求高,执行耗时最长 | 上线前深度验收与回归测试 |
我们推荐在项目初期采用 faithfulness 加 answer relevancy 的双指标组合起步,既控制评测成本又抓住核心质量风险。等 RAG 管线稳定后,我们再把 context precision 与 context recall 纳入评估范围,形成完整的链路监控。下一步我们建议把 Ragas 评测脚本接入 CI 流程,每次 Prompt 或检索策略变更后自动跑分,用分数趋势替代主观感觉。
五、评测数据集与测试用例构建
评测数据集是一切自动化评测的地基,我们首先要做的就是整理 question-context-answer 三元组。question 来自真实用户提问或业务 FAQ,context 是检索系统实际返回的文档片段,answer 是我们期望的标准回复。三元组的质量直接决定评测结果的可信度,因此我们在构建时必须确保 context 与 question 真实相关、answer 与 context 严格一致。
在工具层面,DeepEval 支持我们导入自定义测试数据集,并把经过人工确认的高质量样本标记为黄金样本。这些黄金样本在 CI/CD 流水线中充当回归基线,每次 Prompt 调整或模型升级后都会重新执行一遍。我们通过 pytest 集成就能把评测变成像单元测试一样自动运行的环节,任何指标跌破阈值都会直接阻断发布。
当真实问题积累不足时,Ragas 的合成数据生成能力可以帮我们快速扩展评测覆盖。它基于知识库文档自动派生出新的问答对,专门补齐人工样本没有覆盖到的长尾场景。我们对合成数据会做人工抽检,确认无误后才纳入正式评测集,避免错误样本污染评测结论。
# 我们用 Python 构造 question-context-answer 三元组评测数据集
eval_dataset = [
{
"question": "员工年假天数如何计算?",
"context": "员工手册第三章:入职满1年享5天年假,满10年享15天。",
"answer": "入职满1年5天,满10年15天。"
},
{
"question": "报销流程是什么?",
"context": "财务制度第五章:3000元以下部门审批,以上需财务总监签字。",
"answer": "3000元以下部门审批,以上需财务总监签字。"
}
]
for case in eval_dataset:
print(case["question"], "→", case["answer"])
# 输出:
# 员工年假天数如何计算? → 入职满1年5天,满10年15天。
# 报销流程是什么? → 3000元以下部门审批,以上需财务总监签字。
# 每行一个三元组,可直接导入 DeepEval 作为自定义测试用例或黄金样本
| 方案 | 优势 | 代价 | 适用场景 |
|---|---|---|---|
| 人工标注三元组 | 数据真实、贴合业务实际 | 耗时耗力、覆盖面有限 | 核心业务场景、上线前验收 |
| DeepEval 自定义数据集与黄金样本 | 与 pytest 集成、可沉淀为回归基线 | 需要持续维护样本库 | CI/CD 流水线、持续回归测试 |
| Ragas 合成数据生成 | 自动扩展覆盖、快速补齐长尾问题 | 依赖文档质量、需人工抽检 | 知识库更新初期、真实样本不足时 |
推荐结论:我们采用「人工标注打底 + 合成数据扩充」的混合策略,先构建 50 至 100 条核心三元组并沉淀为 DeepEval 黄金样本,再用 Ragas 合成数据扩充到 300 条以上,最后全部接入 pytest 流水线。下一步行动是本周内完成首批三元组标注,并在下个迭代把评测阈值写进 CI 配置,实现每次提交自动触发评测。
六、CI/CD集成与阈值拦截
DeepEval原生支持pytest流水线集成,我们把每一次评测直接写成标准的测试用例,用 deepeval test run 命令就能在GitHub Actions、GitLab CI或Jenkins中跑通。我们的评测结果会像单元测试一样输出通过或失败状态,构建系统直接读取退出码来判断本次提交是否达标。这种方式让我们第一次把大模型应用的质量门禁落到了和后端服务同等的工程地位上。
配置指标阈值是实现部署前自动拦截的关键,我们在初始化AnswerRelevancy、Faithfulness等指标时传入threshold参数,低于该分数的用例直接判定为失败。一旦流水线中任何一条用例未达到阈值,CI任务立即返回非零退出码,发布流程被强制阻断,问题版本无法进入生产环境。我们建议对核心业务场景设置更严格的阈值,对探索性场景适当放宽,用分级阈值平衡质量与迭代速度。
结合Confident AI,我们把生产环境中失败的样本自动回流为新的评测用例,形成从线上问题到回归测试的闭环。平台会追踪每一次失败trace并标注对应指标,我们定期将这些样本同步进本地测试集,确保同类缺陷不再复发。这套机制让我们的评测体系不再是静态的一次性检查,而是随着线上反馈持续进化的活的质量基线。
输入示例(tests/test_rag.py):
from deepeval import assert_test
from deepeval.test_case import LLMTestCase
from deepeval.metrics import AnswerRelevancyMetric, FaithfulnessMetric
answer_relevancy = AnswerRelevancyMetric(threshold=0.7)
faithfulness = FaithfulnessMetric(threshold=0.8)
def test_rag_answer_quality():
test_case = LLMTestCase(
input="DeepEval如何集成CI?",
actual_output="DeepEval原生支持pytest,可通过deepeval test run命令接入CI流水线。",
retrieval_context=["DeepEval官方文档:CI/CD集成章节"]
)
assert_test(test_case, [answer_relevancy, faithfulness])
运行命令:deepeval test run tests/ --ci
输出说明:终端逐条打印每个指标的得分与通过状态,
阈值达标显示PASSED,未达标显示FAILED并附失败原因;
命令最终以退出码0(全部通过)或1(存在失败)结束,
CI系统依据退出码决定是否放行本次部署。
| 方案 | 优势 | 代价 | 适用场景 |
|---|---|---|---|
| 本地pytest + deepeval test run | 零额外成本,与现有测试框架完全一致 | 报告需自行整理,缺乏生产视角 | 中小团队快速搭建质量门禁 |
| Confident AI平台托管 | 可视化报告、团队协作、生产trace追踪 | 需注册账号并上传评测数据 | 需要跨团队共享评测结果的场景 |
| Ragas独立评测脚本 | 专注RAG核心指标,脚本轻量灵活 | 无原生CI拦截能力,需自行封装退出码逻辑 | 离线实验与模型选型对比 |
| DeepEval + Confident AI组合 | 阈值拦截与失败样本回流闭环 | 集成配置工作量最大 | 规模化上线的LLM应用 |
我们的明确推荐是:以DeepEval的pytest集成作为CI/CD质量门禁的基线方案,第一周内在流水线中接入核心用例并配置阈值拦截,第二周再接入Confident AI打通生产失败样本的回流通道。下一步行动建议是挑选三个最高频的业务场景编写首批评测用例,把threshold设定为当前生产表现的前25%分位线。我们要求在下一次发布前强制跑通整条流水线,用真实的拦截效果验证这套机制的价值。
七、常见问题与排错指南
我们在部署 DeepEval 与 Ragas 的自动化评测流水线时,最先遇到的故障集中在 LLM Judge 调用层。当控制台出现 429 Rate Limit、连接超时或空响应时,我们第一步检查的是模型服务商的 API 配额、余额与网络出口策略,而不是急着改评测代码。我们建议在 CI 环境中为 Judge 模型配置独立的 API Key 与重试退避策略,并把并发数压到供应商限额以内。同时我们把 Judge 调用的请求与响应日志落盘,这样在流水线变红时可以直接定位是哪一次调用失败、失败原因是什么。
第二类高频问题是指标分数异常,例如忠实度长期为 0、出现 NaN,或者同一批用例分数剧烈波动。我们的标准动作是开启 verbose 调试模式,让框架输出逐句拆解、推理链与中间打分过程。通过 verbose 日志,我们发现大量异常并非模型能力问题,而是 retrieval_context 为空、actual_output 被截断或 prompt 模板变量未替换造成的。我们还把单条用例的完整评估结果导出为 JSON,方便团队成员在不重跑全量评测的前提下复现问题。
第三类问题最隐蔽:Ragas 与 DeepEval 对同名指标的计算口径并不一致,直接对比两套分数会导致误判。例如 Ragas 的 faithfulness 侧重 claim 级别的证据支持,而 DeepEval 的 FaithfulnessMetric 采用句级拆解与投票机制,两者分母不同、阈值也不同。我们在实践中固定每条流水线的指标归属:Ragas 负责 RAG 核心质量体检,DeepEval 负责工程化阈值拦截与 pytest 回归。任何跨工具的分数对比,我们都先对齐样本集、模型版本与温度参数,再下结论。
# 开启 verbose 模式定位 Faithfulness 分数异常
from deepeval import evaluate
from deepeval.test_case import LLMTestCase
from deepeval.metrics import FaithfulnessMetric
metric = FaithfulnessMetric(
threshold=0.7,
verbose_mode=True, # 关键开关:打印推理链与逐句打分
model="gpt-4o-mini",
strict_mode=False,
)
test_case = LLMTestCase(
input="DeepEval 支持哪些 RAG 指标?",
actual_output="支持忠实度、答案相关性与检索准确率等指标。",
retrieval_context=[
"DeepEval 提供 faithfulness、answer relevancy、contextual recall 等指标。"
],
)
evaluate(test_cases=[test_case], metrics=[metric])
# 输出说明:
# 控制台除最终分数外,还会打印:
# 1) 拆分出的每个陈述句(statements)
# 2) 每个陈述句是否被 retrieval_context 支持的判定理由
# 3) Judge 模型的 token 用量与耗时
# 若日志显示 statements 为空,说明 actual_output 异常或被截断,
# 应回查生成链路而非调整阈值。
| 方案 | 优势 | 代价 | 适用场景 |
|---|---|---|---|
| 开启 verbose_mode 逐条调试 | 直接暴露推理链与打分依据,定位精度最高 | 单次评测耗时与 token 成本上升 | 分数异常、用例复现、上线前抽查 |
| 切换本地 Judge 模型(如 Ollama) | 摆脱外部 API 配额与网络抖动,数据不出域 | 需要 GPU 资源,小模型打分稳定性较弱 | 离线批量回归、合规敏感业务 |
| 缩小样本集重跑(取 20 条代表用例) | 反馈周期从小时级压缩到分钟级 | 覆盖度下降,需配合全量定期巡检 | 流水线快速排障、PR 门禁预检 |
FAQ 1:LLM Judge 频繁报 429 或超时怎么办?
我们首先核对账户配额、剩余额度与请求速率上限,确认是否与其他业务共用 Key 导致挤占。随后我们在评测脚本中加入指数退避重试,并把并发度降到供应商限额的 70% 以下。网络层面我们检查出口 IP 是否被列入限制名单,必要时为 CI 单独配置代理或切换区域节点。
FAQ 2:指标分数突然变成 0 或 NaN,如何排查?
我们优先开启 verbose_mode 查看 statements 拆分结果,确认 actual_output 与 retrieval_context 是否为空字符串或被截断。接着我们检查 Judge 模型返回的 JSON 是否符合框架解析格式,字段缺失会直接导致分数计算失败。最后我们固定模型版本与温度参数,排除上游模型升级带来的分布漂移。
FAQ 3:Ragas 与 DeepEval 的同名指标分数不一致,以哪个为准?
我们不以任何一方的绝对分数为准,而是以各自流水线内的趋势与阈值判定结果为准。Ragas 的 faithfulness 按 claim 粒度统计证据支持,DeepEval 按句级拆解加投票,两者分母不同。我们在同一份报告里标注指标口径与计算版本,禁止跨工具直接比较绝对值,只允许比较各自基线的变化幅度。
FAQ 4:评测流水线在 CI 中运行太慢,怎么加速?
我们把全量评测拆分为 PR 门禁的快速子集与每日全量巡检两级。快速子集选取覆盖核心路径的 20 至 30 条用例,并启用 Judge 结果缓存复用相同输入。我们还将 Judge 调用并发化并批量提交请求,单次流水线耗时从小时级降到分钟级,同时保留失败用例的完整 verbose 日志供回溯。
FAQ 5:指标阈值应该设为多少才合理?
我们先用历史已上线版本跑基线评测,取 P10 分位数作为初始阈值,而不是拍脑袋定 0.7 或 0.8。随后我们收集至少两周的误报与漏报案例,按月校准阈值。对于忠实度这类影响用户信任的指标,我们设置比相关性更严格的阈值,并在阈值变更时走评审流程留档。
推荐结论:我们建议各位先把 verbose 调试模式与 Judge 调用日志落盘作为标配动作,再建立 Ragas 与 DeepEval 的指标口径对照表,最后实施快速子集加全量巡检的两级评测策略。下一步我们应把排错手册写入仓库的 RUNBOOK,并在下一次流水线变红时按表逐项执行,形成可复用的排障闭环。