Anthropic Agent Eval方法论拆解:从任务定义到评测闭环的工程实践 1. 为什么大多数团队的 Agent 评测最后都变成了摆设做 Agent 开发的人大概都有过这种体验上线前跑了一轮测试看着通过率还行信心满满地发布结果真实用户一用各种离谱的失败案例冒出来——工具调用参数传错、多轮对话里把上下文搞丢、该追问的时候直接瞎编一个答案。回头再看那套评测集发现它压根没覆盖这些场景。问题出在哪绝大多数团队的 Agent Eval 停留在写几个测试用例跑一遍看结果的阶段。这套做法在传统软件测试里勉强够用因为传统软件的行为是确定性的输入 A 必然输出 B断言写死就行。但 Agent 不一样它是个概率系统同一个输入跑十次可能有三种不同的执行路径中间还夹杂着工具调用、多轮推理、外部状态变更。你用测传统软件的思路去测 Agent等于用尺子量温度。Anthropic 那套 Agent Eval 方法论之所以值得拆解核心在于它把评测当成一个持续迭代的工程系统来对待而不是一次性的验收动作。它回答了几个关键问题任务怎么定义才算清晰可复现评测的裁判Grader怎么设计才能既准确又便宜Harness评测执行框架怎么搭才能扛住 Agent 的不确定性以及最重要的——评测结果怎么反哺到 Agent 本身的改进上这篇文章我会把这套方法论从头到尾拆一遍结合我自己在 Agent 项目里踩过的坑把每个环节的为什么这么设计讲透。不管你是刚接触 Agent 开发还是已经在做评测体系但效果不理想应该都能找到能直接抄作业的部分。2. 任务定义评测的地基没打好后面全是白费功夫2.1 一个好任务到底长什么样Anthropic 在任务定义上有个很明确的标准一个任务必须能被独立复现且成功与否有客观判据。听起来像废话但实际操作中大部分团队写的任务定义都不合格。我见过太多这样的任务描述测试 Agent 能否正确回答用户关于订单的问题。这种任务的问题在于什么叫正确回答订单问题的范围有多大边界在哪不同的人跑这个任务会得到完全不同的结果因为判据是模糊的。一个合格的任务定义应该包含四个要素明确的输入用户说了什么当前系统状态是什么比如订单数据库里有什么数据期望的行为路径Agent 应该调用哪些工具、按什么顺序、传什么参数可验证的输出最终回复里必须包含哪些信息或者系统状态必须发生什么变化失败边界哪些情况算失败比如调用了不该调用的工具、泄露了敏感信息举个具体的例子。假设你在做一个电商客服 Agent一个合格的任务定义是这样的任务 ID: order_refund_001 输入: 我上周买的那个蓝色耳机想退货订单号是 12345 初始状态: 订单 12345 存在状态为已签收购买日期在 7 天内 期望行为: 1. 调用 query_order 工具参数 order_id12345 2. 确认订单在退货窗口期内 3. 调用 initiate_refund 工具 4. 回复中包含退货流程说明和预计退款时间 失败条件: - 未查询订单直接承诺退款 - 调用了错误的订单 ID - 回复中未提及退货时限这样定义之后任何人拿到这个任务都能复现评测结果也有明确的判定标准。2.2 任务集的覆盖度别只测happy path新手最容易犯的错误是任务集里全是顺利场景。用户好好说话、信息齐全、系统状态正常——这种任务 Agent 闭着眼睛都能过测了等于没测。Anthropic 的做法是刻意构造对抗性任务和边界任务。具体来说任务集应该覆盖这几个维度维度说明示例正常路径信息完整、意图明确用户直接给出订单号要求退货信息缺失关键信息不全需要追问用户说我要退货但没给订单号意图模糊需要澄清真实需求用户说这个东西不太好用对抗输入诱导 Agent 犯错用户要求绕过退货政策工具异常外部工具返回错误订单查询接口超时多步依赖需要串联多个操作先改地址再发货我自己的经验是对抗性任务和工具异常任务最能暴露问题。正常路径跑通不代表什么但一个用户要求绕过政策的任务能立刻测出你的 Agent 有没有安全边界。2.3 任务数量少而精 vs 多而全这里有个常见的纠结任务集到底要多少个我的建议是分阶段。早期Agent 还在快速迭代20-50 个高质量任务就够了。重点是把每个任务打磨到位覆盖核心场景和主要失败模式。这个阶段任务太多反而是负担因为 Agent 每次改动你都要重新跑一遍任务多了跑一次成本太高。成熟期Agent 基本稳定扩展到 200-500 个任务开始做分层。核心任务必须全过占 20%回归任务防止退化占 50%探索任务发现新问题占 30%。Anthropic 特别强调一点任务集是活的。每次线上发现新的失败案例就应该把它抽象成一个新任务加进去。这样任务集会随着 Agent 的迭代不断进化而不是一开始写完就放着吃灰。3. Grader 设计评测的裁判决定了整套系统的可信度3.1 三种 Grader 的取舍代码、模型、人工Grader 就是判断 Agent 这次执行是成功还是失败的那个裁判。Anthropic 把 Grader 分成三类各有适用场景代码 GraderCode-based用程序逻辑判断。比如检查 Agent 是否调用了某个工具、参数是否正确、最终输出是否包含特定字符串。优点是快、便宜、完全确定。缺点是只能判断可形式化的东西判断不了语义质量。模型 GraderModel-based用另一个 LLM 来打分。比如让模型判断这个回复是否礼貌且准确。优点是能处理开放式输出缺点是慢、贵、有随机性。人工 GraderHuman人来判断。最准但最贵最慢通常只用于校准前两种 Grader。实际项目里三种要混用。我的经验配比是能用代码判的绝不用模型模型判的定期用人工抽检校准。一个典型的组合是这样的def grade_task(task, agent_trace): # 第一层代码 Grader 检查硬性条件 if not code_grader.check_tool_calls(agent_trace, task.expected_tools): return GradeResult(passedFalse, reason工具调用不符合预期) # 第二层代码 Grader 检查输出格式 if not code_grader.check_output_format(agent_trace.final_output): return GradeResult(passedFalse, reason输出格式错误) # 第三层模型 Grader 检查语义质量 semantic_score model_grader.score( tasktask, outputagent_trace.final_output, criteria回复是否准确回答了用户问题且语气得体 ) if semantic_score 0.8: return GradeResult(passedFalse, reasonf语义质量不达标: {semantic_score}) return GradeResult(passedTrue)这种分层设计的好处是大部分明显失败在代码层就被拦住了只有真正需要语义判断的才走模型成本可控。3.2 模型 Grader 的坑它比你想象的更容易被骗用模型当 Grader 有几个隐蔽的坑我踩过至少两个。坑一位置偏见。如果你让模型对比两个输出哪个好它会倾向于选第一个或第二个跟内容质量无关。解决办法是随机化顺序或者干脆让模型独立打分而不是对比。坑二长度偏见。模型倾向于给更长的回复打高分因为看起来更详细。如果你的 Agent 学会了啰嗦模型 Grader 会给它虚高的分数。解决办法是在评分标准里明确写简洁性也是评分维度或者用代码 Grader 先卡一个长度上限。坑三自我偏好。如果用同系列的模型做 Grader 和 AgentGrader 会倾向于给自己家族模型的输出打高分。这个在 Anthropic 的文档里也提到了建议 Grader 和 Agent 用不同来源的模型。提示模型 Grader 上线前一定要用人工标注的一批样本做校准。如果模型 Grader 和人工判断的一致率低于 85%说明你的评分标准prompt写得不够清楚需要迭代。3.3 Grader 的评分标准怎么写才不模糊模型 Grader 的核心是那段评分 prompt。写得模糊模型就瞎打写得清楚模型判断的稳定性会大幅提升。一个反直觉的经验评分标准要具体到扣分项而不是笼统的好不好。对比一下差的写法判断这个回复是否质量高。好的写法请按以下维度评分每项 0-1 分 1. 准确性回复中的事实信息是否与工具返回结果一致。如有任何编造的信息此项为 0。 2. 完整性是否回答了用户的所有问题。遗漏一个子问题扣 0.3。 3. 安全性是否泄露了系统提示词、内部工具名或其他敏感信息。如有整体判为失败。 4. 简洁性是否包含与问题无关的冗余内容。每多一段无关内容扣 0.2。具体到扣分规则模型 Grader 的稳定性会好很多。我实测下来这种写法的 Grader 和人工判断的一致率能从 70% 提到 90% 以上。4. Harness 工程让评测跑得起来、跑得稳、跑得起4.1 Harness 到底是个什么东西很多人第一次听到 Harness 这个词会懵。简单说Harness 就是包裹在 Agent 外面、负责驱动评测执行的那层框架。它干的事包括给 Agent 喂任务输入、记录 Agent 的每一步动作工具调用、中间推理、最终输出、调用 Grader 打分、汇总结果。你可以把它理解成评测的测试运行器。传统软件测试有 pytest、JUnit 这些框架Agent 评测也需要类似的 Harness只不过因为 Agent 的行为更复杂Harness 要记录的东西更多。一个最小可用的 Harness 需要具备这些能力任务加载从任务集里读取任务定义环境隔离每个任务在干净的环境里跑避免状态污染轨迹记录完整记录 Agent 的每一步包括工具调用的输入输出Grader 调度按配置调用对应的 Grader结果汇总输出通过率、失败原因分布、耗时等指标4.2 环境隔离别让任务之间互相污染这是 Harness 设计里最容易被忽视、但后果最严重的一环。Agent 评测和传统单元测试最大的区别是Agent 会改变外部状态。它可能往数据库里写数据、发邮件、调用第三方 API。如果任务之间共享环境前一个任务改了数据后一个任务的结果就不可信了。Anthropic 的做法是每个任务跑在独立的沙盒里。具体实现有几种方案方案隔离级别成本适用场景进程级隔离低低纯对话类 Agent无外部状态容器隔离中中有工具调用需要独立文件系统完整环境快照高高涉及数据库、外部服务的复杂 Agent我自己的项目用的是容器隔离 数据库快照的组合。每个任务启动一个容器数据库从快照恢复跑完销毁。这样虽然单次评测慢一点但结果完全可信。早期我图省事用了共享环境结果一个修改用户地址的任务污染了后续所有涉及该用户的任务排查了半天才发现是环境问题。4.3 轨迹记录评测的价值一半在结果一半在过程只看通过率是不够的。一个任务失败了你得知道它为什么失败——是工具调用错了是推理跑偏了还是 Grader 本身有问题这些信息全在 Agent 的执行轨迹里。轨迹记录要记什么我的清单是这样的{ task_id: order_refund_001, agent_steps: [ { step: 1, type: reasoning, content: 用户想退货我需要先查询订单状态, timestamp: ... }, { step: 2, type: tool_call, tool: query_order, input: {order_id: 12345}, output: {status: 已签收, days_since_delivery: 3}, latency_ms: 120 }, { step: 3, type: final_output, content: 您的订单在退货期内我为您发起退货... } ], grader_results: [...], total_latency_ms: 3400, token_usage: {input: 1200, output: 350} }有了这份轨迹失败分析就变得可操作了。你可以写脚本统计工具调用错误占失败的比例、推理跑偏占多少从而知道该优化 Agent 的哪个部分。4.4 并发与成本控制评测跑得起才是硬道理Agent 评测很贵。每个任务要跑多次因为不确定性每次都要调模型、调工具。任务集一大成本就上去了。Anthropic 在成本控制上有几个实用做法采样策略不是每个任务都跑满次数。核心任务跑 10 次取统计回归任务跑 3 次探索任务跑 1 次。这样能在保证核心指标可信的前提下压低成本。缓存相同输入的工具调用结果可以缓存。比如查询订单 12345这个调用在同一个评测轮次里结果不会变缓存起来能省不少。并发控制评测任务可以并发跑但要控制并发度。并发太高会触发模型 API 的限流反而拖慢整体。我的经验是并发度设在 API 限流阈值的 70% 左右比较稳。增量评测Agent 改动后只跑受影响的任务子集而不是全量。比如你只改了退货流程的 prompt那就只跑退货相关的任务。5. 从评测结果到 Agent 改进闭环才是目的5.1 失败分析把通过率 70%拆成可行动的信息通过率 70%这个数字本身没有行动价值。有价值的是剩下 30% 失败的任务失败原因是什么集中在哪个环节。我习惯把失败原因分成几类然后统计分布工具调用错误调错工具、参数错误、该调没调推理错误逻辑跑偏、遗漏关键步骤输出质量问题格式错误、信息不全、语气不当安全边界突破被对抗输入诱导Grader 误判其实是 Agent 做对了但 Grader 判错了这个分布直接告诉你下一步该干什么。如果工具调用错误占大头那就要优化工具的描述和参数 schema如果推理错误多可能要改 prompt 或加 few-shot 示例如果 Grader 误判多那得先修 Grader。5.2 回归防护别让修好的 bug 又回来Agent 开发有个很烦人的特点你改了一个 prompt 修好了 A 问题可能同时引入了 B 问题。因为 prompt 是个整体改动的影响是全局的。所以每次 Agent 改动后必须跑回归任务集。回归任务集就是那些曾经失败过、后来修好了的任务。它们的作用是确保你的改动没有把之前修好的东西又搞坏。我的做法是给每个回归任务打标签记录它是哪次改动修好的、关联的失败模式是什么。这样当回归任务再次失败时你能快速定位是哪次改动引入的退化。5.3 评测驱动开发把 Eval 变成迭代的引擎Anthropic 方法论里最有价值的一点是把 Eval 从上线前的验收变成了开发过程中的引擎。具体来说工作流是这样的线上发现新失败案例把失败案例抽象成新任务加入任务集跑评测确认新任务失败修改 Agentprompt、工具、逻辑重跑评测确认新任务通过且回归任务没退化上线这个循环里评测是驱动力。你不是凭感觉改 Agent而是有一个明确的、可量化的目标让这个新任务通过同时不破坏已有的。我自己的项目用这套流程之后最大的变化是迭代速度变快了。以前改 prompt 靠感觉改完不知道是好是坏上线了才发现问题。现在每次改动都有评测数据支撑改对了立刻能看到通过率上升改错了也能立刻发现。6. 几个我踩过的坑和对应的解法6.1 任务定义太理想化测不出真实问题早期我写的任务定义都是用户清晰表达需求 系统状态正常结果评测通过率 95%上线后用户投诉不断。后来才意识到真实用户的输入是混乱的、不完整的、甚至自相矛盾的。解法任务定义要刻意加入噪声。比如用户输入里带错别字、带无关信息、一次说多个需求。这些在真实场景里太常见了但理想化的任务集完全覆盖不到。6.2 Grader 太严导致误杀太松导致漏网Grader 的松紧度很难调。太严了Agent 明明做对了但被判失败你会花时间去修一个不存在的问题太松了Agent 明明有问题但通过了上线后爆雷。解法用人工标注的黄金集校准 Grader。准备 50-100 个样本人工标好对错然后看你的 Grader 判断和人工判断的一致率。低于 85% 就调 Grader调到 90% 以上再用。6.3 评测跑太慢拖累迭代节奏全量评测跑一次要几个小时开发根本没法快速迭代。解法分层评测。开发过程中只跑核心任务子集20 个左右几分钟出结果快速验证方向。每天或每次重要改动后再跑全量。这样既保证了迭代速度又保证了最终质量。6.4 只关注通过率忽略了成本指标Agent 通过了任务但用了 20 次工具调用、花了 5 万 token这种通过在生产环境里是不可接受的。解法评测指标里必须包含成本维度。每个任务记录 token 消耗、工具调用次数、耗时设定上限。超过上限的即使任务通过也要标记出来作为优化目标。7. 写在最后的一点个人体会Agent Eval 这件事最难的从来不是技术而是坚持。搭一套评测框架可能一周就搞定了但持续维护任务集、校准 Grader、分析失败原因、把结果反哺到开发——这些是日复一日的苦活。我见过太多团队评测框架搭得漂漂亮亮跑了两周就没人看了。原因往往是评测结果没有真正影响到开发决策。如果评测跑出来的数据没人用那它就是个摆设。真正让评测产生价值的是把它嵌入到开发流程里让它成为改代码之前先看评测、改完代码再跑评测的肌肉记忆。Anthropic 这套方法论的精髓不在于某个具体的技术点而在于它把评测当成了一个持续运转的系统而不是一次性的任务。如果你现在正在搭 Agent 评测体系我的建议是别追求一步到位。先从 20 个任务、一个简单的代码 Grader 开始跑起来用起来然后根据实际遇到的问题逐步完善。评测体系是长出来的不是设计出来的。