Agent评测框架调研报告

10204 字
26 分钟

Agent评测框架调研报告

发布于

我站在什刹海边 一切甜蜜与我无关

Agent 评测框架调研报告

面向有 Agent 开发经验、但第一次系统了解评测框架的程序员

摘要

Agent 评测要解决的不是“能不能跑通”,而是三个问题:同一批任务换了 Prompt、模型或代码之后是否真的变好了;任务失败时问题出在最终回答、工具调用、执行路径还是运行成本;成功和失败案例能否沉淀为下一轮可重复运行的数据。

常见工具可以先按评测入口理解:

  • 代码驱动的评测入口:把 Agent、测试样本和评测逻辑放在代码仓库附近,修改代码后本地或在 CI 中运行一批任务,再查看分数和回归结果。DeepEval 是典型代表,Ragas 也更接近这一入口。
  • 运行数据驱动的评测入口:先记录 Agent 的运行过程,再围绕 Trace 调试、沉淀数据集、运行实验和比较版本。Langfuse 是典型代表,LangSmith 和 Phoenix 也为类似的平台型工作流。

这里的划分描述的是默认使用入口,不是能力边界。两类工具都在向对方扩展能力;真正影响日常体验的,是评测从哪里启动、数据在哪里流转,以及失败后能否快速回到执行过程。

常见框架的默认评测入口
常见框架的默认评测入口

1. 先把 Agent 评测对象说清楚

普通模型调用通常只有一进一出:

问题 → 模型 → 答案

Agent 会规划、选择工具、读取外部信息,并可能多次调用模型:

用户任务 → 理解任务 → 选择工具 → 调用工具 → 读取结果 → 继续规划 → 输出答案或执行动作

所以一次 Agent 任务至少要看四件事:

评测对象需要回答的问题常见证据
任务结果最终答案或动作是否满足目标最终回答、结构化结果、状态变化
工具行为工具、参数和调用顺序是否正确工具名、参数、调用顺序、错误码
执行过程是否出现重复、绕路或异常步骤Trace、模型调用、重试、异常
运行代价延迟、Token、费用和失败率是否可接受时间、Token、成本、成功率
一次失败的 Agent 任务,可能错在哪里
一次失败的 Agent 任务,可能错在哪里

一个分数只能告诉我们“哪里变差了”,过程记录才能帮助回答“为什么变差了”。两种评测入口最终都会用到 Dataset、Run、Evaluator 和 Score,只是把哪个对象放在中心不同。

2. 两种评测入口

2.1 代码驱动的评测入口

典型代表:DeepEval

这类入口从测试样本开始。Agent 代码、评测逻辑和数据集通常与代码仓库一起维护,运行方式接近集成测试:

Dataset → 运行当前版本 Agent → Evaluator / Metric → Score → CI 回归检查

它最适合回答:

我改了 Prompt、工具描述或路由逻辑,当前代码版本是否比上一版更好?

它的优势是启动快、版本关系清楚、容易放进本地命令或 CI。它的主要入口是测试代码和测试报告,因此复杂执行过程的长期浏览、线上案例沉淀和团队共享,通常需要额外的平台能力。

2.2 运行数据驱动的评测入口

典型代表:Langfuse

这类入口从一次真实运行开始。Agent 可以继续运行在本地、测试环境或线上,平台只负责接收 Trace 和结果,再提供查询、评分、数据集和实验能力:

Agent 运行 → Trace / Result 进入平台 → 定位问题 → 沉淀 Dataset → Experiment → 比较版本

它最适合回答:

这次任务每一步发生了什么?哪些真实案例值得加入下一轮回归?

它的优势是能把最终结果和执行证据放在一起,便于调试、协作和持续积累。代价是需要接入 Trace、维护平台工作区,并考虑数据存储、隐私和运行成本。

两种入口的差异可以压缩成一句话:

代码驱动的入口先定义“要测什么”;运行数据驱动的入口先保留“实际发生了什么”。

对比维度代码驱动的评测入口运行数据驱动的评测入口
默认起点测试样本、测试文件或 CIAgent 的一次运行和 Trace
核心对象Test Case、Metric、ScoreTrace、Dataset、Experiment
主要动作重跑同一批任务,检查回归查看过程、沉淀案例、比较实验
典型价值发布前回归门禁失败诊断和持续数据积累
常见落点Git 仓库、本地环境、CI平台工作区、Trace 和实验记录

两类入口不是互斥选择。实际工程中,代码驱动的入口适合发布前回归,运行数据驱动的入口适合失败诊断和持续积累。

3. 代码驱动的入口:DeepEval

3.1 先准备一次可评测的 Test Case

DeepEval 的基本单位是 Test Case。它把一次 Agent 交互需要的输入、实际结果、预期结果和过程信息放在一起,供不同 Metric 使用。

字段含义例子
`input`Agent 收到的任务查询北京明天天气
`actual_output`Agent 实际返回明天降雨概率 80%,建议带伞
`expected_output`可选的参考结果应给出正确的天气建议
`tools_called`实际调用的工具`weather`
`expected_tools`可选的预期工具`weather(city=北京, date=明天)`
`retrieval_context`可选的检索内容检索到的天气信息
`token_cost / time`运行成本和耗时1,240 tokens、2.8s

Test Case 不是只保存最终答案;需要哪些字段,取决于这次评测想检查什么。不同字段对应不同的评测问题:

想检查的问题主要使用的数据
最终回答是否正确`input`、`actual_output`、`expected_output`
工具是否调用正确`tools_called`、`expected_tools`
检索内容是否支持回答`actual_output`、`retrieval_context`
运行成本是否达标`token_cost`、`time`

如果评测只关心最终结果,可以先从输入、实际输出和参考结果开始;涉及工具、RAG 或运行成本时,再补充对应字段。Test Case 的作用,是把一次交互整理成可重复评测的数据。

DeepEval Test Case 构造代码
DeepEval Test Case 构造代码

3.2 从 Agent 运行记录到 Metric 分数

  • Test Case 解决“评测数据从哪里来”
  • Metric 解决“按什么标准判断”

DeepEval 不会自动得到 Agent 调用了哪些工具。实际项目中,工具调用和最终回答通常来自 Agent 框架的回调、Trace、日志或运行代码,再整理为 LLMTestCase 和 ToolCall。

Metric 可以使用确定性规则、参考答案比较或模型评审。它最终输出分数、是否通过以及失败原因。

DeepEval 从运行记录到评测结果
DeepEval 从运行记录到评测结果

3.3 不同评测范围,回答不同问题

当 Test Case 准备好之后,还要决定评测观察到哪一层。DeepEval 通常可以从端到端、轨迹和组件三个范围观察同一个 Agent:

评测范围主要问题典型数据或对象
端到端整个任务是否完成输入、最终输出、目标
轨迹决策和动作链路是否合理工具调用、步骤顺序、模型调用
组件级某个工具、检索器或模型调用是否可靠单个组件的输入、输出和指标
DeepEval 的三种评测范围
DeepEval 的三种评测范围

评测范围决定“看哪一层”,Metric 决定“用什么标准判断”。同一个 Agent 可以同时有端到端结果、轨迹结果和组件级结果,不必压缩成一个总分。这些范围可以组合使用,也不代表严格的对象包含关系。

3.4 运行评测并检查回归

Test Case 和评测范围确定后,就可以运行当前版本的 Agent,收集实际输出和过程信息,再应用 Metric 生成分数或通过状态:

准备 Test Case → 运行当前 Agent → 收集回答与工具轨迹 → 应用 Metric → 查看分数和失败样本

最自然的回归循环是:

改代码 → 跑 benchmark → 看回归 → 决定是否合入

不同评测方式适合检查不同内容:

评测方式适合检查的内容
确定性规则工具名、参数、状态码、步骤数
参考答案比较结构化结果、固定字段、标准答案
LLM Judge答案质量、目标完成度、轨迹合理性
人工评审复杂任务和边界案例

DeepEval 适合快速建立最小 benchmark、版本化评测逻辑、接入 pytest 或 CI,并用自定义规则检查工具名、参数、调用次数和结构化结果。下面用同一条任务展示一次真实运行:先让错误样本失败,再修复 Agent,最后重跑并检查回归。

DeepEval 回归评测结果
DeepEval 回归评测结果

4. 运行数据驱动的入口:Langfuse

Langfuse 的基本工作方式,是先把 Agent 的真实运行记录下来,再围绕这些运行记录进行调试、评分、数据集沉淀和版本比较。

因此它通常先回答:

这次 Agent 执行过程中,每一步发生了什么?

在掌握执行过程之后,再进一步回答:

这次运行是否满足目标?新的版本是否有所改进?

4.1 先记录一次可分析的 Agent 运行

Langfuse 的评测基础不是一条孤立的最终答案,而是一条包含执行过程的 Trace。Agent 每完成一个重要步骤,就把对应的输入、输出和状态记录下来。 一次天气查询可以被记录为:

Trace: 查询北京明天天气
├── Agent:理解用户意图
├── Generation:决定调用 weather
├── Tool:weather(city=北京, date=明天)
├── Generation:解释工具结果
└── Final Answer:给出是否带伞的建议
Langfuse 对象在这条运行中的作用
Trace表示一次完整的 Agent 任务
Observation表示任务中的一个执行步骤
Generation表示模型生成或模型调用
Span / Tool表示工具调用或普通程序步骤
Score表示对结果或过程的评价

Langfuse 的重点不是只保存“Agent 最后说了什么”,而是把最终结果和产生结果的过程放在同一条运行记录中。

1791724598062
1791724598062

4.2 Evaluator 如何读取 Trace 并生成 Score

Trace 记录 Agent 实际发生了什么,Evaluator 定义如何判断这次运行,Score 保存判断结果。三者分别承担“证据、判断和结果”的职责。

Evaluator 是一个独立的评测单元。它可以针对某类运行被配置和执行,也可以对一批 Trace 逐条评估。每执行一次,Langfuse 都会记录这次评测的状态、分数和解释。

Agent 运行
    ↓
Trace 记录回答、工具调用和执行步骤
    ↓
Evaluator 读取 Trace
    ↓
Evaluator Run 执行判断
    ↓
Score + Comment 写回平台

工具调用需要由 Agent 运行时通过 SDK、OpenTelemetry 或框架集成写入 Trace。Evaluator 再读取工具名、参数、工具结果和最终回答,根据预先设定的评测标准进行判断。

Langfuse Evaluator 执行结果
Langfuse Evaluator 执行结果

Evaluator 可以采用不同的评测方式:

Evaluator 类型适合判断的问题输出形式
代码规则工具名、参数、JSON、状态码是否正确通过 / 失败,或 0 / 1
LLM-as-a-Judge回答质量、完整性、相关性、任务完成度连续分数 + 解释
人工评审复杂案例、边界情况和有争议的结果人工分数 + 备注
外部评测器业务系统或其他评测平台提供的结果外部评分写回 Langfuse

因此,Langfuse 中的一次评测可以概括为:Trace 提供证据,Evaluator 执行判断,Evaluator Run 记录执行过程,Score 保存结果。相同的 Evaluator 既可以用于单条运行,也可以用于批量 Trace 和 Dataset Experiment。

4.3 从真实运行到 Dataset 和 Experiment

单次 Trace 适合回答“这次为什么失败”,但无法稳定回答“新版本是否整体变好了”。Langfuse 因此允许把真实运行中的任务沉淀为 Dataset Item,再用同一批任务运行不同版本的 Agent。

从运行 Trace 到可重复的 Benchmark
从运行 Trace 到可重复的 Benchmark

Dataset Item 可以保存用户输入、预期结果、关键约束和必要的元数据,作为之后重跑的任务样本。后续运行产生的新 Trace 则记录这一版本实际采用的工具、步骤和最终结果。

可以把三个对象理解为:Dataset 固定“要做什么”,Trace 记录“实际怎么做”,Experiment 比较“不同版本做得怎么样”。

4.4 运行实验、比较版本并理解边界

Dataset 和评测标准确定后,就可以让不同版本的 Agent 运行同一批任务。每一次实验都会产生新的 Trace 和 Score,平台再把这些结果汇总到一起,帮助比较 Prompt、模型、检索策略或代码版本的变化。

固定 Dataset
    ↓
运行版本 A
    ↓
运行版本 B
    ↓
分别记录 Trace 和 Score
    ↓
比较成功率、工具正确性、质量、延迟和成本

Langfuse 更适合查看复杂执行过程、持续沉淀真实案例、多人共享评测结果,以及比较实验版本。它需要额外配置 Trace 接入、数据存储和平台工作区,也要考虑运行数据的隐私和长期成本。

Agent 可以继续运行在本地、测试环境或线上服务中,Langfuse 通过 SDK、OpenTelemetry 或框架集成接收运行记录。它不要求 Agent 必须由 Langfuse 启动,关键是 Agent 能够把运行过程和结果写入平台。对于只有几十条样本、主要用于发布前回归的早期 benchmark,代码驱动的评测入口通常更轻量。

5. 其他框架如何放在同一张图里

框架更自然的使用入口主要特点适合优先关注的问题
DeepEval代码驱动Test Case、指标、pytest / CI修改代码后是否回归
Ragas代码驱动RAG 指标和实验比较检索内容是否有用、回答是否有依据
Langfuse运行数据驱动Trace、Dataset、Experiment失败过程如何定位、案例如何沉淀
LangSmith运行数据驱动Trace、Dataset、Evaluation,LangChain / LangGraph 生态结合紧密生态内的调试和评测协作
Phoenix运行数据驱动OpenTelemetry / OpenInference、开源和自托管标准化 Trace 和可观测性

6. 实际使用时,差异主要体现在哪里

这一节作为例会演示的路线。前面的章节已经解释了两类入口和各自的核心对象,这里只说明现场应该按什么顺序操作、每一步让听众看到什么,以及需要准备哪些截图。

演示可以使用同一个天气查询任务,让两种入口形成对照:DeepEval 展示如何从测试代码得到回归结果;Langfuse 展示如何从一次真实运行进入 Trace、Evaluator 和 Experiment。

6.1 DeepEval:从测试代码到回归结果

DeepEval 的演示从代码仓库中的 Dataset 和评测脚本开始,完整展示一次“准备数据、定义评分器、运行 Agent、执行评测、查看结果”的路径。它和 Langfuse 的演示步骤对应,但每一步都通过代码和命令完成。

第一步:准备 Dataset

DeepEval 的 Dataset 由代码文件维护。本次 Demo 使用 dataset.json 保存 4 个天气 Case,每个 Case 包含用户问题、期望调用的工具参数以及对最终回答的要求。

DeepEval Dataset 代码
DeepEval Dataset 代码

这一步固定的是“要评测哪些任务”。和 Langfuse Dataset Item 存在平台中不同,DeepEval 的 Dataset 通常就是仓库里的 JSON、Python 列表或测试数据文件。

第二步:定义评分器

准备好 Dataset 后,在评测脚本中定义如何判断 Agent 的表现。本次 Demo 使用两个评分器:ToolCorrectnessMetric 检查工具名称和参数,GEval 使用 LLM-as-a-Judge 评估回答是否正确使用天气结果,并给出合理的出行建议。

DeepEval 评分器代码
DeepEval 评分器代码

这里的 Metric 承担和 Langfuse Evaluator 类似的职责:它定义“按照什么标准判断”。不同之处在于,DeepEval 的 Metric 直接写在评测代码附近。

第三步:运行 Agent

评分之前,先让每个 Case 真实运行一次 Agent。模型根据用户问题决定是否调用 get_weather,工具访问 Open-Meteo 获取天气数据,Agent 再根据工具结果生成最终回答。

DeepEval Agent 运行
DeepEval Agent 运行

这一步产生后续评测需要的证据:实际回答、实际工具名、工具参数以及工具返回的天气结果。

第四步:执行评分器

Agent 运行完成后,DeepEval 将每次运行整理为 LLMTestCase,再把实际工具调用转换为 ToolCall,交给两个 Metric 执行评测。

DeepEval 评测执行
DeepEval 评测执行

这里体现了代码驱动入口的特点:评测从测试脚本启动,多个 Case 按照同一组 Metric 执行,不需要先在平台中创建实验。

第五步:查看分数和评测原因

评测完成后,DeepEval 输出每个 Metric 的分数、阈值、通过状态和原因,同时汇总整体通过率。

DeepEval 评测结果
DeepEval 评测结果

如果修改 Agent 的 Prompt、工具定义或路由逻辑,只需要重新运行同一个评测脚本,就可以比较修改前后的结果。这就是 DeepEval 中“测试代码 → Metric → Score → 回归检查”的闭环。

这组截图串起了 DeepEval 的完整使用路径:Dataset 固定评测任务,Metric 定义评分标准,Agent 产生运行证据,评测器计算分数,最终输出每条 Case 的结果和整体通过率。

6.2 Langfuse:从一次运行到评测实验

第一步:准备 Dataset

Langfuse 可以把真实运行中的代表性案例整理成 Dataset。每个 Dataset Item 保存之后需要重复运行的任务输入、预期输出和相关元数据。

Langfuse Dataset Items
Langfuse Dataset Items

这一步固定的是“之后要做什么”。同一批 Dataset Item 可以被不同版本的 Agent 反复运行,从而让后续比较具有可比性。

第二步:配置 Evaluator

Dataset 确定后,需要配置 Evaluator 来判断 Agent 的输出质量。截图中的 Evaluator 使用 LLM-as-a-Judge:它接收诊断请求和待评估的诊断报告,按照结论明确性、证据充分性、逻辑一致性、置信度合理性、可操作性以及完整性与规范性等维度进行评分,并输出 0 到 1 的分数。

Langfuse Evaluator 配置
Langfuse Evaluator 配置

第三步:运行一次 Experiment

在 Dataset 页面启动 Experiment 时,Langfuse 提供两种运行方式:通过用户界面配置 Prompt 或模型,也可以通过 SDK / API 接入已有代码,执行自定义评测逻辑。本次演示通过 Experiment 运行同一批 Dataset Item。

Langfuse 运行 Experiment
Langfuse 运行 Experiment

启动后,每个 Dataset Item 会产生一次实验运行。Agent 的输出和执行过程会继续写入 Trace,Evaluator 则根据配置对这些结果进行评分。

第四步:查看 Experiment 运行结果

Experiment 运行完成后,可以查看每条 Dataset Item 对应的 Trace、延迟、成本和 Evaluator 分数。截图中每一行对应一个样本,评测结果会和 Trace 入口放在同一张结果表中。

Langfuse Experiment 运行结果
Langfuse Experiment 运行结果

如果某条样本得分较低,可以从结果表进入对应 Trace,查看模型调用、工具调用、最终输出和评测评论,定位分数下降的原因。

第五步:比较多次 Experiment

当 Agent、Prompt 或模型发生变化后,可以再次运行同一 Dataset。Langfuse 会把多次 Experiment 放在一起,比较平均分数、延迟和成本等结果。

Langfuse Experiment 对比
Langfuse Experiment 对比

7. 怎么选择评测入口

按工作场景选择评测入口
按工作场景选择评测入口

可以先按工作问题选择入口,再选择具体工具:

当前最关心的问题更自然的起点选择原因
改代码后快速跑一批任务DeepEval测试和当前代码版本放在一起,容易接入 CI
主要研究 RAG 和检索指标Ragas指标和实验比较更集中
需要查看 Agent 的完整执行路径Langfuse、Phoenix、LangSmithTrace 是默认工作对象
已经使用 LangChain / LangGraphLangSmith生态和运行记录结合更紧
希望自托管并使用 OpenTelemetryPhoenix 或 Langfuse更适合围绕标准 Trace 建设
希望从真实运行反哺测试集Langfuse、LangSmith、PhoenixDataset 和 Trace 之间的流转更自然

建议的最小落地路径

收集一批真实任务
      ↓
固定输入、预期结果和关键工具行为
      ↓
先建立最终结果、工具行为和运行代价三类指标
      ↓
接入本地回归或 CI
      ↓
为运行保留 Trace,持续收集失败样本
      ↓
根据调试、协作和线上观测需求决定是否平台化

8. 结论

选择 Agent 评测框架时,先看团队的主要工作方式:

  • 如果首要任务是让 benchmark 可重复运行、进入 CI 并检查回归,优先考虑代码驱动的评测入口;
  • 如果首要任务是理解复杂 Agent 为什么失败,并持续积累真实案例,优先考虑运行数据驱动的评测入口;
  • 如果两类需求同时存在,可以让前者负责发布前门禁,让后者负责线上诊断、数据集沉淀和持续实验。

第一阶段不必一次解决所有评测问题。先固定一批真实任务,明确最终结果和关键工具行为,再逐步补充 Trace、LLM Judge、人工评审和平台协作能力。评测框架负责把流程执行起来,指标定义、样本覆盖和评测稳定性仍然需要单独验证。

参考资料

Last updated on