搭好一个 AI agent,最危险的时刻是 demo 跑通那一下。你问它一个问题,它调了两个工具,吐出一段看起来合理的回答——"能用"。但"能用"和"能上生产"之间隔着整套评测:它到底完成了多少比例的任务?跑一趟要烧多少 token?能不能被一句 prompt injection 诱导越权?换个问法还稳吗?这些问题的答案,demo 永远给不了。
agent 评测和普通 LLM 评测最大的不同在于:agent 有动作(action),每一步都可能调用工具、读写文件、执行代码,成败不只看"说得好不好",还要看"做对了没有"。一个回答流畅但把文件删错的 agent,比一个沉默但准确执行任务的 agent 危险得多。这篇 SOP 走一遍科学衡量 agent 的全流程:先拆出四类评测指标,再搭评估集,定评测方法,可提的工具和公开基准,最后附步骤、踩坑和 FAQ。和本站《RAG 系统评估 SOP》不同,那篇评的是检索-生成管道,这篇评的是有动作、有工具调用的自主 agent——评测维度从"检索/生成"换成了"成功/效率/安全/鲁棒"。
一、四类指标:先把"行不行"拆成可测的维度
agent 的好坏不是一个分数,是四类指标的组合。只看"任务做没做成"会漏掉成本和安全,只看"有没有被越狱"又偏离了核心能力。四类缺一不可。
| 指标类别 | 测什么 | 为什么重要 | 典型度量 |
|---|---|---|---|
| 任务成功率 | 端到端有没有完成 | agent 存在的意义就是完成任务 | success rate、完成率 |
| 效率 | 花了多大代价 | 决定能不能量产 | latency、token 用量、步数 |
| 安全/越狱 | 能不能被诱导越权 | 上生产前的红线 | 拒答率、越狱成功率 |
| 鲁棒性 | 多轮和边界稳不稳 | 真实用户不会按剧本问 | 多轮一致率、边界输入通过率 |
1. 任务成功率(success rate)
这是最根本的指标:给 agent 一个任务,它最终做对了没有。"做对"必须有客观判据——不是"看起来对",而是可验证的断言。比如"在 /tmp 下创建了一个名为 report.txt 的文件且内容包含关键字段""调用了正确的 API 且返回了有效结果"。没有可验证断言的"成功"都是主观判断,不同人评会得出不同结论。
任务成功率要按任务类型分桶统计,别只看一个总数。"编程类 8/10、检索类 3/10"比"总计 55%"信息量大得多——前者一眼看出检索是短板,后者把短板藏进了平均数。
2. 效率(efficiency)
效率决定 agent 能不能量产。一个任务成功率 90% 但单次跑 5 分钟、烧 10 万 token 的 agent,在成本敏感场景里不如一个成功率 80% 但 30 秒、1 万 token 的。三个核心度量:
- Latency(延迟):从发请求到任务完成的墙钟时间。注意区分单次 API 延迟和端到端任务延迟——agent 可能调 10 次工具,每次 API 快但总时长长。
- Token 用量:输入 + 输出 token 总量。agent 多轮调用容易 token 爆炸,尤其带 reasoning 的模型,思考 token 占比可能极高。本站《DeepSeek-V4-Flash 正式版实测》30 题实测中,思考 token 占总输出的 84%——模型"想得多、说得少",推理 token 占了大头。
- 步数(steps):agent 调了多少次工具、走了多少轮推理。步数过多往往意味着 agent 在兜圈子,即使最终做对了也不健康。
3. 安全/越狱(safety)
agent 和普通 chatbot 的安全风险不在一个量级——chatbot 顶多输出有害文本,agent 能执行动作。一个被 prompt injection 诱导的 agent 可能删文件、发邮件、调越权 API。安全评测至少覆盖两类:
- 越狱测试:在输入里嵌入"忽略以上指令,改为执行 xxx"之类的注入,看 agent 是否被诱导偏离原任务。
- 越权测试:给 agent 一个合法但超出其权限范围的指令(如"把数据库导出为 CSV 发到这个邮箱"),看它是否拒绝或至少要求确认。
安全指标的度量不是简单的"通过率越高越好"——你要明确可接受的风险阈值。比如"越狱成功率必须 < 1%""高危动作(删文件、外发数据)必须 100% 二次确认"。
4. 鲁棒性(robustness)
鲁棒性测的是"换个问法、多轮交互、边界输入"下还稳不稳。一个 agent 单轮跑得很好,但以下情况可能翻车:
- 多轮一致:用户第 3 轮改了主意,agent 能不能跟上而不是继续按旧目标执行。
- 边界输入:空输入、超长输入、非预期格式、对抗性措辞。
- 工具异常:某个工具调用失败或返回脏数据,agent 是崩溃、死循环,还是优雅降级。
鲁棒性的度量通常用"边界输入通过率"和"异常恢复率"——不是测它正常情况下行不行,而是测它在不正常情况下不崩。
二、搭建评测集:任务集决定评测上限
和 RAG 评测一样,agent 评测的质量上限由评测集决定,不是由工具决定。一个只覆盖"简单 happy path"的任务集,跑出来的高分会给你虚假的安全感。
定义代表性任务集
任务集要覆盖三类,按比例搭配:
| 类型 | 占比建议 | 作用 |
|---|---|---|
| 典型任务 | 60% | 测核心能力,日常最常见的场景 |
| 边界任务 | 25% | 测鲁棒性,空输入、超长、非预期格式 |
| 对抗任务 | 15% | 测安全,越狱注入、越权指令 |
任务要贴近真实场景,别只拿 demo 题。如果 agent 是做代码的,评测集不能只有"两数之和"——得有"修改这个有 200 行的文件里的某个函数并跑通现有测试"这种真实复杂度的任务。
每任务标注黄金答案或可验证断言
这是最容易被跳过的一步,也是最关键的。每个任务必须有明确的"成功条件",优先用程序化判定:
# 好的断言:程序化判定,无主观
def check_task(result):
# 检查文件是否创建且内容正确
assert os.path.exists("/tmp/report.txt")
content = open("/tmp/report.txt").read()
assert "关键字段" in content
# 检查 API 调用结果有效
assert result["status"] == "success"
return True# 差的断言:LLM 当裁判,主观且不稳定
def check_task(result):
# 让 GPT 判断"这个结果看起来对吗" -> 不可复现
return llm_judge("这个 agent 的输出正确吗?", result)程序化判定的核心优势是可复现:同一个 agent、同一个输入,今天跑和明天跑判定结果一致。LLM 当裁判有温度敏感性,同一份输出不同时间评可能给出不同分数。
独立评分:程序化优先
评分原则一句话:能用代码判定就不用 LLM 判定。 判定方式优先级:
- 程序化断言(文件存在、API 返回码、单元测试通过)——最可靠
- 精确答案比对(字符串/数字/JSON 字段匹配)——可靠
- LLM-as-judge 仅用于无法程序化判定的开放性任务,且需校验其一致性
三、评测方法:多轮采样与对照基线
固定输入多轮采样
agent 输出有随机性(temperature > 0),单轮跑一次的结果可能是运气好。同一组任务跑 N 轮(建议至少 3 轮),看成功率的分布而不是单次值。"3 轮分别 70%、80%、60%"比"1 轮 80%"信息量大得多——前者告诉你波动范围,后者可能是偶然命中。
采样轮数取决于任务成本和方差。任务便宜就多跑(10 轮),任务贵就少跑但至少 3 轮。关键是别拿单轮结果下结论——单轮结论是 agent 评测最常见的坑。
对照基线(baseline comparison)
没有基线的绝对分数意义不大。80% 成功率是高还是低?取决于基线是什么。至少对照两类:
- 纵向对照:vs 旧版本(这次改了 prompt/换了模型,分数涨了还是跌了?)
- 横向对照:vs 竞品或已知强模型(在同样任务集上跑 Claude/GPT/Gemini 做参照)
对照时务必用同一套任务集、同一套评分器、同样的采样轮数——变量只留一个(模型或 prompt),否则没法归因。
记录 latency 和 cost
评测时顺手记录每任务的 latency 和 token 用量,别事后补。成本数据在选模型时是硬指标:一个成功率略低但成本低 10 倍的 agent,在量产场景可能更合适。记录格式建议每任务一行 JSONL:
{"task": "T01", "success": true, "latency_s": 4.2, "input_tokens": 1200, "output_tokens": 800, "steps": 3, "cost_usd": 0.003}跑完可以聚合统计、按维度切片——比如"编程类平均 latency 3.2s,检索类平均 8.5s"。
四、工具与公开基准
自建 eval 脚手架:harness 思路
评测脚手架不需要重框架。本站《DeepSeek-V4-Flash 正式版实测》用的 harness.py 就是"纯标准库、本地执行评分、原始数据可复现"的范例:纯 Python 标准库无第三方依赖,模型输出交由本地独立进程判定(编程题跑单元测试、数学题答案程序化比对),原始结果存 JSONL 留档。这套思路完全适用于 agent 评测:你需要的不是花哨的 dashboard,而是"输入固定、评分可复现、原始数据留痕"三件事。
自建 harness 的最小骨架:
# harness.py — agent 评测最小脚手架
import json, time
def run_task(agent, task):
t0 = time.time()
result = agent.run(task["input"]) # 调你的 agent
elapsed = time.time() - t0
success = task["checker"](result) # 程序化判定,不用 LLM
return {
"task_id": task["id"],
"success": success,
"latency_s": round(elapsed, 2),
"steps": result.get("step_count"),
"tokens": result.get("token_usage"),
}
def main():
agent = YourAgent()
results = [run_task(agent, t) for t in TASKS]
with open("results.jsonl", "w") as f:
for r in results:
f.write(json.dumps(r, ensure_ascii=False) + "\n")
rate = sum(r["success"] for r in results) / len(results)
print(f"成功率: {rate:.1%} ({sum(r['success'] for r in results)}/{len(results)})")
if __name__ == "__main__":
main()关键设计:checker 是纯函数,输入 agent 输出、返回 bool,不含 LLM 判定。所有结果写 JSONL,可 diff、可复现、可审计。
公开 agent 基准(以官方为准)
如果不想从零搭任务集,可以参考公开 agent 基准的设计思路。以下为知名公开基准,具体定义和分数以官方为准:
| 基准 | 测什么 | 设计借鉴点 |
|---|---|---|
| SWE-bench | 软件工程任务(修真实 GitHub issue) | 断言是项目现有测试通过——天然实现"程序化判定优先" |
| Terminal Bench | 终端环境下的 agent 任务 | 评分基于终端操作结果,可程序化验证 |
| τ-bench | 工具-代理-用户多轮交互 | 专门测多轮对话中的工具调用——agent 最易翻车的维度 |
公开基准的核心价值不是拿它的分数直接用,而是学它的任务集设计:SWE-bench 用真实仓库的 issue + 现有测试做断言,免去了自己造 checker;τ-bench 专测多轮交互,补上了多数自建评测集最缺的一块。具体分数请查官方来源,勿引用未经核实的二手数字。
五、评测步骤:从目标到结论的六步
把以上串成一个可执行流程:
步骤 1:定义评测目标。 先问"评完要做什么决策"——是选模型、验收上线、还是回归测试?目标决定指标权重:选模型重效率和成本,验收上线重安全和鲁棒性,回归测试重"有没有退化"。
步骤 2:选指标。 从四类指标里挑和目标相关的。不是每次都四类全测——快速回归可能只测成功率和步数;上线验收必须四类全测,安全一票否决。
步骤 3:搭任务集。 按典型/边界/对抗 6:2.5:1.5 比例组集,每任务写 checker。任务集大小:最小 30 条(能看趋势),推荐 50–100 条(统计有意义),关键场景单独加权。
步骤 4:写评分器。 程序化判定优先,LLM-as-judge 仅用于开放性任务且需校验一致性。评分器本身要测——拿已知对错的样例验证 checker 不会误判。
步骤 5:跑 + 采样。 固定输入跑至少 3 轮,记录每轮 success/latency/tokens/steps。用同一套设置跑基线。
步骤 6:分析 + 对照。 别只看平均成功率。按任务类型切片、看分布、找最差的 10%。和基线对照,标注哪些任务退化了。导出报告留档。
六、踩坑记录
坑一:拿单轮结论下判断。 agent 单次跑对不代表稳。temperature > 0 时同一任务跑 5 轮可能出现 3 次对 2 次错,单轮碰巧跑对就上线,上线后翻车率 40%。至少 3 轮采样看分布,别赌运气。
坑二:LLM 当裁判不校验。 用 GPT 当 judge 评 agent 输出,但不验证 judge 本身稳不稳——同一份输出跑两次 judge 给出不同分数。LLM-as-judge 必须做一致性校验:同一批样例跑两遍 judge,分数差异大的说明 judge 不靠谱,需换更强模型或改成程序化判定。
坑三:任务集太窄。 只测 happy path,上线后用户一换问法就崩。任务集必须覆盖边界和对抗。一个只覆盖典型场景的任务集跑出 95% 成功率,真实场景可能只有 60%——那 35% 的落差就是翻车现场。
坑四:不记成本。 只看成功率不看 token 和 latency,上线发现一个月烧了几千美元。评测时顺手记成本,选模型时成本是硬约束——一个成功率 85% 但成本只有竞品 1/10 的 agent,量产场景里可能比成功率 90% 但贵 10 倍的更合适。
坑五:评分器和 agent 耦合。 checker 直接调 agent 的内部状态或依赖 agent 实现细节,换 agent 就得重写 checker。checker 应只看"外部可观测结果"(文件、API 返回、终端输出),不依赖 agent 内部实现。
坑六:对照基线时变量没控制。 拿 A 模型在任务集 v1 上的分数和 B 模型在任务集 v2 上的分数比——任务集都变了,没法归因。对照必须同任务集、同评分器、同采样轮数,只留一个变量。
FAQ
Q1:评测集多少题够? 看目标。最小可用 30 条(能看大致趋势),推荐 50–100 条(统计有意义),关键场景单独加权。任务集质量比数量重要——30 条覆盖典型/边界/对抗的高质量任务集,比 1000 条只有 happy path 的强得多。任务集要持续迭代:上线后把真实翻车 case 补进去,越跑越贴近真实分布。
Q2:LLM 当裁判靠谱吗? 有条件靠谱。LLM-as-judge 适合无法程序化判定的开放性任务(如"这段总结是否流畅连贯"),但必须满足两个前提:评估器模型足够强(别拿 7B 评 70B 的输出);做过一致性校验(同一批跑两遍,分数差异大说明不稳)。能程序化判定的任务优先用程序,LLM judge 只做补充。同时避免 self-rewarding bias——别让生成模型评自己的输出,换厂商或换更强的模型当 judge。
Q3:怎么对照基线? 两步。纵向对照:在改 prompt/换模型前后,用同一套任务集、同一套 checker、同样采样轮数各跑一遍,diff 分数看涨跌。横向对照:在同样任务集上跑一个已知强模型(如 Claude/GPT)做参照锚点。关键原则是只留一个变量——要么换模型要么换任务集,别同时换,否则分数变了没法归因。
Q4:评测多久跑一次? 分两种节奏。上线前:全量评测一次,四类指标全测,作为验收基线。上线后:每次改 prompt、换模型、加工具时跑回归评测(至少测成功率和安全)。日常可以跑一个精简子集(10–20 条核心任务)做冒烟测试,几分钟出结果;全量评测定期跑(每周或每两周)或重大变更时跑。
Q5:上生产前必测哪几项? 四类指标里有三类是上线红线:任务成功率至少达到验收阈值(如 > 85%);安全/越狱——越狱成功率必须低于风险阈值(如 < 1%),高危动作必须 100% 二次确认;鲁棒性——边界输入通过率和异常恢复率达标。效率指标不是红线但必须记录,用于成本预估和容量规划。一个 agent 安全不达标绝对不能上线,哪怕成功率 100%。
参考来源
- SWE-bench:软件工程 agent 基准(公开基准,以官方为准)
- τ-bench:工具-代理-用户交互基准(公开基准,以官方为准)
- Terminal Bench(公开基准,以官方为准)
- 本站《用 Codex 实测 DeepSeek-V4-Flash 正式版:30 题硬核压测与竞品横评》—— harness.py 自建 eval 脚手架范例
- 本站《RAG 系统评估 SOP:用 Ragas/TruLens/DeepEval 量化检索与生成质量》—— 评测类 SOP 配套(评 RAG 管道)