Agent Skill评测实战:用skill-up拆解技能验收难题

发布时间:2026/9/4 4:59:26
Agent Skill评测实战:用skill-up拆解技能验收难题 做 Agent 的同学应该都有这种体会链路越长验收越玄学。模型改个 prompt你以为提升了结果一跑全流程前几步的行为变了后面全跟着乱最终分数不升反降。这半年我基本都在跟工具调用类 Agent 打交道也陆陆续续试过不少评测方案最后觉得有一个方向最值得落地——把 skill 从 agent 里拆出来单独测单独打分。阿里最近开源的 skill-up 就是干这件事的它是一套 Agent Skill 评测工具解决的是“某个技能到底行不行”的量化问题。很多人第一次看到这个项目名会以为又是一个新的 Agent 框架其实恰恰相反。它不帮你写 Agent也不帮你编排流程它只做一件事对一个技能做系统化评测输出通过率、失败用例和失败原因让你知道下一次改动应该改哪里。对我来说它补上的正是 Agent 开发里最容易被忽略、也最影响研发效率的那一环——验收。这篇文章我把 skill 和 agent 的区别、skill-up 的设计思路、实际跑通一次评测的完整过程以及我在评测集和裁判设计上踩过的坑都整理出来希望对正在做工具调用类 Agent 的朋友有用。1. 先理清概念skill 和 agent 到底差在哪1.1 你以为你在做 Agent其实你每天都在调 Skill先从一个真实的翻车开始说。我之前做过一个客服场景的 Agent需要查询订单、申请售后、计算退款金额。最开始我是拿“整个 Agent 回答得好不好”来做验收的准备了 100 条端到端问题每天跑一轮看着分数没掉就觉得一切正常。但实际开发里模型本身几乎没有大改我每天改的是什么是工具描述、参数 schema、系统提示词里的使用约束、退款规则说明。这些东西本质上都是一个 skill 的组成部分。问题在于我根本不知道这 100 条端到端问题里有几条真正考到了我改的那个工具。可能我今天把“订单查询”的工具描述改坏了而 100 条用例里只有 5 条需要查订单剩下 95 条全靠闲聊兜底跑完总分居然还涨了。这种评测结果给了我很强的虚假安全感。把 skill 从 agent 的场景里单独拎出来之后情况就完全不一样了。技能就是最稳定的评价单元查询订单是一个技能申请售后是一个技能计算退款金额是一个技能。它们的输入输出边界清楚、评价标准相对客观不会像完整 agent 那样被旁路因素干扰。skill-up 的价值本质上就是帮你把评测粒度下沉到了这一层。1.2 Skill 是一个可以独立验收的“最小单位”要理解 skill-up首先得把 agent 和 skill 的边界划清楚。我用一句话概括Agent 是决策系统Skill 是执行能力。Agent 拿到用户问题之后要决定调用哪个技能、以什么参数调用、调用结果怎么组织成回答而 skill 本身体现的是“给定一个明确任务能不能正确完成”。举例来说“帮我把这个订单退款”是 agent 的任务而“根据订单号计算退款金额并返回结构化结果”是一个 skill 的任务。这个区分非常关键因为两者在开发节奏和验收方式上完全不同。agent 层的改动往往是策略性的比如选择工具、编排多步、处理拒绝skill 层的改动则是能力性的比如工具逻辑、描述语义、参数 schema、约束规则。前者适合用真实场景做端到端抽测后者却完全可以用更小成本、更高覆盖的方式做批量评测。我在实际工作中对两者的定位是这样的对比维度AgentSkill职责范围理解意图、规划步骤、调用技能完成一项具体的原子能力输入形态开放的自然语言对话结构化的任务描述或参数评测难度涉及多步推理结果难量化输入输出边界清楚适合自动化打分缺陷定位很难判断是哪一步出了问题失败基本就是技能自身的问题迭代方式调 prompt 和编排逻辑调工具逻辑、描述、schema 和约束从这个表格能看出来如果评测只做到 agent 层等于把决策层和执行层的问题全混在一个桶里。而 skill-up 这样的工具提供的是一条更高效的路径先把每个 skill 单独测到 90 分以上再来谈整个 agent 的串联效果。否则你连问题出在哪都不知道调 prompt 就是瞎猫碰死耗子。2. skill-up 的思路为什么要把评测粒度打到 skill 层2.1 端到端评测最大的问题混淆“运气”和“能力”继续说端到端评测的毛病。很多人觉得端到端最接近线上真实情况所以最可信。理论上是这样但工程上有一个很现实的困境链路越长中间环节越多最终的结果里噪声就越大你很难把一次失败归因到具体位置。举个例子一条端到端用例“用户想退掉昨天买的耳机”它至少涉及语言理解、意图识别、参数抽取、技能选择、工具调用、结果生成六个环节。任何一个环节出问题最终回答都是错的。但当你看到总失败率是 20% 的时候你根本不知道这 20% 是因为什么。可能是意图分错了可能是参数抽错了也可能是 skill 本身有 bug。想定位问题就得加日志、拆链路、手工复现一次定位通常要花半天。更要命的是很多长链路用例在评测过程中调用了不同的 skill导致你的用例集里每个 skill 的有效样本其实特别少。样本少就意味着偶然性大。LLM 本身有采样随机性同一条用例跑两次都可能不一样你再叠加三层推理最终分数波动几个点太正常了。用这种数据来指导优化纯属自欺欺人。skill-up 的做法是把评测对象从“完整 agent”缩小到“单个 skill”。评测时不再有意图识别和多技能选择的干扰直接给定任务描述看这个技能能否产生预期结果。粒度细了评测集就可以为每个技能单独设计样本可以做到又专又多回归成本也大幅下降。2.2 skill-up 的三段式评测流程从设计上看skill-up 的评测思路可以拆成三段准备技能、准备用例、执行评测。第一步把你的能力封装成一个标准化的 skill 定义包含名字、描述、输入参数 schema、执行逻辑或调用的工具接口第二步为这个 skill 编写一组评测用例每个用例包含输入和期望结果第三步用评测器批量执行把实际输出和期望结果做比对最终生成报告。这里最有意思的是它的评分方式。不是简单对比字符串也不是完全依赖规则而是结合了多种判定方法。对于结构化输出可以做字段级比对对于开放结果可以让评测模型判断输出是否满足预期对于必须严格遵守的约束还可以内置校验函数比如枚举值检查、日期格式检查、数值范围检查。这种“规则为主、模型为辅”的思路在我看来非常务实。因为纯规则的缺点是没有弹性稍微换个句式或者表达方式就误判而纯模型判定的缺点是不可控、不稳定你无法保证它每次的判断标准一致。把格式、枚举、范围、必填字段这类硬约束交给规则把语义是否匹配这类软指标交给模型效果会稳定很多。skill-up 很符合这种工程化思路。2.3 评测报告能回答什么我比较喜欢把评测报告理解为“技能体检报告”。它不只是给你一个总分而是把失败用例摊开告诉你哪些输入让技能失效、失败的模式是什么。比如一个订单查询技能评测完发现失败集中在“订单号带前缀”和“用户 ID 为空”这两类输入上那你下一步的工作重心就非常明确了去打磨参数预处理或者补充描述说明。有了这层信息你就能建立一套“改代码 → 跑评测 → 看失败原因”的快速反馈循环。以前我改一个工具描述要等端到端的大规模回归才能知道好坏现在只需要跑对应 skill 的评测集几分钟出结果。这种效率提升对一个频繁迭代 Agent 的团队来说价值是巨大的。3. 实操还原从 skill 定义到评测报告3.1 第一步准备一份标准化的 Skill 定义要跑 skill-up第一步是把你的能力封装成标准结构。我拿一个真实做过的“订单退款金额计算”技能举例。在这个技能里输入是订单信息输出是结构化退款结果核心逻辑是读取订单金额和退款规则返回可退金额。按照我的使用习惯skill 定义大致长这样{ name: refund_amount_calculator, description: 根据订单实付金额和退款规则计算用户可获得的退款金额, input_schema: { type: object, properties: { order_id: { type: string, description: 订单号形如 ORD123456 }, paid_amount: { type: number, description: 订单实付金额单位元 }, apply_reason: { type: string, description: 用户申请退款的原因 }, goods_received: { type: boolean, description: 用户是否已收货 } }, required: [order_id, paid_amount] }, logic: 按规则计算退款金额, output_schema: { type: object, properties: { refundable_amount: { type: number }, reason_code: { type: string } }, required: [refundable_amount, reason_code] } }不要小看这一步。写清楚 input_schema 和 output_schema不只是为了给评测用它本身就是把业务规则重新梳理一遍的过程。我见过很多团队的技能逻辑是“缝缝补补又三年”连参数有哪些都说不全这种状态根本没办法评测。定义好结构评测才有抓手。3.2 第二步设计评测用例集有了 skill 定义下一步就是写用例。我用的模式是把用例放在一个结构化的文件里每条用例包含输入和期望结果。针对上面这个退款技能我的用例集会覆盖几类情况。首先是正常场景直接算退款金额比如实付 100 元、未收货、七天无理由退款期望结果是可退 100 元其次是边界场景比如实付金额为 0、订单已部分发货、退款原因不符合规则再次是异常输入比如缺参数、金额是负数、订单号格式不对。每一类都会配多条用例确保每个参数变化都有覆盖。{ cases: [ { id: refund_001, name: 未收货全额退款, input: { order_id: ORD123456, paid_amount: 100, apply_reason: 七天无理由, goods_received: false }, expected: { refundable_amount: 100, reason_code: FULL_REFUND } }, { id: refund_002, name: 已收货扣除运费, input: { order_id: ORD654321, paid_amount: 100, apply_reason: 质量问题, goods_received: true }, expected: { refundable_amount: 90, reason_code: DEDUCT_SHIPPING } } ] }这套用例就是后续所有评测的地基。我建议一开始不要贪多先保证每个分支规则至少有正反两条用例。等规则稳定了再逐步补异常输入和模糊输入。评测集的优先级永远是把核心功能守住而不是追求数量上的好看。3.3 第三步配置评测器并执行用例准备好了接下来进入评测执行环节。skill-up 通常通过命令行触发核心就两个参数指定要评测的 skill指定评测集文件。执行之后它会批量调用 skill并把每个输出和期望结果做比对。如果你的 skill 是一个本地函数评测跑起来会非常快如果 skill 需要调用外部大模型接口那评测成本就和用例数量、模型输入输出长度直接相关。我的建议是第一轮评测先跑 50 到 100 条用例量级适中既能看出问题又不会烧掉太多预算。等迭代进入后期再加大样本量做回归。执行完会生成一份报告里面最核心的是通过率、各用例的执行结果、失败用例的具体输出。我拿到报告的第一反应永远是去看失败用例而不是盯通过率那个数字。因为数字只是结果失败用例才是下一步的行动指南。3.4 第四步把“通过”定义清楚实操里最容易被忽略的是“怎样才算通过”。这个不定义清楚后续全是糊涂账。我的做法是把判定分成三层。第一层是硬校验期望结果里的每个字段是否都存在、类型是否正确、枚举值是否合法这类问题没有商量余地第二层是规则比对数值是否在误差范围内、日期格式是否符合预期、内容是否满足约束条件第三层才是语义判断对开放性的回答判断核心信息是否传达完整。在上面的退款技能里refundable_amount 是否等于 100 就是硬校验只要不等于就是失败。process 层还可以加一个容差判断比如涉及四舍五入的场景允许 0.01 的误差。只有把“通过”标准体系化评测结果才能在不同人、不同时间之间保持一致。注意评测标准的稳定性比严格性更重要。宁可标准宽松一点只要有量化记录就能看到趋势但标准如果一成不变加几条新用例就推翻整个基线那回归体系就名存实亡了。4. 比跑分更重要的评测集和裁判怎么设计4.1 用例不是堆出来的是按维度设计出来的我看到很多人在写评测用例时唯一的思路是“多写点”结果写了一堆同质化用例实际覆盖维度却很窄。比如某个技能支持 5 种输入类型前面 50 条用例全在测第 1 种剩下 4 种一次没跑到。这种评测用例再多也没意义。我现在做用例设计时会先列维度表。以技能评测来说至少应该覆盖正常流程、边界条件、异常输入、参数缺失、格式不标准、规则冲突。把这些维度都列出来每个维度再去补具体用例保证测试面的完整。拿“订单查询”类技能举例正常流程就是给一个标准订单号查出来返回正确状态边界条件是订单号很长、订单状态很奇怪异常输入是订单号不存在此时应该返回明确的错误码而不是抛异常。一条用例的价值不在于输入有多复杂而在于它能不能单独检验一类典型行为。另外强烈建议给每条用例加难度或优先级标记。P0 用例是上线前必须全部通过的P1 可以容忍少量失败但需要人工复核。这样在发布节奏很紧的时候你能快速判断“能不能放”而不是被一条无关紧要的失败卡住整体进度。4.2 LLM 当裁判看起来省事坑其实不少skill-up 这类工具之所以能用起来很大程度上是因为 LLM 裁判的出现让很多原来没法自动判定的开放式输出变得可以自动评测。但 LLM 做裁判这件事我踩过的坑比预想的多得多。第一个坑是标准不一致。同一个评测问题我让模型评测两次一次判过一次判不过。把温度调低之后好一些但还是会有波动。后来我学到的办法是在评测 prompt 里把标准写细明确哪些情况算通过、哪些情况算失败最好每条标准都能对应一个可观察的证据。如果你的 prompt 只是说“请判断结果是否正确”那模型就完全靠猜。第二个坑是默认输出宽松。如果被判定的输出内容比较长评测模型很容易只抓其中一个点就判定通过忽略其他错误。针对这个问题我会在 prompt 里要求必须按维度逐项打分最后再综合并且要求给出判断依据。宁可多花一点 token也要把过程搞扎实。第三个坑是模型偏见。评测模型本身如果能力和被测技能所依赖的模型不一样判断可能会有系统性偏差。比如被测 skill 依赖一个开源小模型生成的内容比较简略而评测用的模型水平更高它可能因为“风格不够完整”而误判。所以在评测 prompt 里要明确告诉裁判不要对风格做评判只判断任务目标是否达成。4.3 回归集应该跟着代码一起提交聊一个工程习惯问题。很多团队的评测集是放在一个单独的文件夹里和代码仓库分开维护结果代码改了评测集没同步新功能没有新用例老用例也过时了。我后来把评测集当成代码的一部分和 skill 定义放在同一个仓库同一个目录下每当新增一个功能分支就要求补充对应的评测用例并且跟着 PR 一起提交。这样做的直接收益是当代码合并到主干时评测集一定是最新的回归结果也最能反映当前线上能力。间接收益其实更大评测集成了团队内部的沟通语言。产品说“这个月退款成功率要提升”开发就直接补几条之前失败的用例跑完评测看一眼通过率就能量化地告诉产品“现在到了什么程度”。这种对齐方式比开十次周会都有效。还有一个细节建议每次跑评测都记录一份历史结果。不需要搞大数据平台维护一个 JSON 或者 CSV 就够了。有了历史数据你才能回答“这周比上周到底进步了没有”这种最基础的管理问题。5. 常见问题与排查技巧实录5.1 快速排查速查表实操过程中我整理了一份出现频次比较高的排查速查表按症状、可能原因、处理方式列出来供大家直接参考。症状可能原因处理方式所有用例都失败skill 定义没写对地址或函数名错先用单条用例手工调用一次确认 skill 本身可用部分用例失败但无明显规律评测用例的输入和实际 schema 不一致检查输入里的字段名、类型是否匹配定义预期结果明明是“错误”却被判失败没有把异常场景的期望结果写成错误码在 expected 里明确写出错误码和错误信息分数波动很大两次运行差很多LLM 裁判的 prompt 标准太模糊细化判定规则要求按维度打分并输出依据新代码让老用例失败但新用例全通过行为变更但评测集没有同步更新评测集让回归用例反映新的业务约定评测报告里失败原因解读不出来日志信息太少看不到输入输出上下文让 skill 在评测模式下输出完整中间参数这张表是“事后排查”的兜底方案我建议你把它们沉淀到团队文档里。遇到一类新问题就补一行三个月之后这就是团队最值钱的资产。5.2 我自己踩过的三个坑第一个坑是盲目追求通过率。刚用 skill-up 那阵子我每天盯着通过率看觉得 95% 了就是没问题。结果线上还是出了几单异常全部集中在评测集没覆盖到的场景里。从那以后我给自己定了个规矩通过率只能作为参考指标真正要关注的是失败用例属于哪个维度。如果某一个维度的通过率是 60%那这个技能就还不算稳定。第二个坑是把评测模型和业务模型混为一谈。有一段时间我拿同一个大模型既做业务推理又做评测裁判结果发现评测结果总是“偏乐观”。后来想明白了裁判模型最好和被测模型的水平拉开差距或者至少不能是同一个实例否则它很容易顺着业务的输出圆过去失去了客观性。第三个坑是评测集的过度拟合。有一版技能我为了让评测集通过率更高在代码里写死了几条针对特定测试订单号的 case评测全绿但用户真的拿别的订单号来查照样出错。这是在作弊不是在做工程。从那之后我要求评测集里的用例输入必须来自真实业务分布或随机抽样宁可手工构造也不能用“识别特殊 ID 然后返回固定答案”的方式去骗分。5.3 上线之后评测集还要继续长很多工具跑完首轮评测就变成了摆设这是最大的浪费。一个 skill 评测体系的真实价值是在上线之后通过线上日志持续补充用例的。我在团队里会定期抽一周的线上用户请求把其中命中该 skill 的请求匿名化挑出成功和失败的代表样本加入评测集。每轮迭代跑一遍能非常有效地防止能力回退。长出来的用例要让业务同学和开发同学一起标注。比如一条线上失败的退款请求产品负责人的判断是“用户确实不满意应该多退一点”开发的角度是“规则里没有这条不适用退款”两边观点都补进去评测集就会越来越接近真实业务。这才是评测系统和大模型能力一起进化的正确姿势。从我个人的实操体会来说skill-up 这种工具真正改变的不是跑分环节而是开发习惯。以前我们讨论 Agent 质量全靠拍脑袋和主观感受现在每个人都能打开一份评测报告指着某一条用例说“这次失败是因为这里”这种精确到技能层级的反馈才是把 Agent 工程化最重要的基础。如果团队里还没有类似的评测机制我建议你从这个周末开始选一个核心技能写五十条用例用 skill-up 跑一遍先把病灶看清楚再谈怎么优化。