Agent 评测 + Benchmark 栈
十件评测资产,给真正在度量 agent 质量的 ML/LLM 工程师:离线测试集(DeepEval / Promptfoo / Ragas)、benchmark 跑分器(LM Eval Harness / SWE-bench)、agent CI 专用评测、trace-based LLM-as-judge(Phoenix Evals / Langfuse)、安全检查(Giskard)以及 CI 拦截门。别再凭感觉发 agent。
这个 pack 包含什么
这是 agent demo 让全屋惊艳、然后几个用户开始报奇怪 bug、你突然意识到「上周改的 prompt 到底是变好了还是悄悄把 tool-call 准确率降了 12%」时,你会搭的那一套。这里每个资产存在的理由只有一个:把 agent 质量从「感觉」变成「可以在 CI 里盯的数字」。
这个 pack 刻意做成 agent 专用。姊妹 pack ml-engineer-rag-eval 覆盖 RAG 基础设施(分块、embedding 服务、向量库)。这个 pack 假设这一层已经存在,问下一个问题:上面跑的 agent 到底变好还是变坏? 答案 —— 测试集、benchmark、trace 评测、回归门 —— 是另一类形态的工具。
四层贯穿所有资产:
- 离线测试集 —— DeepEval / Promptfoo / Ragas。手工标注的 case,配预期输出或评分准则。测试集是你的 ground truth。
- Benchmark —— LM Evaluation Harness / SWE-bench。公开、可比、用来在换模型时做 go/no-go 决策。
- 基于 trace 的评测 —— Phoenix Evals / Langfuse。用 LLM judge 或规则引擎给真实生产 trace 打分,对用户真正命中的请求做采样。
- CI 回归门 —— Agent Evaluation / Giskard Checks / promptfoo-action。指标掉下来或安全规则被踩,直接拦 PR。
推荐安装顺序(测试集 → 离线跑 → benchmark → trace 评测 → CI 回归)
- DeepEval —— 从这里开始。pytest 风格对 LLM 输出做断言,30+ 内置指标(faithfulness / hallucination / answer relevancy / contextual recall / G-Eval 自定义评分准则 / tool-correctness / task-completion)。一个文件写 30 个 agent case,跑
deepeval test run,看着它们失败 —— 你瞬间就有了 5 分钟前根本不存在的 baseline。 - Promptfoo —— 声明式 YAML 测试套件,在多 prompt、多模型、多 provider 配置之间并排 diff 输出。比 DeepEval 更适合在视觉上 A/B 两个 prompt、跑一波带对抗输入的 red-team、或者把结果矩阵给非工程同事看。两个一起用:DeepEval 当断言库,Promptfoo 当对比与 red-team 入口。
- Ragas —— agent 如果检索任何东西(文档、记忆、工具结果),检索质量就是一个隐藏变量。Ragas 对检索增强输出计算 faithfulness / answer relevancy / context precision / context recall。在 agent loop 内部的检索步骤上跑,而不是只对独立 RAG 流水线跑。
- LM Evaluation Harness —— 标准的离线 benchmark 跑分器。60+ 学术 benchmark(MMLU / GSM8K / HellaSwag / BBH / HumanEval)一个 CLI 包圆。换模型 go/no-go 用:在考虑从 Sonnet 切到 Haiku 之前,harness 数字是最便宜的第一道筛子,免得直接花在定制 agent 评测上。
- SWE-bench —— 代码 agent 引用最多的公开 benchmark。真实 GitHub issue、真实测试套件,agent 出的补丁能不能让它们变绿就是 pass/fail。先跑 SWE-bench Lite 拿快速信号(300 个 instance,单机几个小时);换 harness 或模型时再跑全集。供应商博客里的 agent benchmark 数字是营销;你自己 harness 跑出来的 SWE-bench 数字才是证据。
- Agent Evaluation — Test Virtual Agents in CI —— 专为在 CI 里测虚拟 agent 而生。定义测试计划、跑你的 agent、给 tool call 和最终答案打分、用 CI 能拦截的格式回报。补上「我有测试集」到「我的 PR 在指标掉的时候被拦」之间的中间件。
- Phoenix Evals — LLM-as-Judge —— 真实流量起来之后,手工标注的测试集就扛不住扩展了。Phoenix Evals 是 LLM-as-judge 库,自带幻觉 / 毒性 / 相关性 / 摘要质量 / 代码生成正确性的评分模板。每晚采样 100 条生产 trace 打分,指标漂移就告警。
- Langfuse Python SDK —— 给 agent 应用打 trace,让评分能挂回去。Langfuse 装饰器包住 LLM 调用、工具调用、整条 agent run;DeepEval / Phoenix Evals / 自定义 judge 的分数都能写回这条 trace。现在你的离线测试集分数和线上采样分数住在同一个看板里。
- Giskard Checks — Evals and Safety Tests for LLM Agents —— 安全、鲁棒性、red-team 检查。抓 prompt injection、跑题 prompt、违反品牌规范的输出、paraphrase 一致性失败。和准确率评测不同:这里查的是 agent 不该做什么,而不是它做得多好。当作 CI 套件的一部分跑,不要等上线之后。
- promptfoo-action —— 回归门。GitHub Action 在每个 PR 上跑你的 Promptfoo 评测集,指标低于阈值就拦合并,并贴一条 diff 评论告诉你哪些 case 回归了。这条把「我们有时跑评测」变成「每个 PR 都被度量」。没有 CI 门的评测 loop 三个月就悄悄烂掉。
它们怎么协同(agent 评测流水线)
┌─────────────────────────────────────────────────────────────┐
│ 离线 — 测试集 │
│ DeepEval(断言 + 指标) │
│ Promptfoo(YAML、并排对比、red-team) │
│ Ragas(agent loop 内的检索) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 离线 — BENCHMARK │
│ LM Evaluation Harness(MMLU / BBH / HumanEval ...) │
│ SWE-bench(代码 agent,真实 GitHub issue) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 线上 — TRACE + JUDGE │
│ Langfuse SDK ──► 捕捉每一次 agent run │
│ │ │
│ ▼ │
│ Phoenix Evals(对采样 trace 跑 LLM-as-judge) │
│ │ │
│ ▼ │
│ 指标漂移告警 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 回归门 — CI │
│ Agent Evaluation(虚拟 agent CI 测试) │
│ Giskard Checks(安全 + red-team) │
│ promptfoo-action(指标掉就拦 PR) │
└─────────────────────────────────────────────────────────────┘
切分是有意义的。离线测试集慢、贵、跑在你笔记本上;benchmark 跨团队可比,能用来做换模型决策;trace 评测采的是用户真正命中的请求;CI 门是唯一能防止前面这些烂掉的东西。
你会遇到的取舍
- DeepEval vs Promptfoo vs Ragas —— 三个互有重叠的评测库,形态不同。DeepEval 是 Python 原生、读起来像 pytest,团队本身就住在 Python 里时最合手。Promptfoo 是 YAML 优先、自带并排对比 UI,适合 A/B 多 prompt 多模型扫描或 red-team 跑批。Ragas 是检索专用,能算另外两个算不好的指标。多数生产 agent 团队最后是 DeepEval + Promptfoo 一起用 —— 断言库 + 对比面 —— 检索环节再用 Ragas。
- 公开 benchmark vs 自定义评测集 —— 公开 benchmark(LM Eval Harness / SWE-bench)跨团队可比、跑起来便宜;自定义评测集反映你真实的用户和真实的失败模式。两个都要。换模型时先过公开 benchmark;自定义集才能抓住你自己 agent 在你自己工具 schema 上特有的 bug。
- LLM-as-judge vs 规则评测 —— LLM-as-judge(Phoenix Evals)能扩展到 hallucination / helpfulness 这种细微指标,但继承 judge 模型的偏见、每个 case 烧 token。规则评测(regex / JSON-schema / 精确匹配)免费、确定性强,但只抓得住明显错误。结构正确性用规则(「这个 tool call 验证通过没?」),语义质量用 LLM-as-judge(「回答是否忠于检索到的 context?」)。
- Langfuse vs Phoenix vs Arize —— 互有重叠的可观测栈。Langfuse 是 prompt + trace 管理上的 OSS 头部,自托管强。Phoenix 是 OSS 评测框架,自带 LLM-as-judge 模板。Arize 是 Phoenix 的商业母公司,企业功能更全。多数团队自托管 Langfuse 做 tracing,跑 Phoenix Evals 作为对那些 trace 打分的 judge 库。
- SWE-bench Lite vs 全集 —— Lite(300 个 instance)几个小时跑完,够拿周级信号。全集(2,294 个 instance)烧真金白银算力。换模型时跑 Lite;Lite 上看到向好趋势或者大版本发布前才跑全集。
常见踩坑
- 没测试集只看日志 —— 最常见的死法。「我们就看生产日志」在流量小时还能撑,流量起来之后没人看。第一周就手工标 30–50 个 case。每次用户投诉暴露新失败模式就更新。三个月之后有 200–500 个 case,才有真信号。
- 测试集只有成功 case —— 一半的测试集必须是难 / 模糊 / 对抗 case。如果 agent 100% 通过,case 本身就没用。包含已知的 prompt injection 尝试、跑题 query、相互矛盾的工具结果、常见 query 的脆弱 paraphrase。
- 只评测最终答案 —— agent 在工具选择、参数 shape、重试行为、多轮状态上挂掉,不只是最终字符串。给 tool-correctness 和 trajectory 打分,不只是 answer-correctness。DeepEval 和 Agent Evaluation 都暴露 tool 级指标。
- judge 模型和 agent 模型同一个 —— 用 GPT-4 评 GPT-4 继承它的偏见,错过特定失败类。预算允许就用不同家族的 judge 模型。哪怕在两个 judge 之间轮换、看分歧也是有用信号。
- 测试集本身在漂移 —— 测试集是软件 artifact。打版本号。每季度审一次。退役 agent 早就轻松通过的 case。加这个季度的失败模式 case。半年没改过的测试集就是一个在骗你的测试集。
- 没 CI 门 —— 拦不住 merge 的 loop 就是会烂掉的 loop。接上 promptfoo-action 或 Agent Evaluation 的 CI 步骤,指标掉就让 build 红。阈值不必第一天就严,门存在本身才是关键。
- 供应商博客里的 benchmark 数字 —— 模型供应商自己晒的 agent benchmark 在你拿自家 harness 复现之前,全部是营销文案。任何 agent benchmark 声明在你信之前先自己跑一次 SWE-bench Lite。
10 个资产打包就绪
常见问题
这个 pack 跟 TokRepo 已有的 `ml-engineer-rag-eval` pack 有什么区别?
ml-engineer-rag-eval 覆盖 RAG 基础设施层:分块、embedding 服务、向量库、检索框架、reranker。它假设你在搭检索、需要一套栈。这个 pack 假设 agent 基础设施已经存在,问下一个问题:怎么度量上面的 agent 是变好还是变坏?受众不同、workflow ID 几乎不重叠(Phoenix Evals 2842 是评测库子组件,不是 RAG pack 里的完整 Phoenix 可观测工具)。两个搭配用:先用前一个 pack 把 RAG 层搭好,再用这个 pack 度量上面跑的 agent。
为什么 DeepEval 和 Promptfoo 都要?它们不是重复的吗?
有重叠但服务不同形态。DeepEval 是 Python 原生、读起来像 pytest —— 你写 assert_test(case, metrics=[FaithfulnessMetric()]),直接塞进已有测试套件。Promptfoo 是 YAML 优先、渲染对比矩阵 UI —— 适合在 5 个模型上 A/B 扫两个 prompt 或者跑 red-team 对抗集。多数生产团队最后两个都用:DeepEval 当断言库、Promptfoo 当并排对比面 + CI 入口。只能选一个的话,团队住在 Python 里就选 DeepEval;YAML/config 比代码多就选 Promptfoo。
已经有自定义评测集了,还需要 SWE-bench 吗?
你的 agent 不是代码 agent 就跳过 SWE-bench。是的话,SWE-bench 是唯一被广泛引用、带真实 GitHub issue 和真实测试套件的公开 benchmark,跑出来的分数跨供应商可比。每次换模型前先跑 SWE-bench Lite(300 个 instance,几小时跑完)当便宜的第一道筛子。自定义评测集抓你特有的 bug;SWE-bench 告诉你这一类模型在代码工作上是不是连方向都对。两个都需要。
judge 应该用和 agent 一样的模型吗?
能避免就避免。同家族 LLM-as-judge 继承 agent 模型的偏见 —— 倾向于给自己输出打高分、漏掉它自己有的失败模式。能用不同家族就用(比如 OpenAI agent 用 Anthropic 当 judge 或反过来)。预算紧就在两个 judge 之间轮换,把分歧 case 推到人工复核队列。Phoenix Evals 一行配置就能换 judge 模型。
最小可用的评测集是多少?
30 个手工标注 case 配预期输出(开放式任务配评分准则)第一周就够用。包含 10 个 happy path、10 个 agent 历史上栽过跟头的边缘 case、10 个对抗 case(跑题 / prompt injection / 脆弱 paraphrase)。接到 DeepEval 或 Promptfoo 里、每次 prompt 改动就跑一次、再接上 promptfoo-action 拦 PR。三个月之后到 200–500 个 case,真信号会从 trace 评测(Phoenix Evals + Langfuse 采样生产流量)那边来 —— 但手工集永远不下线。