本节摘要:给 Agent 选模型/选框架,沿用"模型答一道题"的口径会系统性失真——因为 Agent 评测与模型评测有三个结构不同:复合误差(五步任务每步 90%,端到端就剩 59%——数字为算术示意);环境依赖(同一 Agent 换个工具版本成绩就变,测的是"系统"不是"模型");过程即证据(答案对不代表过程对,误打误撞与正确推理在下一版环境里命运不同)。本节交付三件东西:三态口径——成功/部分成功/失败,加权完成率 =(成功 + 0.5 × 部分)/ 总数,"部分成功"必须存在,否则"做了一半"和"完全没做"被压成同一个 0;失败归因四分——模型、工具、环境、题目歧义各自记账,环境与工具的锅先修基建再评模型,只有模型归因才进横向比较;最小五项轨迹审查——目标可达、步骤支撑、工具调用正确、上下文使用、终止合理,配"失败全查、成功抽检"的抽样策略。附汇总脚本(含不稳定任务识别:重跑两次结果不一致的任务是环境敏感的第一嫌疑)。
阅读完本节,你应当能够:
| 不同 | 机制 | 口径后果 |
|---|---|---|
| 复合误差 | 多步任务错误相乘(0.9⁵≈0.59,示意) | 单步分数的小差异在端到端被放大,必须测任务级 |
| 环境依赖 | 工具版本、沙箱数据、外部页面都在变 | 不钉死环境快照的完成率没有可比性 |
| 过程即证据 | 结果对可能是运气,过程错迟早翻车 | 判定对象是"轨迹 + 结果",不只是结果 |
一句话:模型评测是考一场试,Agent 评测是验收一项工程——工程验收要查施工记录,这就是轨迹评测的位置。
完成率先钉三态:S(成功:目标达成且过程合规)、P(部分成功:主目标达成但有瑕疵,或反之)、F(失败)。加权完成率 =(S + 0.5P)/ N。"部分成功"这一档存在的理由:客服 Agent "查到了订单但回错退款政策"是 P 不是 F——把它压成 F 会冤枉模型,压成 S 会放过缺陷。
汇总脚本:
# task_score.py(纯标准库,可直接运行) """Agent 任务评测汇总:三态口径(S 成功/P 部分/F 失败)+ 不稳定识别 + 失败归因分布。""" TASKS = { # 示意:12 个任务各重跑 2 次(S=成功 P=部分成功 F=失败) "查库存并下单": "SS", "汇总周报数据": "SS", "生成退款工单": "SS", "批量改订单地址": "PS", "检索竞品价格": "SF", "跨系统核对发票": "FF", "重置会员积分": "SS", "导出对账单": "SP", "多条件筛选工单": "PF", "回复催件邮件": "SS", "核销优惠券": "FS", "归档旧工单": "PP", } CAUSES = { # 示意:人工审查轨迹后填写的失败/部分归因 "批量改订单地址": ("模型", "长任务中途丢失指令约束"), "检索竞品价格": ("环境", "目标页面改版,选择器失效"), "跨系统核对发票": ("工具", "发票接口超时且无重试"), "导出对账单": ("题目", "任务描述存在两种合理理解"), "多条件筛选工单": ("模型", "条件组合遗漏一项"), "核销优惠券": ("环境", "沙箱时间与真实时间不一致"), "归档旧工单": ("工具", "归档接口分页参数错误"), } if __name__ == "__main__": runs = "".join(TASKS.values()) s, p, f = runs.count("S"), runs.count("P"), runs.count("F") weighted = (s + 0.5 * p) / len(runs) print(f"任务完成率(加权口径:成功=1,部分=0.5,失败=0)") print(f" 总体 {weighted * 100:.1f}%({len(runs)} 次运行:S {s} / P {p} / F {f})") unstable = [t for t, o in TASKS.items() if len(set(o)) > 1] print(f" 不稳定任务(重跑结果不一致,{len(unstable)} 个):{'、'.join(unstable)}") print("失败归因分布(异常任务的审查结论):") by_cause = {} for t, (c, _) in CAUSES.items(): by_cause.setdefault(c, []).append(t) for c, ts in sorted(by_cause.items(), key=lambda x: -len(x[1])): print(f" [{c}] {len(ts)} 个:{'、'.join(ts)}") print("读法:环境/工具归因先修基建再评模型;题目归因修任务描述;" "只有模型归因才进模型横向比较")
一次运行的真实输出(实测,示意输入):
任务完成率(加权口径:成功=1,部分=0.5,失败=0) 总体 68.8%(24 次运行:S 14 / P 5 / F 5) 不稳定任务(重跑结果不一致,5 个):批量改订单地址、检索竞品价格、导出对账单、多条件筛选工单、核销优惠券 失败归因分布(异常任务的审查结论): [模型] 2 个:批量改订单地址、多条件筛选工单 [环境] 2 个:检索竞品价格、核销优惠券 [工具] 2 个:跨系统核对发票、归档旧工单 [题目] 1 个:导出对账单 读法:环境/工具归因先修基建再评模型;题目归因修任务描述;只有模型归因才进模型横向比较
示例的读法:总体 68.8% 听起来是模型不及格,但归因一拆——7 个异常任务里模型只占 2 个,环境 2、工具 2、题目 1;修掉基建再测,完成率的可比版本才会出现。这与 3.1 的口径意识同构:完成率不标口径(环境版本、归因规则)就没有横比资格,《Evals 实战》4.1 的通过率陷阱在 Agent 场景加倍成立。
| 归因 | 判据 | 动作 |
|---|---|---|
| 模型 | 推理/指令/记忆错误,环境无异常 | 进横向比较(换模型/换 prompt) |
| 工具 | 接口超时、返回异常、参数 bug | 修工具或加重试,别记模型头上 |
| 环境 | 页面改版、沙箱数据漂移、权限变化 | 钉环境快照后重测 |
| 题目歧义 | 人工也说不清任务要什么 | 修任务描述,该任务本轮作废 |
⚠️ 归因是人工审查轨迹后的结论,不是自动标签——自动归因(按失败环节猜)会把工具超时记成"模型不会重试",恰恰把最该修的基建问题埋进模型分数里。
对轨迹(每一步的输入、模型输出、工具调用与返回)逐项过堂:
抽样策略:失败与部分成功全查,成功抽 20%——审查预算花在信息量最大的地方(社区通行的审查配比经验)。
三条钉死,写进评测记录:环境快照(工具版本、沙箱数据集、外部页面存档,跑之前定格);重跑次数(每任务至少 2 次,报均值±波动——4.3 第 12 项的 Agent 版);时间敏感任务单独标记(汇率、库存类任务天然不可复现,跨轮比较要剔除或降权)。环境工程与 Agent 基准的系统做法是专论话题,见 《深入理解 AI Agent:设计原理与工程实践》第 6 章;本书给选择者的底线是:没有环境快照的 Agent 完成率,一律当营销数字处理(4.3 核对表动机区的口径)。
完成率测的是"活干得怎么样",但 Agent 还有一层独有的风险:它会在汇报里说谎——声称读过的文件没读、声称通过的测试没过。这就是 8.2 的主题:虚报判定。