点击上方「蓝字」关注我们,每周一篇 AI 工程实战
原创 · AI 工程笔记 · 系列第 2 篇 · 预计阅读 13 分钟
导读:上一篇我们讲了怎么把 Agent 搭起来。但搭起来只是开始——真正难回答的问题是:你怎么知道它是个好 Agent?改了一句 prompt、换了个模型、加了一个工具,它是变好了还是变坏了?这篇给一套能落地的评测方法:怎么造样本、怎么打分、看什么指标,以及 40 行代码的评测框架。
一、为什么 Agent 评测比模型评测难得多
传统模型评测的思路很简单:给一个问题,比一个答案,对就是对、错就是错。准确率、F1、AUC,一套成熟方法论用了十几年。
但 Agent 不行。它有三个独有的麻烦:
· 结果对,不代表过程对 Agent 蒙对了一次正确答案,下次同样的任务就翻车。只看最终输出,你根本不知道它是推理出来的,还是猜出来的。
· 过程对,不代表结果对 它规规矩矩调了三个工具、走完了全部流程,但第三个工具挂了,最终输出一坨垃圾。这时候你罚谁?
· 环境不可复现 昨天的搜索结果和今天不一样,外部 API 会限流、会改返回格式,甚至同一句话模型两次采样给出不同决策。"固定输入 → 固定输出"的范式,在这里直接失效。
所以有个认知必须换过来:Agent 评测不是打分,是回归测试。
你不是在给它评个 85 分,你是在给这套系统建一道防线——确保这次的改动,没有让昨天能跑通的东西今天跑不通。
这个视角一换,后面的所有设计都会顺。
二、评什么:分四个层次,别一上来就端到端
很多团队一上来就跑完整任务,然后失败了也说不清哪儿坏了。正确做法是分层,从下往上建。
L1、L2 一定要自动化、跑得快,因为你要频繁跑;L3 是主体,但对错标准必须提前写死;L4 决定能不能上线,第五节细讲。
一句话:下三层失败,上一层没有意义。端到端成功率只有 60% 时,别急着改 prompt——先去查 L1,大概率是某个工具的参数格式,模型总是传错。
三、造样本:200 条评测集怎么配
评测集(Golden Set)的质量,决定了整个体系的上限。烂样本上跑出来的分数,比没有分数更危险——它会给你虚假的安心。
样本从哪来?三个来源,按价值排序
1. 真实 bad case 回捞(最值钱) 从线上日志、用户吐槽、内测反馈里捞。这是真实分布,也是真实痛点。
2. 人工构造 按业务场景设计,重点覆盖那些"用户一定会问、但你从没测过"的输入。
3. 合成生成 用强模型批量造变体,效率高,但必须人工过筛——模型造的题往往太"正",缺少真实用户的脏话和歧义。
200 条怎么分配?
每条样本长什么样?
- id: order-refund-001 task: "帮我把上周买的那双鞋退掉" expected: must_call: [query_order, submit_refund] must_not_call: [delete_account] final_state: "退款单已创建" constraints: max_steps: 8 max_cost: 0.05 tags: [主流程, 有副作用]
这里有个关键设计:expected 写的是"可接受标准",不是"唯一答案"。
同一个退款任务,Agent 先查订单再退款,和先问用户确认订单号再退款,都对。你不能用字符串精确匹配去卡它,否则你测的不是能力,是它有没有猜中你心里的那条路径。
四、怎么打分:三种方法,按成本递增
方法一:规则评分
能用代码判断的,绝不交给模型。这是铁律。
· 输出是 JSON?校验 schema 和字段类型
· 输出是数字?用容差范围,别用等号
· 要检查工具调用?比对"必须调用"的集合是否齐备
· 要检查没干坏事?检测 must_not_call 有没有被触发
规则评分快、便宜、完全确定。评测集里至少一半样本应该能用规则判掉。
方法二:模型评分(LLM-as-Judge)
开放式输出——比如写的那封客服邮件够不够得体——只能靠模型判。但用它有讲究:
· 评分标准先写死 别只说"判断好不好",要给明确维度:是否回答了用户问题 / 语气是否礼貌 / 有没有编造信息,每项 0 或 1。
· 给 few-shot 示例 至少给一个满分和一个零分的例子,判定会稳定很多。
· 要求结构化输出 让它返回 JSON:score 加 reason,方便后续统计。
还要主动对抗它的三种已知偏见:
| |
|---|
| 模型倾向选第一个。做 A/B 对比时交换顺序各跑一次 |
| 长回答容易被判更好。标准里写明"字数不作为评分依据" |
| |
方法三:人工评分
只用两个地方,别全量上:
1. 定义标准的那一次 先人工标 50 条,看看你定的标准,自己能不能一致地执行。
2. 仲裁分歧 规则和 Judge 打架时,人工看一眼。
全量人工是不可能持续的。评测体系一旦依赖人力,三天后就没人跑了。
五、关键指标:忘掉 Pass@1,看 Pass^k
这是整篇文章我最想让人记住的一点。
Pass@1:同一个任务跑一次,成功就算过。看起来没问题,但 Agent 是随机过程——今天跑通,明天可能就挂。Pass@1 测的是运气。
Pass^k:同一个任务跑 k 次,全部成功,才算通过。
为什么?因为用户的体感就是"我试了三次,有一次不行,这玩意儿不可靠"。一个 Pass@1 是 85% 的 Agent,Pass^3 可能只有 61%(0.85³ ≈ 0.614)。这个数字,才接近你上线后会收到多少投诉。
一个提醒:别只看平均值。平均值很好但 P95 爆掉的系统,上线后就是灾难——因为每天总有那么一批用户,会因为最慢的那 5% 而骂人。
六、动手:40 行的评测框架
import statistics def evaluate(agent, dataset, k=3): """跑完整评测集,返回关键指标""" report = {"total": len(dataset), "passed": 0, "details": []} for case in dataset: results = [run_once(agent, case) for _ in range(k)] ok = all(r["success"] for r in results) # 全过才算过 report["passed"] += int(ok) report["details"].append({ "id": case["id"], "pass_k": ok, "steps": statistics.mean(r["steps"] for r in results), "cost": sum(r["cost"] for r in results) / k, }) report["pass_k_rate"] = report["passed"] / report["total"] return report def run_once(agent, case): """跑一次,返回是否成功、走了几步、花了多少钱""" trace = agent.run(case["task"], max_steps=case["constraints"]["max_steps"]) return { "success": judge(trace, case["expected"]), # 规则 + Judge "steps": len(trace.steps), "cost": trace.total_cost, }这段代码没什么魔法,但它是整套体系的地基。真正花时间的不是这 40 行,而是:
· judge 里那套判定逻辑(规则优先,Judge 兜底)
· 那 200 条样本的设计
· 每次改动之后的对比分析
七、CI 化:让评测从"偶尔跑"变成"每次都跑"
评测最大的敌人不是难度,是没人跑。
把它接进 CI:每次改 prompt、换模型、加工具,自动跑一遍评测,然后和基线对比。
门禁怎么定?三条经验:
1. Pass^k 不能低于基线(允许 ±2% 波动,避免噪声误判)
2. 成本不能涨超 20%(换强模型提升效果可以,但要有代价意识)
3. P95 延迟不能翻倍(翻倍意味着架构上有问题)
别追求 100 分。Agent 永远有失败率,你的目标不是"满分",而是不退化。今天比昨天好一点点,就赢了。
八、五个最容易踩的坑
01 评测集泄露进 prompt 你把样本例子写进了系统提示词里。这等于开卷考试,分数毫无意义。解法:留一份 hold-out 集,只在最终验收时用,平时碰都不碰。
02 只测 happy path 200 条样本里 195 条是正常需求,分数当然好看。解法:强制 40% 以上是边界和失败场景——反直觉,但必须做。
03 评分标准模糊 "判断回答质量"——这句话让 Judge 变成了随机数发生器。解法:把标准拆成可执行的二值判断,判不了就是标准没写好。
04 自己评自己 同一个模型既生成又评判,分数会虚高 10~20 个点。解法:换模型家族做 Judge,或者至少换一个 prompt 模板。
05 只看平均值 平均成本 ¥0.4 很好看,但有一批任务烧了 ¥5。解法:看分位数、看分布。P95 才是你用户真正会遇到的那个体验。
九、七天落地清单
从零开始,七天能建起一套能用的评测体系:
| |
|---|
| 捞 50 条真实 bad case,先跑通手工评测流程 |
| |
| 补齐到 200 条,按 6 : 2.5 : 1.5 分层 |
| |
| 接上 LLM-as-Judge,处理开放输出,跑通全量 |
| 建立基线,产出第一份 Pass^k / 成本 / 延迟报告 |
| |
一周之后,你就有了一个可以持续演进的评测体系。
写在最后
评测这件事,心态上有个坎要过:
它不是用来证明你的 Agent 很行的,它是用来告诉你,它什么时候不行。
一个没有评测的 Agent,你的信心来自"我试了几次都还行"——这是感觉。一个有评测的 Agent,你的信心来自"200 条样本,Pass^3 是 82%,成本 P95 是 ¥0.9"——这是数据。
从感觉走向数据,就是从"会玩"走向"能用"的那道分水岭。
下一篇,我们聊聊最近最热的话题:MCP。为什么一个协议能统一工具生态,以及怎么从零写一个自己的 MCP Server。
如果这篇对你有帮助,点个「赞」和「在看」
转给正在折腾 Agent 的朋友 👇
关注我们,每周一篇 AI 工程实战
让每一次技术投入,都算数