☰
Agent评测实战手册:从评测集构建到LLM-as-a-Judge落地
2026/10/8 4:03:13 网站建设 项目流程

1. Agent 评测到底在评什么:先把靶子立对

做 Agent 评测这件事,我踩过最大的坑不是技术难,而是一开始就没想清楚“评什么”。团队花了两周搭了一套评测流水线,跑了几百条用例,最后发现测的东西跟线上真实场景对不上,白干。所以这篇手册的第一件事,就是把评测目标拆清楚。

1.1 三层评测对象:结果、过程、系统

很多人一提 Agent 评测,脑子里第一反应就是“答对了没有”。这个思路在传统问答场景里没问题,但放到 Agent 上就太窄了。Agent 和普通 LLM 调用最大的区别在于:它是有多步决策的。一个 Agent 可能调了五次工具、走了八步推理,最后答案对了,但中间绕了巨大弯路;也可能答案错了,但过程其实很合理,只是某个工具返回了脏数据。

所以我习惯把评测对象分成三层:

  • 结果层:最终输出对不对。比如任务完成率、答案准确率、结构化字段的匹配度。这是最直观的一层,也是老板最关心的一层。
  • 过程层:中间步骤合不合理。包括工具调用是否必要、参数是否正确、推理链有没有跳步、有没有重复劳动。这一层决定了 Agent 是“碰巧对了”还是“稳定能对”。
  • 系统层:整体运行指标。包括平均步数、token 消耗、端到端延迟、失败重试率、异常中断率。这一层直接关系到成本和用户体验。

三层缺一不可。只测结果,你会被“运气好的 Agent”骗;只测过程,你没法跟业务方交代。我的建议是:结果层作为准入门槛,过程层作为优化抓手,系统层作为上线红线。

1.2 不同阶段的评测重点完全不一样

同一个 Agent,在 demo 阶段、内测阶段、上线阶段,评测重点应该动态调整。我见过太多团队用一套评测集从头跑到尾,结果就是早期被细节拖死,后期被漏测坑死。

阶段核心目标评测重点用例规模通过标准
Demo 验证能不能跑通结果层为主20-50 条完成率 > 60%
内测迭代稳不稳定过程层 + 结果层100-300 条完成率 > 85%,工具调用正确率 > 90%
上线前能不能扛系统层 + 全层500+ 条完成率 > 90%,P95 延迟达标
线上监控有没有退化抽样 + 回归集持续采样无显著下降

这张表不是拍脑袋来的,是我在几个项目里反复调整后总结的。Demo 阶段你要是追求 90% 完成率,基本等于自虐,因为很多边界情况还没覆盖。上线前你要是只看完成率不看延迟,用户分分钟教你做人。

1.3 评测集构建:别一上来就想着“大而全”

热词里有个词叫“agent评测集构建”,这确实是核心难点。我的经验是:评测集的质量远比数量重要。500 条精心设计的用例,胜过 5000 条随机爬来的问题。

构建评测集时,我一般按这个维度来分层:

  • 核心路径:用户最常走的流程,占 40%。比如一个客服 Agent,核心路径就是“查订单-改地址-确认”。
  • 边界情况:参数缺失、格式异常、多意图混杂,占 30%。这类用例最容易暴露 Agent 的鲁棒性问题。
  • 对抗样本:故意诱导 Agent 犯错,占 15%。比如让它在信息不足时强行编造答案。
  • 长尾场景:低频但真实存在的需求,占 15%。这类用例不追求覆盖全,但要有代表性。

注意:评测集不是一次性的。每次线上发现新问题,都要反哺回评测集。我习惯给每条用例打标签,方便后续按维度分析。

2. 评测方法选型:LLM-as-a-Judge 不是万能药

“怎么评”这个问题,本质上是在问:用什么手段来判断 Agent 的输出好坏。目前主流就三条路:人工评测、规则匹配、模型评测。热词里的 LLM-as-a-Judge 属于第三条,但它不是银弹。

2.1 三种评测手段的适用边界

先上一张对比表,这张表我建议直接贴在工位上:

手段成本速度一致性适用场景不适用场景
人工评测极高极慢中主观质量、复杂推理大规模回归
规则匹配低快高结构化输出、关键词开放式生成
LLM-as-a-Judge中中中高语义相似、多维度打分强事实性校验

人工评测的问题不用多说,贵且慢,但它在“主观质量”判断上仍然是金标准。规则匹配适合那些有明确答案的场景,比如“订单号必须是 12 位数字”。LLM-as-a-Judge 则填补了中间地带:它能理解语义,但又比人快得多。

我的实操策略是:规则匹配打底,LLM-as-a-Judge 做主力,人工评测做校准。具体来说,先用规则过滤掉明显错误的输出,再用 Judge 模型对剩余输出做多维度打分,最后每周抽 5% 的样本人工复核,用来校准 Judge 的偏差。

2.2 LLM-as-a-Judge 的坑与调优

用 Judge 模型评测,最容易犯的错就是“直接问模型好不好”。这种问法得到的分数基本没有区分度,模型倾向于给中间分。我试过很多 prompt 结构,最后稳定下来的方案是分维度打分 + 强制排序。

具体做法是:

  1. 把评测拆成 3-5 个维度,比如“事实准确性”“指令遵循度”“表达清晰度”。
  2. 每个维度给 1-5 分的明确标准,写清楚 1 分是什么样、5 分是什么样。
  3. 让 Judge 先输出每个维度的分数和理由,再给总分。
  4. 对于同一批样本,让 Judge 做两两对比,而不是绝对打分。
# Judge prompt 的核心结构示例 judge_prompt = """ 你是一个严格的评测员。请根据以下标准对 Agent 的输出打分。 维度1:事实准确性 1分:包含明显事实错误 3分:事实基本正确但有遗漏 5分:事实完全正确且完整 维度2:指令遵循度 1分:完全忽略用户指令 3分:部分遵循但有偏差 5分:完全遵循且无多余动作 请先输出每个维度的分数和理由,再输出总分。 """

实操心得:Judge 模型的温度参数建议设成 0,否则同一批样本跑两次分数会飘。另外,Judge 模型最好比被测模型强一个档次,否则容易出现“看不懂所以给高分”的情况。

2.3 规则匹配的隐藏价值

很多人觉得规则匹配太 low,不屑于用。但我在实际项目里发现,规则匹配在回归测试中的价值被严重低估了。Agent 迭代频繁,每次改 prompt 或换模型,都可能引入退化。这时候用规则匹配跑一遍核心用例,几分钟就能发现明显问题,根本不需要动用 Judge。

我常用的规则包括:

  • 输出格式校验:JSON 能不能解析、必填字段在不在。
  • 关键词命中:关键信息有没有出现在输出里。
  • 长度约束:输出是不是过长或过短。
  • 工具调用序列:有没有调用不该调用的工具。

这些规则写起来快,跑起来更快,是评测流水线的第一道防线。

3. 评测落地:从脚本到流水线的完整实现

聊完“评什么”和“怎么评”,接下来是最硬核的部分:怎么把评测真正跑起来。我见过太多团队停留在“写了个评测脚本”的阶段,每次要评测就手动跑一下,结果就是评测频率越来越低,最后不了了之。真正的落地,必须做成自动化流水线。

3.1 评测流水线的整体架构

一条完整的 Agent 评测流水线,我一般拆成五个模块:

  1. 用例管理:存储评测集,支持标签、版本、优先级。
  2. 执行引擎:批量跑 Agent,记录每一步的输入输出。
  3. 评测器:规则匹配 + Judge 打分,输出结构化结果。
  4. 结果存储:把每次评测的结果存下来,支持对比。
  5. 报告生成:自动生成可视化报告,推送到群里。

这五个模块里,执行引擎是最容易被低估的。Agent 跑一次可能涉及多次工具调用、多次模型请求,如果串行跑 500 条用例,可能要几个小时。我的做法是用异步并发,但要注意控制并发数,避免把下游工具打挂。

import asyncio from semaphore import Semaphore async def run_evaluation(cases, agent, max_concurrency=10): sem = asyncio.Semaphore(max_concurrency) async def run_one(case): async with sem: result = await agent.run(case.input) return {"case_id": case.id, "output": result} tasks = [run_one(case) for case in cases] return await asyncio.gather(*tasks)

注意:并发数不是越高越好。我试过设成 50,结果下游的检索服务直接超时,评测结果全是失败。后来稳定在 10-20 之间,具体看下游服务的承载能力。

3.2 评测结果的结构化设计

评测结果如果只是一堆文本,后续根本没法分析。我要求每次评测的输出必须是结构化的,至少包含这些字段:

字段类型说明
case_idstring用例唯一标识
run_idstring本次评测批次 ID
agent_versionstringAgent 版本号
final_outputstring最终输出
stepsint执行步数
tool_callslist工具调用记录
latency_msint端到端延迟
token_usageinttoken 消耗
rule_scorefloat规则匹配得分
judge_scoresdict各维度 Judge 得分
passedbool是否通过

有了这套结构,后续做趋势分析、版本对比、问题定位都方便得多。我习惯把结果存到一张宽表里,然后用 SQL 直接查“哪个维度的得分在最近三次评测中持续下降”。

3.3 版本对比与回归检测

Agent 迭代最怕的就是“改了一个地方,坏了另一个地方”。所以每次发版前,我都会跑一次全量回归,然后跟上个版本做对比。

对比的核心指标有三个:

  • 通过率变化:整体通过率下降超过 2% 就要警惕。
  • 新增失败用例:上个版本通过、这个版本失败的用例,必须逐条分析。
  • 修复用例:上个版本失败、这个版本通过的用例,确认是不是真的修好了。

我一般会生成一张对比表,直接贴到发版评审里:

指标上个版本当前版本变化
整体通过率87.3%89.1%+1.8%
核心路径通过率92.0%93.5%+1.5%
边界情况通过率78.5%76.2%-2.3%
平均步数4.24.8+0.6
P95 延迟3.2s3.5s+0.3s

这张表一出来,问题就很明显了:整体通过率涨了,但边界情况退化了,而且步数和延迟都涨了。这时候就要去看边界情况的失败用例,大概率是新加的某个功能影响了鲁棒性。

4. 常见问题与排查技巧实录

评测做久了,遇到的问题五花八门。我挑几个最高频的,把排查思路和解决方法整理出来,方便你直接抄作业。

4.1 Judge 打分不稳定怎么办

这是最常被问到的问题。同一批样本,今天跑出来 85 分,明天跑出来 78 分,根本没法用。原因通常有三个:

  • 温度参数没设成 0:这是最低级的错误,但真的很多人犯。
  • Prompt 里有模糊表述:比如“回答得好就给高分”,什么叫“好”?模型理解不一致。
  • 样本顺序影响:Judge 模型对上下文敏感,如果一批样本里前面都是高质量回答,后面一个中等质量的回答可能被压低。

解决方法:温度设 0,评分标准写具体,每批评测前打乱样本顺序,并且固定随机种子。

4.2 Agent 输出格式不稳定怎么评

Agent 有时候输出 JSON,有时候输出 Markdown,有时候还夹带解释性文字。这种情况下,规则匹配基本失效。我的做法是先做输出归一化:用正则或轻量解析器,把输出里的结构化部分抽出来,再拿去评测。

import re import json def normalize_output(raw_output): # 尝试提取 JSON 块 json_match = re.search(r'\{.*\}', raw_output, re.DOTALL) if json_match: try: return json.loads(json_match.group()) except json.JSONDecodeError: pass # 兜底:返回原始文本 return {"raw": raw_output}

实操心得:归一化逻辑本身也要有测试用例。我见过归一化代码把合法 JSON 解析错的,导致评测结果全错。

4.3 评测集“过期”了怎么办

业务在变,评测集如果一直不更新,就会逐渐失去代表性。我的做法是每月做一次评测集审计:

  • 统计每条用例的失败率,长期 100% 通过的用例考虑降权或移除。
  • 检查用例是否还符合当前业务场景,过时的直接删。
  • 从线上日志里采样新的真实问题,补充进评测集。

这个过程听起来麻烦,但比“评测集跑出来全是高分,线上却天天出问题”要好得多。

4.4 评测成本太高怎么控

Judge 模型调用是要花钱的,500 条用例每条调 3 个维度,就是 1500 次模型调用。如果每天跑一次,成本很可观。我的控本策略是:

  • 分层评测:核心用例每天跑,全量用例每周跑。
  • 规则优先:能用规则判断的,绝不调 Judge。
  • 缓存复用:同一批样本的 Judge 结果缓存起来,没变化就不重复调。
  • 小模型打底:先用小模型做初筛,只把有争议的样本交给大模型。

这套组合拳下来,评测成本能压到原来的三分之一左右。

4.5 常见问题速查表

问题现象可能原因排查方向解决方法
Judge 分数波动大温度非 0、标准模糊检查 prompt 和参数温度设 0,标准量化
规则匹配误判输出格式不统一看原始输出加归一化层
评测跑得慢串行执行、并发低看执行日志异步并发,控制并发数
通过率虚高用例太简单分析用例分布补充边界和对抗样本
版本对比无差异评测集太小看用例数量扩充到 300+ 条
线上问题测不出评测集过期对比线上日志定期审计和补充

这张表我建议打印出来贴在显示器旁边,遇到问题先扫一眼,能省不少排查时间。

5. 评测之外:那些容易被忽略的细节

评测本身是技术活,但真正决定评测价值的,往往是技术之外的东西。这部分我分享几个踩坑换来的经验。

5.1 评测指标要跟业务指标对齐

技术团队容易陷入“指标自嗨”:完成率从 85% 提到 92%,觉得很厉害,但业务方关心的可能是“用户投诉率有没有降”。如果评测指标跟业务指标脱节,评测做得再好也没人认。

我的做法是:每个技术指标都要能找到对应的业务指标。比如“工具调用正确率”对应“任务一次完成率”,“平均步数”对应“用户等待时长”。这样在汇报时,才能说清楚评测的价值。

5.2 评测报告要让人看得懂

我见过很多评测报告,满屏都是数字和术语,业务方看了直摇头。好的评测报告应该做到:一页纸说清楚结论,附录里放细节。

报告结构我一般这样组织:

  • 第一页:整体通过率、关键指标变化、是否建议发版。
  • 第二页:分维度得分、失败用例分类。
  • 附录:具体失败用例、Judge 打分理由。

实操心得:报告里一定要有“结论先行”。老板没耐心看你分析过程,先把结论甩出来,再解释原因。

5.3 评测不是终点,而是起点

最后说一个心态问题。很多人把评测当成“发版前的最后一道关卡”,跑完就完事了。但在我看来,评测的真正价值在于驱动迭代。每次评测发现的失败用例,都是下一轮优化的输入。评测-分析-优化-再评测,这个循环转起来,Agent 才能持续变好。

我现在的习惯是:每次评测后,把失败用例按原因分类,然后直接开一个优化会,当场定下改进方案。这样评测就不是一个“检查动作”,而是一个“生产动作”。

5.4 关于 Agent 安全评测的补充

热词里提到了“agent安全”,这块确实越来越重要。除了常规的功能评测,我建议至少加上这几类安全用例:

  • 越权操作:Agent 会不会执行超出权限的工具调用。
  • 信息泄露:Agent 会不会在输出里暴露敏感信息。
  • 诱导攻击:用户故意诱导 Agent 做出不当行为。
  • 资源滥用:Agent 会不会陷入死循环,疯狂调用工具。

这些用例不需要多,但必须有。我一般放在单独的“安全评测集”里,每次发版前必跑。

6. 一套可直接复用的评测方案模板

聊了这么多,最后给一套可以直接抄的评测方案模板。这套模板我在三个项目里用过,基本不需要大改。

6.1 目录结构

agent-eval/ ├── cases/ # 评测集 │ ├── core.jsonl # 核心路径 │ ├── edge.jsonl # 边界情况 │ ├── adversarial.jsonl # 对抗样本 │ └── safety.jsonl # 安全用例 ├── evaluators/ # 评测器 │ ├── rule_based.py # 规则匹配 │ └── llm_judge.py # Judge 评测 ├── runner/ # 执行引擎 │ └── async_runner.py ├── reports/ # 评测报告 └── config.yaml # 配置文件

6.2 配置文件示例

evaluation: concurrency: 10 timeout_seconds: 60 retry_times: 2 judge: model: "your-judge-model" temperature: 0 dimensions: - name: "事实准确性" weight: 0.4 - name: "指令遵循度" weight: 0.4 - name: "表达清晰度" weight: 0.2 rules: - type: "json_valid" weight: 0.3 - type: "keyword_hit" keywords: ["订单号", "金额"] weight: 0.3 - type: "length_limit" max_length: 2000 weight: 0.4 report: output_dir: "./reports" notify_webhook: "your-webhook-url"

6.3 执行入口

import asyncio from runner.async_runner import AsyncRunner from evaluators.rule_based import RuleEvaluator from evaluators.llm_judge import LLMJudge async def main(): runner = AsyncRunner(config_path="./config.yaml") cases = runner.load_cases("./cases") results = await runner.run(cases) rule_eval = RuleEvaluator(config_path="./config.yaml") judge_eval = LLMJudge(config_path="./config.yaml") for result in results: result["rule_score"] = rule_eval.evaluate(result) result["judge_scores"] = await judge_eval.evaluate(result) runner.save_results(results, "./reports") runner.generate_report(results) if __name__ == "__main__": asyncio.run(main())

这套模板跑起来后,每次评测只需要更新用例集,然后执行入口脚本,报告会自动生成并推送。我实测下来,500 条用例从执行到出报告,大概 15 分钟,完全能接受。

6.4 后续扩展方向

这套方案目前覆盖了功能评测和安全评测,后续还可以往这几个方向扩展:

  • 多轮对话评测:现在的用例大多是单轮的,多轮场景需要单独设计。
  • RAG 专项评测:如果 Agent 用了 RAG,需要单独评测检索质量和答案忠实度。
  • 成本评测:把 token 消耗和工具调用成本纳入评测指标。
  • A/B 评测:支持同时跑两个版本的 Agent,直接对比。

我个人在实际操作中的体会是:评测体系不是一次搭好的,而是随着 Agent 一起成长的。先跑起来,再慢慢完善,比一开始就追求完美要靠谱得多。踩过几次坑之后,你会发现,评测最大的价值不是“证明 Agent 行不行”,而是“告诉团队下一步该往哪走”。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询