怎么评估一个 Agent 的表现?
一句话回答
Agent 的评估要看三方面:结果,任务到底有没有完成,最好能自动验证,比如代码改完测试是否通过、数据库里的状态是否符合预期;过程,步数是否合理、工具选得对不对、参数是否正确、有没有多余或危险的操作;代价,token、费用和耗时。Agent 每次运行的路径都可能不同,同一任务要跑多次,看成功率和稳定性(如 pass@k、pass^k)。评测要在可复现的环境里进行:沙箱、固定的初始状态、模拟的外部工具。
详细解析
结果评估
检查最终状态,而不是相信 Agent 自己说的"已完成":
- 编程任务:运行事先准备好、Agent 看不到的测试。SWE-bench 就是这个思路:用真实的 GitHub issue 作为任务,用测试判断修复是否成功
- 操作类任务:检查数据库或系统的最终状态,比如订单是否已取消、退款金额是否正确。τ-bench 就是把对话结束时的数据库状态和标注好的目标状态做比较
- 信息类任务:把答案和标准答案比对,用规则或模型打分
- 开放任务(如写一份调研报告):评分细则加模型打分,再人工抽检
复杂任务可以拆成多个检查点,记录完成了几个,比单纯的成功或失败提供更多信息。
过程评估
完整记录轨迹:每一步的推理、工具调用、参数和结果(见 链路追踪)。然后检查:
- 工具选择:必需的工具有没有调用,有没有用错工具
- 参数:比如查询订单时,用的是不是当前用户自己的订单号
- 顺序约束:先查询再修改;执行写操作前征得用户确认
- 多余操作:重复调用同一个工具、和任务无关的搜索、绕远路
- 危险操作:删除数据、越权访问、未经确认的不可逆操作。一旦出现就直接判失败,不管结果对不对(防护措施见 怎么防止 Agent 失控)
- 效率:总步数,有没有陷入循环
不要规定唯一正确的路径。同一个任务往往有多种合理的做法,只检查关键约束(必须做的、不能做的、先后顺序),否则会惩罚更聪明的做法。
稳定性和代价
Agent 每次运行的路径都可能不同,同一任务要跑多次,用下面几个指标衡量稳定性:
| 指标 | 含义 | 适合 |
|---|---|---|
| 成功率(pass@1) | 单次运行成功的概率 | 基本指标 |
| pass@k | k 次中至少成功一次的概率 | 可以多试几次、能自动挑出正确结果的场景,比如生成多个方案再跑测试 |
| pass^k | k 次全部成功的概率 | 面向用户、每次都要做对的场景,比如客服 Agent |
pass^k 由 τ-bench 提出,用来衡量可靠性:每个任务跑 n 次、成功 c 次时,pass^k 的估计值是 C(c, k) / C(n, k),再对所有任务取平均;pass@k 的估计方法见 评测指标。比如某个任务跑 5 次成功 3 次:pass@1 = 0.6,pass@3 = 1,pass^3 却只有 0.1,说明 Agent 能做到,但很不稳定。
代价方面,记录 token 和费用、模型调用次数、工具调用次数、总耗时。对比两个版本时看"每个成功任务的成本",而不只是平均每次运行的成本:一个更便宜但经常失败的版本,算下来可能反而更贵。
可复现的评测环境
- 沙箱:每个任务在独立的容器或虚拟机里运行,从相同的初始状态(数据库快照、代码仓库的某个提交)开始,结束后销毁(见 沙箱)
- 模拟工具:发邮件、支付、第三方查询这类外部接口,用模拟实现或录制回放,避免真实的副作用,也让返回结果稳定
- 模拟用户:需要多轮交互的任务,用另一个模型按设定扮演用户(τ-bench 就是这样做的),但模拟用户自己也会出错
- 固定其他变量:模型版本、工具版本、系统时间(比如假定"今天"是某个日期)
代码示例
一条 Agent 评测任务的定义(格式为示意):
- id: refund-partial-001
instruction: 用户想把订单 A1001 里的耳机退款,其他商品保留
initial_state: fixtures/order_a1001.sql # 每次运行前恢复的数据库快照
user_simulator: 被问到时才说出退款原因:耳机有杂音
checks:
final_state: # 结束后在数据库里执行,结果必须符合预期
- sql: SELECT status FROM order_items WHERE order_id = 'A1001' AND sku = 'EARPHONE-01'
expect: refunded
- sql: SELECT COUNT(*) FROM order_items WHERE order_id = 'A1001' AND status = 'refunded'
expect: 1
process:
required_tools: [get_order, create_refund]
forbidden_tools: [cancel_order] # 调用了就直接判失败
confirm_before: [create_refund] # 执行前必须先征得用户确认
max_steps: 12
trials: 5 # 跑 5 次,统计 pass@k 和 pass^k
// 组合数 C(n, k)
function comb(n: number, k: number): number {
if (k < 0 || k > n) return 0
let r = 1
for (let i = 1; i <= k; i++) r = (r * (n - k + i)) / i
return r
}
// 一个任务跑了 n 次,成功了 c 次
const passAtK = (n: number, c: number, k: number) => 1 - comb(n - c, k) / comb(n, k)
const passHatK = (n: number, c: number, k: number) => comb(c, k) / comb(n, k)
passAtK(5, 3, 3) // 1
passHatK(5, 3, 3) // 0.1
面试官可能追问
为什么不能只看 Agent 最后的回答?
Agent 可能说"已经帮你退款了",实际上没有调用退款接口,或者退错了订单;也可能结果对了,但过程中做了危险的操作,比如先取消了整个订单再重新下单。所以要检查真实的最终状态,同时检查过程。
公开的 Agent 基准分数高,能说明在我的业务里表现好吗?
不能直接说明。公开基准反映的是模型和通用 Agent 框架的能力,可以作为选型的参考;你的工具、业务规则、用户的说话方式都不一样,要用自己的任务集来评估。
每个任务跑多次、每次几十步,评测太贵怎么办?
分层运行:一个小的冒烟任务集每次改动都跑,完整的任务集定期跑或在发布前跑。任务之间并行执行,工具的返回用录制回放,减少外部调用。运行次数也可以分步加:先用较少的次数初筛,两个版本差距不明显时再增加。
用模型扮演用户,靠得住吗?
有风险。模拟用户可能不按设定说话,比如一开始就把所有信息都说出来,或者说出设定之外的信息。失败的案例要人工看轨迹,区分是 Agent 的错还是模拟用户的错,并据此改进模拟用户的设定。
易错点
- 相信 Agent 自己说的"任务完成",不检查真实状态
- 只跑一次就下结论,忽略了 Agent 的不稳定性
- 在真实环境里评测,产生真实的副作用;或者环境状态不固定,结果无法复现
- 把危险操作和普通失败同等对待,危险操作应该一票否决
AI 模拟面试官
用自己的话回答,AI 对照参考答案打分、指出遗漏,再追问,最多 3 轮
这道题你掌握了吗?
选一个最接近的状态,没掌握的题会出现在"我的进度 · 待复习"里。
学习记录暂存在本机浏览器。登录后自动同步到账号,换设备也能看到。