在说一个 Agent 好不好之前,先把好拆开

"这个 Agent 不错。"

这句话几乎没有信息量。不错在哪?完成率高,还是速度快?是面对标准输入不错,还是面对刁钻输入也不错?是这一次不错,还是跑一百次有九十五次不错?

做 Agent 的人都踩过同一个坑:写完一个 Agent,自己点几下,看它跑通了一个 demo,就以为它能用了。然后上线,真实用户进来,各种奇怪的输入、各种中途的工具报错、各种它自己绕进死胡同的情况——你才发现,你从来没有真正"评判"过它,你只是看它表演了几次

这个系列要解决的就是这件事:怎么严肃地、可重复地、量化地判断一个 Agent 到底好不好。这是第一篇,先把最基础的问题想清楚——评判一个 Agent,你到底在评判什么。

为什么 Agent 比模型难评测

评测一个语言模型,其实是相对成熟的事。你有一个固定的题库(MMLU、GSM8K、HumanEval),每道题有标准答案,把模型的输出和标准答案对一遍,算个准确率,就得到一个分数。输入固定,输出固定,评判规则固定。

评测一个 Agent,上面这套几乎全部失效。原因有五个,每一个都很本质:

第一,非确定性。 同一个任务,Agent 跑两次,可能走出两条完全不同的轨迹。它第一次先查数据库再调 API,第二次先调 API 再查数据库;它第一次三步完成,第二次绕了七步。你测一次得到的结论,不代表它稳定的水平。模型也有采样随机性,但 Agent 的随机性会沿着多步决策链层层放大。

第二,多步,且错误会累积。 Agent 的一次任务是几步、十几步、几十步的决策链。中间错一步,后果是不确定的——可能整条链就崩了,也可能它自己在下一步把错误纠正回来了。这意味着"最终对不对"和"过程好不好"是两件事,你不能只看终点。

第三,常常没有唯一正确答案。 "帮我订一张周五去上海的机票"——什么叫做对了?订到了就算?订最便宜的?订时间最合适的?一个开放任务往往有一整片"都算对"的解空间,你没法拿一个标准答案去逐字符比对

第四,过程的代价是第一类指标,不是附属品。 一个 Agent 把任务做对了,但它用了 50 步、烧了 8 美元的 token、花了 4 分钟、中途还调用了一个有副作用的危险工具——这算"好"吗? 对模型评测来说,成本是工程优化的附属话题;对 Agent 评测来说,步数、token、延迟、调用了什么工具,本身就是评判的一部分

第五,环境有状态,评测会改变世界。 评测一个模型是只读的——问它一道题,它答,世界没有变化。评测一个 Agent 常常不是:它真的会发出邮件、真的会写数据库、真的会提交订单。你不能在生产环境里反复跑评测,你需要一个可重置、可回滚的沙箱环境——这本身就是评测体系的一部分工程。

把这五点合起来看,结论很清楚:Agent 评测不是模型评测的延伸,它是一个独立的、更难的工程问题

只看最终答案,是最常见的错

新手做 Agent 评测,第一反应几乎都是:准备一批任务,每个任务一个期望结果,跑完对一下终点对不对,算完成率。

这个做法不是没用,但它会系统性地骗你。两种情况:

结果对了,但轨迹是错的。 一个 Agent 被问"我们公司上个季度营收多少",它没去查数据库,而是凭训练知识编了一个数字——恰好蒙对了。终点检查"通过"。但这个 Agent 本质上是坏的,它换个问题就会编一个错的数字。只看终点,你给它打了满分。

结果错了,但只差最后一步。 另一个 Agent,推理链完全正确,工具调用全对,数据也查准了,只是在最后格式化输出时少了一个字段。终点检查"失败"。但这个 Agent 其实非常接近可用,它需要的修复极小。只看终点,你把它和那个"完全不会做"的 Agent 打了同样的零分。

这两种情况说明一件事:Agent 的质量信息,大量地藏在轨迹里,而不只在终点。一个严肃的评测体系,必须能看见过程。后面会专门讲轨迹评测,这里先记住这个结论。

把"好"拆成五个维度

回到最初那句没有信息量的话——"这个 Agent 不错"。要让它有信息量,得把"好"拆开。我把它拆成五个维度,任何一次 Agent 评测,都应该同时在这五个维度上给出说法:

一、任务完成度(Task Completion)。 它有没有真的把事情做完?注意"做完"和"做对"是两回事——做完是指它走完了流程、给出了一个终态(而不是中途卡死、无限循环、或者放弃),做对是下一个维度的事。完成度低,通常意味着 Agent 的循环控制、错误处理有问题。

二、正确性(Correctness)。 它做完的那个结果,对不对?对于有唯一答案的任务,这是和标准答案比对;对于开放任务,这往往要靠规则检查(rubric)或者用另一个模型来判断(LLM-as-judge,后面专门讲)。

三、效率(Efficiency)。 它用了多少步、多少 token、多少钱、多少时间?同样把任务做对,3 步完成和 30 步完成是天壤之别——不只是成本,步数越多,出错和发散的概率越大。效率不是优化项,它是质量项

四、鲁棒性(Robustness)。 把任务换一种说法,它还行吗?输入里加一点噪声、加一句无关的话,它会被带跑吗?某个工具突然返回报错,它能不能恢复?一个只在"干净输入 + 一切正常"下工作的 Agent,不算一个好 Agent——真实世界永远不干净。

五、行为边界(Safety / Autonomy)。 它知不知道什么时候该停下来?该问人的时候会不会问,而不是自作主张?遇到它不该做的事(删库、转账、越权),它会不会拒绝?自主性是 Agent 的卖点,也是它最危险的地方——一个"很能干但不知道边界"的 Agent,比一个"不太能干"的 Agent 危险得多。

这五个维度不是平均加权的。不同场景下,权重完全不同:一个写代码的 Agent,正确性和效率最重要;一个能操作生产系统的运维 Agent,行为边界压倒一切;一个面向终端用户的客服 Agent,鲁棒性是命门。评测的第一步,是先想清楚你的场景里这五个维度怎么排序

评测要分三个层次

知道了看哪五个维度,还要知道在哪个粒度上看。Agent 评测有三个层次,它们回答的是不同的问题,缺一不可:

单步评测(Step-level)。 冻结 Agent 在某个具体状态——给定当前的上下文、已有的观察、可用的工具——只看它这一步的决策对不对。这是最细的粒度,适合定位"它到底在哪一类决策上容易犯错"。比如你会发现,某个 Agent 在"该调用工具时却直接回答"这一类单步决策上,错误率特别高。

轨迹评测(Trajectory-level)。 看 Agent 走完一整条决策链,这条链整体合不合理——有没有重复劳动、有没有绕路、有没有在两个状态之间反复横跳、错误发生后有没有自我恢复。轨迹评测回答的是"它的决策过程像不像一个聪明的人"。

端到端评测(End-to-end)。 不管过程,只问最终任务有没有在五个维度上达标。这是最接近"用户真实体验"的层次,也是最终要对齐的目标。

新手只做端到端,资深的人三层都做。端到端告诉你"有没有问题",单步和轨迹告诉你"问题出在哪"。一个只有端到端评测的团队,知道自己的 Agent 完成率是 72%,但完全不知道该改什么;三层都有的团队,能说出"完成率 72%,其中 18% 的失败是因为工具选择错误,集中在第 3-5 步"——后者才有改进的抓手。

一个最小评测框架长什么样

把上面的想法落到代码上,一个最小的 Agent 评测框架,核心只有三件东西:任务、运行、打分

from dataclasses import dataclass
from typing import Callable

@dataclass
class EvalCase:
    task: str                  # 任务描述,喂给 Agent 的输入
    checker: Callable          # 判定函数,输入完整轨迹,输出是否达标
    tags: list[str]            # 给这个用例打标签,便于分组统计

def run_eval(agent, cases: list[EvalCase], repeat: int = 3) -> list[dict]:
    results = []
    for case in cases:
        # 同一个任务跑多次,对抗非确定性
        for run_idx in range(repeat):
            trace = agent.run(case.task)        # 跑一遍,记录完整轨迹
            results.append({
                "task": case.task,
                "tags": case.tags,
                "run": run_idx,
                "passed": case.checker(trace),   # 正确性
                "completed": trace.reached_terminal,  # 完成度
                "steps": len(trace.steps),       # 效率:步数
                "tokens": trace.total_tokens,    # 效率:token
                "cost": trace.total_cost,        # 效率:成本
                "latency": trace.wall_time,      # 效率:延迟
                "tools_used": trace.tool_names,  # 行为边界:用了什么工具
            })
    return results

这段代码很短,但有几个点值得说:

记录的不只是 passedcompletedstepstokenscosttools_used——五个维度的原始数据都被留下来了。打分是后面的事,但原始数据必须在评测时一次性采集全,事后补不回来。

对每个任务跑了多次(repeat=3)。这是在直接对抗第一节说的"非确定性"——单次结果不可信,你要的是"5 次里通过几次"这种分布,而不是"通过/不通过"这种布尔值。

checker 接收的是完整轨迹 trace,不是最终答案。这就给轨迹评测留好了口子——你的 checker 可以检查"它有没有真的调用数据库",而不只是"最后那个数字对不对"。

还有一件事这段代码没写、但最重要:这批 cases 本身,是你最值钱的资产。一个项目做久了,模型会换、prompt 会改、框架会迁移,但那套精心积累的、覆盖了各种刁钻情况的评测用例集,是会一直增值的东西。它应该被当作代码一样进版本库、做 review、持续扩充。很多团队 Agent 越做越好,靠的不是什么神奇的 prompt,而是那套评测集一年里从 20 个用例长到了 2000 个

为什么这件事值得认真做

最后说说动机。

你做 Agent,一定会不停地改它——换个更新的模型、调一句 prompt、加一个工具、改一下循环逻辑。每一次改动,你都在赌它变好了。如果没有评测,你凭什么相信这个赌注?你只能再点几下 demo,看它"感觉上"是不是顺了。这就是在盲改。

有了一套覆盖五个维度、分三个层次的评测体系,改动就从"赌博"变成了"实验":改之前跑一遍,改之后跑一遍,两个分数一比,变好还是变坏,清清楚楚。这就是软件工程里"回归测试"那一套,搬到了 Agent 上——它的名字叫评测驱动开发(Eval-Driven Development),是把 Agent 从"玄学调参"做成"工程"的唯一路径。

这一篇把框架立起来了:Agent 难评测的五个根本原因、好要拆成的五个维度、评测要分的三个层次、一个最小评测框架的样子。下一篇会往里填具体的东西——每个维度上的指标到底怎么定义、怎么计算,比如完成率该怎么算才不会骗自己、效率该用哪几个数才有意义、那些看起来很美但其实有毒的指标长什么样。

版权声明: 如无特别声明,本文版权归 sshipanoo 所有,转载请注明本文链接。

(采用 CC BY-NC-SA 4.0 许可协议进行授权)

本文标题:01. 评判一个 Agent,你到底在评判什么

本文链接:https://www.sshipanoo.com/blog/ai/agent-eval/01-评判一个Agent/

本文最后一次更新为 天前,文章中的某些内容可能已过时!