☰
AI 评测系列(06):DeepEval 实战——企业级 Agent 评测套件
2026/9/29 2:51:13 网站建设 项目流程

1. 为什么企业级 Agent 评测需要 DeepEval 而不是只看分数

做 Agent 评测最容易踩的坑,是把「质量分析」和「上线门控」混为一谈。我见过不少团队用批量评测框架跑出一堆均值分数,看着挺漂亮,但 PR 合并前没人能回答一个简单问题:这次改动到底能不能上?均值 0.76 是比上周的 0.74 好,可它跟「这次提交是否引入回归」没有直接关系。

DeepEval 解决的正是这个问题。它把每个评测样本包装成LLMTestCase对象,每个用例有明确的 Pass/Fail 判断,直接挂进 pytest。你跑pytest tests/test_agent_quality.py -v,输出就是绿的通过、红的失败,CI 里天然可做质量门控。它和 RAGAS 那种 DataFrame 批量出均值的范式完全不同——RAGAS 告诉你「这周系统质量趋势如何」,DeepEval 告诉你「这次提交能不能上线」。

这篇聚焦企业级 Agent 评测落地,核心是三件事:用LLMTestCase描述工具调用期望、用ToolCorrectnessMetric校验工具调用序列、用 pytest 把整套评测变成可回归的流水线。适合已经在做 Agent 但评测还停留在「人工看几条」阶段的同学,也适合想把评测接进 CI 的工程团队。全程用 TaoToken 统一 Key 和 API 通道接入 Judge LLM,避免在多个模型供应商之间来回切配置。

2. TaoToken 前置:统一 Key 与 API 通道

DeepEval 默认拿 OpenAI 当 Judge LLM,但企业环境里往往要接自己的模型通道。这里用 TaoToken 做统一入口,好处是一个 Key 走通对话、编码、评测三类工具,settings.json 里不用维护多套 base_url 和密钥。

先拿 Key。访问控制台创建 API Key:

https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=deepeval_agent_eval

创建后在 API Keys 页面复制密钥,形如sk-xxxx。接入文档在:

https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=deepeval_agent_eval

API 基地址统一用https://taotoken.net/api(注意这个地址不加 UTM 参数,直接写进代码配置)。模型对话调试入口:

https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=deepeval_agent_eval

如果你还要跑长期编码或 Agent 任务,Coding Plan 页面可以看套餐:

https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=deepeval_agent_eval

环境变量先配好,后面代码全部读环境变量,不硬编码:

export TAOTOKEN_API_KEY="sk-你的密钥" export TAOTOKEN_BASE_URL="https://taotoken.net/api"

注意:Judge LLM 的调用会产生 token 消耗,评测用例越多消耗越大。建议开发阶段先用 5–10 个核心用例跑通,稳定后再扩到全量。

3. 可复制配置:自定义 Judge LLM 与 pytest 骨架

3.1 继承 DeepEvalBaseLLM 接入 TaoToken 通道

DeepEval 允许你继承DeepEvalBaseLLM把任意模型接成 Judge。下面这个类通过 TaoToken 的 OpenAI 兼容通道调用模型,temperature=0.0保证评测结果可复现:

import os from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage from deepeval.models.base_model import DeepEvalBaseLLM class TaoTokenJudge(DeepEvalBaseLLM): def __init__(self): self._llm = ChatOpenAI( model="gpt-4o-mini", api_key=os.environ["TAOTOKEN_API_KEY"], base_url=os.environ["TAOTOKEN_BASE_URL"], temperature=0.0, ) def load_model(self): return self._llm def generate(self, prompt: str, *args, **kwargs) -> str: result = self._llm.invoke([HumanMessage(content=prompt)]) return str(result.content) async def a_generate(self, prompt: str, *args, **kwargs) -> str: return self.generate(prompt) def get_model_name(self) -> str: return "taotoken-judge" judge_llm = TaoTokenJudge()

关键点:base_url指向 TaoToken 的 API 地址,api_key读环境变量。这样 Judge LLM 和你的业务 Agent 可以走同一个通道,密钥管理只维护一份。

3.2 构建 LLMTestCase:工具调用期望怎么写

LLMTestCase是 DeepEval 的核心数据结构。评测 Agent 时,除了输入输出,还要描述期望调用的工具和实际调用的工具。注意expected_tools和tools_called都必须传ToolCall对象,不是字符串列表——这是新手最容易写错的地方:

from deepeval.test_case import LLMTestCase, ToolCall case = LLMTestCase( input="你们的退款政策是什么?", actual_output=agent_answer, expected_tools=[ToolCall(name="search_faq")], tools_called=[ToolCall(name="search_faq")], retrieval_context=["退款政策:7天内全额退款,需提供订单号..."], )

retrieval_context是检索到的上下文。这里有个陷阱后面会专门讲:如果 Agent 跳过了工具调用直接回答,这个字段为空,Faithfulness 指标会直接判 0。

3.3 pytest 配置骨架

把评测用例参数化,每个 case 跑一遍指标断言:

import pytest from deepeval import assert_test from deepeval.metrics import ( AnswerRelevancyMetric, FaithfulnessMetric, ToolCorrectnessMetric, ) from judge import judge_llm from cases import build_test_cases @pytest.mark.parametrize("case", build_test_cases()) def test_agent_response(case): assert_test( case, metrics=[ AnswerRelevancyMetric(threshold=0.7, model=judge_llm), FaithfulnessMetric(threshold=0.7, model=judge_llm), ToolCorrectnessMetric(model=judge_llm), ], )

build_test_cases()返回一个LLMTestCase列表,每个用例对应一条真实用户问题。assert_test会在任一指标低于 threshold 时抛断言失败,pytest 直接标红。

3.4 settings.json 配置片段

如果你用支持 settings.json 的 AI 工具链(比如某些编码助手),把 TaoToken 通道写进去,评测脚本和业务工具共用一套配置:

{ "llm": { "provider": "openai-compatible", "base_url": "https://taotoken.net/api", "api_key_env": "TAOTOKEN_API_KEY", "model": "gpt-4o-mini", "temperature": 0.0 }, "eval": { "framework": "deepeval", "judge_model": "gpt-4o-mini", "default_threshold": 0.7 } }

api_key_env指向环境变量名而不是明文密钥,避免密钥进版本库。

4. 验证请求与成功结果

4.1 运行命令

装依赖后直接跑 pytest:

pip install deepeval langchain-openai pytest pytest tests/test_agent_quality.py -v

4.2 结果解读

5 个用例跑下来,典型输出如下:

问题AnswerRelevancyFaithfulnessToolCorrectness
退款政策是什么?1.00 通过0.50 失败失败
订单 ORD-001 发货了吗?0.33 失败0.50 失败失败
ORD-004 能退多少钱?1.00 通过1.00 通过失败
支持哪些支付方式?0.50 失败0.00 失败失败
299 元 3 天前买的能退吗?1.00 通过1.00 通过通过

聚合结果:

AnswerRelevancy avg=0.767 pass_rate=60% Faithfulness avg=0.600 pass_rate=40% ToolCorrectness avg=0.200 pass_rate=20%

4.3 三个指标怎么读

AnswerRelevancy 低往往是工具没触发的下游结果。订单查询那条只拿了 0.33,因为 Agent 没调get_order_status,直接回了「您好,关于您的订单发货情况…」这种没有实质内容的回答。这不是 LLM 生成质量问题,是工具调用失败导致的连锁反应。

Faithfulness 的 0 分陷阱要特别小心。支付方式那条 Faithfulness=0.00,因为 Agent 跳过工具直接回答「支持微信、支付宝、银行卡」,而retrieval_context是空的。评测框架认为答案完全不基于上下文,直接判 0——哪怕答案事实上是对的。Faithfulness 测的是「答案有没有超出上下文」,前提是得有上下文。工具调用不成功,这个指标就失去意义。

ToolCorrectness 是 DeepEval 相比批量评测框架的独有优势。只有最后一个用例通过,因为用户直接给了金额和天数,Agent 正确调用了calculate_refund。其余 4 个要么没调工具,要么调错。20% 的通过率直接暴露了 Agent 的工具调用是最大短板。

4.4 CI 集成

把评测挂进 GitHub Actions,PR 合并前自动跑:

name: Agent Quality Gate on: [pull_request] jobs: eval: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: pip install deepeval langchain-openai pytest - run: pytest tests/test_agent_quality.py -v env: TAOTOKEN_API_KEY: ${{ secrets.TAOTOKEN_API_KEY }} TAOTOKEN_BASE_URL: https://taotoken.net/api

任意用例指标低于 threshold,CI 直接失败,PR 无法合并。

阈值设置建议分阶段:开发初期用 0.5 宽松门控,防止过早阻断迭代;稳定阶段用 0.7;医疗、金融等关键路径用 0.85。

5. 本篇常见错排查

5.1 ToolCall 传成字符串列表

最常见的报错是expected_tools或tools_called传了["search_faq"]这种字符串列表。DeepEval 要求传ToolCall对象:

# 错误 expected_tools=["search_faq"] # 正确 expected_tools=[ToolCall(name="search_faq")]

传错类型时指标会直接报解析异常,或者 ToolCorrectness 恒为 0。

5.2 Judge LLM 连接超时或 401

如果assert_test卡住或报鉴权错误,先确认环境变量:

echo $TAOTOKEN_API_KEY echo $TAOTOKEN_BASE_URL

base_url必须是https://taotoken.net/api,不要带多余路径。密钥失效就去控制台重新生成:

https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=deepeval_agent_eval

5.3 Faithfulness 恒为 0

如果所有用例 Faithfulness 都是 0,检查retrieval_context是否为空。Agent 没调工具时这个字段没内容,指标自然判 0。解决办法是先修工具调用,让 Agent 真正检索到上下文,再评 Faithfulness。顺序反了会得到误导性结论。

5.4 评测结果不可复现

同一批用例两次跑分数不一样,通常是temperature没设成 0。Judge LLM 的temperature=0.0是复现的前提。另外 DeepEval 有缓存机制,调试时可以用--cache相关参数控制,避免旧结果干扰。

5.5 pytest 收集不到用例

@pytest.mark.parametrize的第二个参数必须是可迭代对象。如果build_test_cases()返回生成器且被消费过,第二次收集会为空。改成返回列表:

def build_test_cases(): return [case1, case2, case3, case4, case5]

6. 把评测变成可回归的工程习惯

跑通一次基线只是开始。真正有价值的是把 DeepEval 评测变成每次提交都跑的固定动作。我的做法是:开发过程中每次提交跑 5–10 个核心用例做快速门控,每周跑一次全量批量评测看趋势,发布前两者都跑——批量评测给趋势,DeepEval 给明确的通过/失败结论。两个范式不互斥,组合起来才完整。

工具调用正确性是企业级 Agent 最该盯的指标。这次 20% 的通过率说明大部分问题出在 Agent 没调工具或调错工具,而不是生成质量。先把 ToolCorrectness 拉上去,AnswerRelevancy 和 Faithfulness 往往会跟着改善,因为它们是工具调用失败的下游指标。

Judge LLM 统一走 TaoToken 通道后,密钥和 base_url 只维护一份,评测脚本、业务 Agent、编码工具共用同一套配置,切换模型时改一个环境变量就行。模型对话调试可以用:

https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=deepeval_agent_eval

长期跑 Agent 评测和编码任务的话,Coding Plan 的额度更划算:

https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=deepeval_agent_eval

下一步建议你把build_test_cases()里的用例换成自己 Agent 的真实问题,先跑通 5 条,看到红绿结果后再逐步加量。评测用例的质量比数量重要,一条能暴露工具调用失败的用例,胜过十条永远通过的摆设。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询