ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Agent评测实战手册:从评测集构建到LLM-as-a-Judge落地

Agent评测实战手册:从评测集构建到LLM-as-a-Judge落地 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 结构最后稳定下来的方案是分维度打分 强制排序。具体做法是把评测拆成 3-5 个维度比如“事实准确性”“指令遵循度”“表达清晰度”。每个维度给 1-5 分的明确标准写清楚 1 分是什么样、5 分是什么样。让 Judge 先输出每个维度的分数和理由再给总分。对于同一批样本让 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 评测流水线我一般拆成五个模块用例管理存储评测集支持标签、版本、优先级。执行引擎批量跑 Agent记录每一步的输入输出。评测器规则匹配 Judge 打分输出结构化结果。结果存储把每次评测的结果存下来支持对比。报告生成自动生成可视化报告推送到群里。这五个模块里执行引擎是最容易被低估的。Agent 跑一次可能涉及多次工具调用、多次模型请求如果串行跑 500 条用例可能要几个小时。我的做法是用异步并发但要注意控制并发数避免把下游工具打挂。import asyncio from semaphore import Semaphore async def run_evaluation(cases, agent, max_concurrency10): 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本次评测批次 IDagent_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.80.6P95 延迟3.2s3.5s0.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-url6.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 行不行”而是“告诉团队下一步该往哪走”。
返回列表