当前位置:首页>排行榜>Agent评测·三层质量门 2026.10.02

Agent评测·三层质量门 2026.10.02

  • 更新时间 2026-10-02 07:21:58

Agent评测·三层质量门 2026.10.02

你的 Agent demo 跑得飞起,上线三天被 dealer 骂到退车——因为「只看最终答案」的评测,根本测不出工具选错、推理断裂、多轮忘记约束这三件要命的事。本期把 Motorway × AWS 的生产评测蓝图拆成一套三天能跑通的质量门。

为什么是现在

  • 你的客服 Agent 单次回答「看起来对」,但 10 次里有 1 次选错工具、把退款金额算错——你靠人工抽查永远发现不了。
  • 你的搜索 Agent 在单轮测试里 90% 正确,可真实用户连问三轮后,它把第一句说的「只要红色」忘得一干二净。
  • τ-bench 早就量过:benchmark 上 pass@1 有 60% 的 Agent,跨多次重复试验的一致性可能只有 25%。单次测试通过 ≠ 生产里可靠。

读完你能做到:用开源库 strands-agents-evals 把「最终答案对不对」拆成工具选择 / 推理连贯 / 输出质量三层独立判分,再用 pass^k(连跑 k 次全过) 替代 pass@1 度量稳定性,并把它接进 CI 当质量门——不达阈值直接拦下发布。


四要素卡(先拿结论)

维度
内容
场景
生产环境里上线工具调用型 Agent(经销商库存搜索、客服退改签、技术支持排障);要在真实流量下量化「选对工具 + 推理连贯 + 答案正确」三件事,并防回归、防随机性。
条件
Python≥3.10;被评 agent 可调用(Strands / LangChain / CrewAI / 自研皆可,只需能给定 input 吐出 output + trajectory);工具 schema 已知可写确定性 grader;可选 LLM-judge(Anthropic / OpenAI / Bedrock 兼容);≥ 几十个代表性 case(含多轮);CI 能跑 strands-evals。
方法
一句话——把「只看最终答案」拆成三层独立判分(L1 工具选择/参数确定性 grader >95%;L2 推理连贯 LLM-judge rubric >85%;L3 输出质量 LLM-judge + 人审 >90%),并用 pass^k 替代 pass@1 度量稳定性;三层分 + pass^k 设成 CI 质量门,不达标禁发布。
效果业务收益(Motorway 真实拍卖业务)
:错误结果 1/8 → 1/50、工具选择准确率 87% → 98%、任务完成率 96%、多轮上下文保留 94%、月事故 12 → 2、问题定位 hours → minutes。技术指标:pass@1=90% 仅等价于 pass^3≈73%(0.9³);τ-bench 60% pass@1 → 25% 一致性。代价:LLM-judge 自身有方差需人审校准;多轮 case 构造 + k 次重跑抬升评测成本(API / 算力)。

采用方:Motorway(英国二手车拍卖平台,8,000 经销商 / 2,500 车日拍,日均真实资金流)已落地;AWS 将其写成生产蓝图并开源 strands-agents-evals;Bedrock AgentCore Evaluations 提供线上监控。


一、技术背景与问题定义

现有做法卡在哪

绝大多数团队评 Agent 的方式,和评语言模型一样:跑几个任务,看最终输出,假设它 work。这在 Agent 上会系统性漏掉三类失败:

  1. 选对工具但参数写错——推理没错,调用却挂;
  2. 选对工具参数也对,但最终答案似是而非——lexer 没验证事实;
  3. 单次成功、三次里挂一次——非确定性让单轮测试形同赌博。

Motorway 的经销商库存搜索 Agent 就是典型:demo 全过,上线后每 8 个查询就有 1 个错误结果,对拿搜索结果做采购决策的经销商来说是信任崩塌。根因不是模型笨,是评测只看了最终答案这一层。

本文对象的核心主张

AWS × Motorway 给出的解法是一套三层质量门(Three-Layer Quality Gates)+ pass^k 一致性度量:

  • 把「答案对不对」拆成三个彼此独立、可单独失败的判分层;
  • 每层用最便宜且最可信的判分器(能确定的用代码,不确定的用 LLM-judge,主观的加人审);
  • 用 pass^k 把「单次通过」换算成「连续 k 次全过」,直接当发布红线。

它落地在开源库 strands-agents-evals(github.com/strands-agents/evals,PyPI 同名,Apache-2.0 友好),框架无关——LangChain / CrewAI / 自研都能用;纯本地跑评测不依赖 AWS,AgentCore 只是可选的线上监控。

读者画像与采用方

  • 算法 / 评测负责人:要把「Agent 靠不靠谱」变成可拦发布的数字;
  • 应用开发者:在上线前用 CI 挡住工具选错、上下文丢失类回归;
  • 真实采用方:Motorway 生产落地;AWS 官方生产蓝图;Bedrock AgentCore 线上评估。

二、实现路径与步骤【本期重点,照抄落地】

目标:三天内跑通「三层判分 + pass^k + CI 门」最小闭环。以下用 strands-agents-evals 实跑,judge 用 Anthropic 兼容端点(换 OpenAI / 本地 vLLM 同理)。

步骤 1:环境与依赖

# 1) Python 3.10+ 虚拟环境python -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scripts\activate# 2) 装评测库(同时装出 strands-evals CLI)pip install strands-agents-evals# 3) 被评 Agent 用的 SDK(以 Strands 为例;LangChain 自行替换)pip install strands-agents# 4) 配置 judge 模型(环境变量,二选一)export ANTHROPIC_API_KEY=sk-...# 或走本地 vLLM:export str依据框架,judge model 指到 openai 兼容 base_url
  • 验证成功:strands-evals --help 打出 5 个子命令(run / validate / report / diagnose / generate)即装好。
  • 耗时与成本:装包 < 5 分钟;评测本身零 GPU,只烧 judge 模型的 API(见步骤 6)。

步骤 2:构造 case 集(评测数据)

case 要覆盖单轮 + 多轮,且每层都要能判:L1 需要「期望工具 + 期望参数键」,L3 需要「期望答案」。

# cases.pyfrom strands_evals import Casecases = [# 单轮:工具选择 + 参数可确定性校验    Case[str, str](        name="dealer_search_color",input="只给我红色、预算 2 万英镑以内的车",        expected_output="返回红色且 ≤20000 英镑的车列表",        metadata={"layer": "tool_use", "expected_tool": "search_inventory","expected_args": {"color": "red", "max_budget_gbp": 20000}},    ),# 多轮:第二句收紧约束,测上下文保留    Case[str, str](        name="dealer_search_refine",input="先给我 2020 年后的电动车;啊不对,把年份放宽到 2018",        expected_output="返回 2018 年后电动车,不含 2020 限制",        metadata={"layer": "multi_turn", "expected_tool": "search_inventory","expected_args": {"min_year": 2018, "fuel": "electric"}},    ),]
  • 数据来源:从生产日志里抽真实 query(优先踩过坑的);多轮 case 用「用户中途改口」覆盖 filter-accumulation 失败。
  • 验证成功:strands-evals validate cases.json(先序列化)能过 schema 校验。

步骤 3:三层 evaluator(核心判分)

# evaluators.pyfrom strands_evals.evaluators import OutputEvaluator, TrajectoryEvaluatorfrom strands_evals.extractors import tools_use_extractor# ---------- Layer 1:工具选择/参数 —— 确定性代码 grader(不靠 LLM) ----------deftool_usage_grader(agent_messages, expected_tool, expected_args):    traj = tools_use_extractor.extract_agent_tools_used_from_messages(agent_messages)    used = {t["name"]: t.get("args", {}) for t in traj}if expected_tool notin used:return0.0, f"未调用期望工具 {expected_tool},实际={list(used)}"    got = used[expected_tool]    missing = [k for k in expected_args if got.get(k) != expected_args[k]]if missing:return0.0, f"参数不符:{missing}"return1.0, "工具与参数均正确"# ---------- Layer 2:推理连贯 —— LLM-judge(主观,用 rubric) ----------reason_evaluator = OutputEvaluator(    rubric="评估 Agent 中间步骤是否连贯、是否支撑最终结论。""1.0=推理链清晰自洽;0.5=部分跳跃;0.0=前后矛盾或瞎编步骤。",    model="us.anthropic.claude-sonnet-4-20250514-v1:0",    include_inputs=True,)# ---------- Layer 3:输出质量 —— LLM-judge + 人审校准 ----------quality_evaluator = OutputEvaluator(    rubric="最终回答是否准确、完整、回答了用户问题。""1.0=准确完整;0.5=部分正确;0.0=错误或答非所问。",    model="us.anthropic.claude-sonnet-4-20250514-v1:0",)
  • 关键参数与取值理由:
    • L1 用代码 grader而非 LLM——工具选择客观可验证,LLM 在这里只会增加方差和成本;
    • L2/L3 的 model 选小一点的 judge(sonnet 级够用),不要拿被测模型当 judge(自赞偏差);
    • include_inputs=True 让 judge 看到上下文,避免断章取义。
  • 验证成功:单 case 跑通,report 里 L1 给 0/1、L2/L3 给 0~1 分数与 reason。

步骤 4:跑 Experiment(Python API)

# run_eval.pyfrom strands import Agentfrom strands_tools import search_inventory   # 你的工具from strands_evals import Experimentfrom cases import casesfrom evaluators import tool_usage_grader, reason_evaluator, quality_evaluatordefget_response(case):    agent = Agent(tools=[search_inventory])    out = str(agent(case.input))# L1 需要 trajectory,从 agent.messages 抽    score, reason = tool_usage_grader(        agent.messages,case.metadata["expected_tool"],case.metadata["expected_args"],    )return {"output": out, "_l1": (score, reason)}experiment = Experiment[str, str](    cases=cases,    evaluators=[reason_evaluator, quality_evaluator],  # L1 在 get_response 内联算)report = experiment.run_evaluations(get_response)report.run_display()

CLI 等价写法(CI 友好):

strands-evals validate cases.jsonstrands-evals run cases.json --agent my_pkg.agents:build_agent --display
  • 验证成功:终端 Rich 表打印每层 overall_score;L2/L3 < 阈值时红旗标出。

步骤 5:pass^k 一致性(接 agent_eval_passk.py)

把每个 case 连跑 k 次的 pass/fail 落 CSV,再算 pass^k:

# 同一 case 跑 5 次(temperature>0),记 pass/failpython - <<'PY'import csv# 伪代码:对 case 循环 5 次,调 get_response,写 results.csv# 列:trial_id, case_id, pass(0/1)PYpython agent_eval_passk.py results.csv 3

内置演示直接看效果:

python agent_eval_passk.py# case          pass@1   pass^3# search-1      0.667      0.000   <- 三次必挂一次,单轮测试漏判# search-2      1.000      1.000# search-3      0.667      0.000
  • 为什么 k=3:Motorway 把 pass^3>80% 当高危路径红线;高 stakes 业务可上 k=5。
  • 验证成功:pass^3 显著低于 pass@1 的 case 被标红,进入修复队列。

步骤 6:CI 质量门

# .github/workflows/agent-eval.yml 片段-name:Agent三层质量门run:|    strands-evals validate cases.json    strands-evals run cases.json --agent my_pkg.agents:build_agent \      --fail-on "layer1<0.95,layer2<0.85,layer3<0.90" \      --display    python agent_eval_passk.py results.csv 3   # pass^3<0.80 视为失败
  • 阈值(Motorway 实测可达成):L1 工具 >95%、L2 推理 >85%、L3 输出 >90%、pass^3 >80%、多轮上下文保留 >90%。
  • 验证成功:任一红线未达,CI 非零退出,发布被拦。

关键超参表

参数
含义
默认
调大
调小
L1 阈值
工具选择确定性通过率
0.95
更稳但易误拦正常波动
低于 0.90 则 3/10 选错工具放行
L2 阈值
推理连贯 judge 分
0.85
更严,需更强 judge
漏掉断裂推理
L3 阈值
输出质量 judge 分
0.90
答案更稳
放行进似是而非回答
k(pass^k)
连续成功次数
3
更苛求稳定性,成本 ×k
退化为 pass@1
judge 模型
LLM-judge 底座
sonnet 级
判分更准、更贵
便宜但 judge 方差大
temperature
重跑随机性
>0
暴露更多不稳定
0 则 pass^k 失真

常见报错与规避

  • strands-evals: command not found → 装在 venv 里但 CI 没 activate;用 python -m strands_evals.cli 或显式 activate。
  • L1 抽不到 trajectory → 工具调用需走 agent.messages;自研框架请实现 tools_use_extractor 等价抽取,否则 L1 退化成 LLM-judge,失去确定性。
  • LLM-judge 两次结果不一致 → judge 自身非确定;固定 judge temperature=0 + 人审校准,别把 judge 分当绝对真理。
  • pass^k 全 1 但线上仍翻车 → case 集不代表真实流量(clean prompt 偏多);补对抗/残缺/冲突输入,按 ZDNet 建议每工作流 ≥100 条。
  • CI 超时 → k 次重跑 × case 数 × judge 调用;先对小子集跑 pass^k,全量留夜间。

跑起来要花多少

  • 算力:零 GPU(judge 走 API;自托管 vLLM 另算)。
  • API 费用:L2/L3 每 case 12 次 judge 调用;50 case × k=3 ≈ 300 次调用,sonnet 级约 **$0.52/轮**(远低于全量 benchmark 横扫)。
  • 数据量:最小闭环 30~50 条代表性 case(含 10 条多轮)即可挡住大头回归;生产建议每工作流 ≥100 条。
  • 时间:首次搭建 1 天,日常 CI < 15 分钟出报告(Motorway 把问题定位压到 minutes 级)。

三、原理讲解:为什么三层 + pass^k 有效

1. 三层解耦各自失败面。 最终答案正确 ≠ 过程正确。三层把「选工具 / 想清楚 / 答得对」拆成独立随机变量,单层失效不互相掩盖:

final_correct = tool_correct ∧ reasoning_ok ∧ output_correctP(final_correct) ≤ min(P(tool), P(reason), P(output))

所以只报总分,会把「工具选错但答案蒙对」的 Agent 误判为健康。分层后任何一层掉档都单独亮红灯。

2. 确定性 grader 优先。 L1 工具选择是客观事实(调了没、参数对没),用代码判分方差=0、成本≈0;把 LLM-judge 留给真正主观的 L2/L3,是用最低成本买最高可信度的分配。

3. pass^k 把随机性显式化。 Agent 非确定,单次成功是伯努利试验:

pass^k = P(连续 k 次全过) ≈ (pass@1)^k        # 独立假设pass^3 | pass@1=0.9 = 0.729                    # 单次 90% → 三次仅 73%

单轮测试用 pass@1 当可靠性,等于用 (pass@1)^k 的乐观上限骗自己。pass^k 直接给出「用户连续 k 次都拿到正确结果」的概率——这才是生产该守的数字。

4. 工程取舍(效果 vs 成本 vs 稳定性)。 三层 + pass^k 多花的是 judge API 与 k 倍重跑;换回的是「上线前拦住 1/8 错误率」的确定性。Motorway 数据证明这笔账划算:错误率砍到 1/50、月事故 12→2。代价是 LLM-judge 方差需人审校准,且 case 集必须代表真实流量,否则门禁只是心理安慰。

不为炫技:上面 4 点就是复现和调参要记住的全部。公式控制在 15 行内,多一个都不用背。


四、效果验证与适用边界

量化结果(方法 | 环境/数据 | 指标 | 基线 | 本文结果 | 来源)

方法
环境 / 数据
指标
基线
本文结果
来源
三层质量门
Motorway 经销商搜索 Agent(生产)
错误结果率
1/8 查询
1/50
AWS×Motorway 生产蓝图
三层质量门
同上
工具选择准确率
87%
98%
同上
三层质量门
同上
任务完成率
—
96%
同上
三层质量门
同上
多轮上下文保留
—
94%
同上
三层质量门
同上
月事故数
12
2
同上
pass^k 度量
通用 Agent
pass^3(pass@1=0.9)
—
0.73
(=0.9³)
τ-bench / 框架文档
pass^k 度量
τ-bench Agent
一致性(pass@1=0.6)
—
~25%
τ-bench 研究
strands-agents-evals
开源库(本地)
可跑三层 + CI 门
手工评
可复现
github.com/strands-agents/evals

业务收益单列(哪个环节省了什么)

  • 信任环节:经销商搜索错误率 1/8 → 1/50,直接止住 dealer 流失(拍卖平台日均真实资金流)。
  • 运维环节:问题定位 hours → minutes,月事故 12 → 2,on-call 成本骤降。
  • 发布环节:CI 质量门拦下工具选错 / 上下文丢失类回归,避免「demo 过、生产翻」。
  • 口径:上述为 Motorway 公开生产数据;你的业务需按自身流量重测,数字不直接平移。

决策清单(什么条件下成立 / 失效)

  • 成立:工具 schema 已知、能构造代表性 case(含多轮)、CI 能跑评测、业务容不得「偶尔错」。
  • 失效 / 退化:
    • case 集只覆盖 clean prompt → 门禁虚高,上线仍翻(补对抗/残缺输入);
    • 把被测模型当 judge → 自赞偏差,分层分失真;
    • 只看 pass@1 不设 pass^k → 随机性被掩盖,高 stakes 业务踩雷;
    • L1 没有确定性 grader(工具未知)→ 退化成全 LLM-judge,成本与方差双升。
  • 换业务 / 模型要重验的前提:工具集变更、prompt 大改、模型升级、流量季节性漂移——每次都要重跑旧 case 集(EvoHarnessBench 已证明:往 harness 加工具/技能本身就会让旧任务退化)。
  • 已知局限与合规:LLM-judge 非确定,需人审校准留痕(EU AI Act 高风险的合规证据);judge 成本随 k 线性增长,全量留夜间跑。

复现清单

① 上手三步走(可执行)

  1. pip install strands-agents-evals → strands-evals --help 验证安装。
  2. 写 30~50 条 case(含 10 条多轮改口),L1 配确定性 tool_usage_grader,L2/L3 配 LLM-judge rubric。
  3. strands-evals run cases.json --agent ... --fail-on "layer1<0.95,layer2<0.85,layer3<0.90";同 case 连跑 3 次写 CSV,python agent_eval_passk.py results.csv 3 看 pass^3。

② 踩坑记录

  • strands-evals 找不到 → venv 没 activate,改用 python -m strands_evals.cli。
  • L1 抽不到 trajectory → 自研框架要实现等价工具抽取,否则失去确定性。
  • judge 两次不一致 → 固定 temperature=0 + 人审,别当绝对真理。
  • pass^k 全 1 仍翻车 → case 集不代表真实流量,补 ≥100 条/工作流。

③ 实用评分卡

维度
评分(1-5)
说明
可复现性
5
库开源、命令明确、零 GPU 本地可跑
上手成本
4
半天内出首份报告;多轮 case 构造稍费时
算力门槛
5
零 GPU,只烧 judge API
效果可信度
4
Motorway 硬数据;judge 方差需人审
许可友好度
5
Apache-2.0 友好,框架无关

④ 关键源码 / 论文链接

  • 评测库:https://github.com/strands-agents/evals[1] (PyPI strands-agents-evals)
  • 生产蓝图:AWS ML Blog《Evaluating AI Agents: a production blueprint with Strands and AgentCore》(2026-07)
  • 可部署样例:sample-evaluating-agents-on-aws-with-strands-and-agentcore(GitHub)
  • 一致性研究:τ-bench(Sierra)、pass^k 定义见本期 agent_eval_passk.py

今日反问

如果最终答案正确就能拿高分,为什么把「选对工具」「想清楚」「答得对」拆成三层独立判分后,反而能拦住那些单轮测试全程绿灯、上线却频频翻车的 Agent?

引用链接

[1]https://github.com/strands-agents/evals

随机文章