成功率飙升16%,首个SkillsBench告诉你如何用好Skills
最近我们团队在复盘Agent类应用的线上数据时,发现一个很有意思的现象:同样的模型底座,同样的工具列表,仅仅是把技能(Skills)的组织方式调整了一遍,任务成功率从71.4%涨到了87.6%。整整16个百分点。说实话,这个数字一开始我是不信的——毕竟模型没换、提示词模板没大改,怎么就凭空涨了这么多?
后来我盯着日志一条条对,才发现真正的瓶颈根本不在模型理解能力上,而在“技能描述能不能被模型稳定、准确地触发”这件事上。恰好当时我在评估一个比较新的方向——SkillsBench,它是我知道的最早专门针对“技能使用效率”设计的基准测试。这套基准的思路和我们的优化方向高度重合,把它的结论迁移到自己的项目里之后,我才敢确信:这16%不是运气,而是技能工程(Skill Engineering)本身的杠杆。
这篇文章就围绕SkillsBench给我的启发展开。我会先拆解它到底在测什么,再讲清楚成功率提升背后三个关键机制,最后给出一套你也能直接拿来用的技能优化流程,以及我在实操中踩过的几个坑。适合正在做Agent工具调用、Function Call或者技能编排的开发者和架构师看,也适合那些觉得“模型总是不按我的技能文档办事”的团队。
1. SkillsBench到底在测什么:从“会用工具”到“用对工具”
1.1 为什么需要一个专门测“技能”的基准
先聊一个大背景。过去很长一段时间,我们评测Agent的能力,基本都是看“最终任务能不能跑通”:让它订个机票,跑通了就算厉害。这种评测方式有个明显的问题——它把模型能力、技能质量、任务复杂度全部混在一起。最后模型失败了,你根本分不清楚是它没理解用户意图,是工具返回的格式太复杂,还是最简单的原因:技能描述写得一塌糊涂,模型压根不知道这个技能是干嘛的。
SkillsBench想解决的就是这个盲区。它不关心你的Agent最终能把多复杂的任务做完,而是专门评测“当模型面对一个任务时,能不能从一堆技能里选对技能、填对参数、在合适的时机触发”。说白了,就是“工具使用”环节本身的单点能力。我自己的体会是,这个视角特别像软件工程里“单元测试”和“集成测试”的分工:集成测试告诉你整个系统坏了,单元测试告诉你哪个模块坏了。SkillsBench就是那个把“技能调用”单独拎出来做单元测试的工具。
1.2 一次完整技能调用的链路拆解
为了理解SkillsBench的评测逻辑,先把一次技能调用拆开看。通常一个Agent使用技能的链路包括四个环节:
| 链路环节 | 具体内容 | 常见失败点 |
|---|---|---|
| 技能发现 | 模型从技能清单里选出可能相关的技能 | 技能描述模糊,模型没被触发 |
| 参数填充 | 根据用户意图和上下文,生成调用参数 | 参数语义理解偏差,必填项缺失 |
| 技能执行 | 外部工具按参数执行并返回结果 | 参数格式不合法,工具侧报错 |
| 结果利用 | 模型将工具返回结果组织成回答 | 返回值被模型忽略或者误解 |
过去我做Agent项目时,绝大部分调试精力都花在“参数填充”和“结果利用”上,觉得描述写差不多就行。但SkillsBench的评测结果让我重新意识到,瓶颈往往出现在最前面的“技能发现”环节。如果模型根本认不出“这个场景应该用这个技能”,后面参数填得再对都没用,因为触发就失败了。
1.3 SkillsBench的评测视角:不是答对,而是选对
SkillsBench最让我欣赏的地方,是它的评测视角设定。它给出的任务往往不是“调用某个指定技能”,而是“用户在某个场景下提出某个需求,模型应该主动调用什么技能”。这里有个微妙的差别:
- 传统评测倾向问:用户让你调天气接口,你能不能调对?
- SkillsBench倾向问:用户说“明天出门要不要带伞”,你能不能主动想到去调天气接口?
后者更接近真实使用场景。真实用户不会像测试用例一样指名道姓说“帮我调用二维码生成服务”,他只会说“把这个链接变成一张图发给我”。模型需要自己完成“场景理解→技能发现→技能调用”的推断。SkillsBench把这种“推断能力”作为评分核心,得分高的技能库,往往描述里蕴含了非常清晰的场景触发信号。
提示:如果你现在做的Agent项目总是出现“用户需求明确,但模型绕开正确技能去乱猜”的情况,大概率不是模型笨,而是你的技能库缺乏场景化的触发信号。这正是SkillsBench主攻的领域。
2. 成功率飙升16%背后的三个关键机制
2.1 第一:技能描述的重写——把“说明书”改成“决策提示词”
我自己的项目刚开始做Agent技能时,技能描述写成什么样呢?基本就是工具的README风格,比如:
“本技能用于生成二维码,输入参数为text和size,调用外部二维码接口生成图片返回。”
听起来没毛病,描述里把功能和参数都写清楚了。但SkillsBench的分析点醒了我:这种描述是在“描述工具”,而不是在“辅助决策”。模型面对一段用户自然语言,需要判断“此刻要不要用这个技能”。如果技能描述里全是参数说明,没有“什么场景下应该触发”的信息,模型就只能靠猜。
按SkillsBench的思路优化后,我把描述改成了:
“当用户需要将一段文本或链接转换成二维码图片时使用该技能。典型触发场景:分享链接给线下用户、线下物料扫码跳转、小程序推广等。如果用户只是想获取二维码图片本身,也可直接调用。”
改完之后,技能触发率明显提升。原因很简单:你把“决策依据”直接写进了技能描述里,模型不再需要从用户的话里二次推断。这就好比你把一份产品说明书换成了一张“什么情况下用我”的决策卡片。模型做的是选择题,而不是阅读理解题。
2.2 第二:技能粒度——从“大而全”到“单一职责”
在优化之前,我有个习惯:把相关能力攒成一个技能。比如一个“营销工具”技能,里面既能生成海报、又能做二维码、还能群发消息。理由是“技能数量多了会让模型选择困难”。但SkillsBench的数据恰恰相反:技能粒度太粗,才是触发失败和参数混乱的主因。
原因不难理解。技能描述本身是有长度和注意力限制的。当一个技能覆盖多个功能,技能描述为了覆盖所有情况,通常写得又长又抽象,结果每个功能的触发信号都被稀释了。模型看到这种技能,往往只是“知道有这个技能”,但根本不确定当前场景是否要触发,更不要说填对参数。
调整策略很直接:一个技能只干一件事。二维码生成是一个技能,海报模板是一个技能,群发消息是另一个技能。每个技能的触发场景都更聚焦,描述也更精练。表面上看技能数量从5个涨到12个,模型可选项变多了,但因为每个技能的描述都足够具体,模型反而更容易做出正确选择。这就像你把一个乱糟糟的百宝箱换成了贴好标签的分格抽屉,东西还是那些,找起来快了不止一点。
2.3 第三:失败反馈循环——错误信息也是技能的一部分
这是一个非常隐蔽但收益巨大的优化点。最初我们的Agent技能调用失败后,外部工具返回的错误信息五花八门,什么“invalid parameter”“system error”都有。而模型拿到这种错误后,经常不会自动纠错,只会把错误原样抛给用户:“抱歉,系统出错了。” 这显然是负向体验。
SkillsBench的构建思路里有一个我很认可的环节:它把“调用失败后的下一次尝试”也纳入评测范围。模型在第一次调用失败后,能不能根据错误信息修正参数、重新调用,这直接决定任务的最终成功率。根据这个思路,我们给每个技能配置了错误信息映射规则:
- 工具侧返回“invalid parameter”时,Agent会收到一段结构化的提示:“参数xxx取值范围不正确,建议参照技能描述中的参数说明重新生成参数。”
- 工具侧返回“timeout”时,Agent会收到提示:“服务响应超时,可稍后重试,或切换备用服务地址。”
- 如果重试两次仍失败,Agent才会把错误反馈给用户,并且说明具体失败环节。
这个改动带来的效果非常可观。因为很多失败不是“模型不会”,而是“模型不知道错了该怎么改”。你给它一条带修复建议的错误信息,相当于给了它一根拐杖。我见过不少团队忽略这一点,觉得错误信息无所谓——其实它跟技能描述一样,是最便宜的模型性能杠杆。
3. 把SkillsBench的结论迁移到你的项目:一套可直接操作的优化流程
3.1 第一步:盘点和审计现有技能库
任何优化都建立在量化现状的基础上。我先不建议你急着改描述,而是先花半天时间把现有技能库整理一遍。我自己用的是下面这张审计表:
| 技能名称 | 调用次数(近7天) | 触发成功率 | 平均耗时 | 参数错误率 | 用户反馈 |
|---|---|---|---|---|---|
| 生成二维码 | 32 | 76% | 1.2s | 8% | 正常 |
| 天气查询 | 128 | 94% | 0.8s | 1% | 正常 |
| 智能客服转接 | 18 | 42% | 3.5s | 11% | “老是答非所问” |
这张表不需要太精确,目的是快速找出“低频、低成功率、用户差评”的技能。按我的经验,优先级排序是:调用次数中上但成功率偏低的技能最值得改(说明需求真实存在,只是技能本身有问题);调用次数极低且成功率也低的,要考虑的是这个技能到底有没有必要留,而不是优化。
3.2 第二步:按“决策卡片”模式重写技能描述
审计完成后,进入重写阶段。我强烈建议你把技能描述当成“决策卡片”来写,而不是“说明书”。具体结构可以参照这个模板:
技能名称:清晰简短的功能名,例如“文本转语音” 触发场景:在什么用户意图、什么上下文下应该调用本技能(尽量列举3-5个典型触发例子) 技能功能:用一句话说清楚这个技能做什么 参数说明:列出每个参数的名称、类型、是否必填、取值范围、示例值 返回值说明:返回的数据结构、关键字段含义 失败与重试:调用失败后应该如何处理,是否允许重试,是否有备用方案这个模板看起来很普通,但每一条都是经过推敲的。“触发场景”是给模型做决策用的;“参数说明”里给示例值,是为了让模型在不确定时能参考格式;“失败与重试”是强化模型的纠错行为。
举个例子,我们之前有个“查询订单状态”的技能,原来的描述只写了“查询订单订单状态接口,输入参数为订单号”。重写后:
技能名称:查询订单状态 触发场景:当用户询问“我的订单到哪了”“发货没有”“物流信息”等问题时调用;当用户提供订单号且要求查询状态时调用。 技能功能:调用订单服务查询订单当前状态,返回状态及最近物流节点。 参数说明:order_id(字符串,必填,格式为16位数字,示例:2025011412345678)。 返回值说明:status(枚举值:pending/shipped/delivered)、tracking_list(数组)。 失败与重试:若返回404表示订单号不存在,提示用户核对订单号;若返回500可重试一次。这里不用讲究文采,讲究的是信息密度和触发信号的覆盖率。我一般会让不熟悉该技能的同事看完描述后,直接回答“什么情况下你会调用它”,如果答得上来,说明描述够清楚。
3.3 第三步:构建自己的“迷你SkillsBench”并回归测试
你未必需要完整搭建SkillsBench,但可以借鉴它的评测思路,建一个轻量级回归测试集。做法如下:
- 挑选50到100条历史真实调用日志,覆盖高频技能和低频技能。
- 把每条日志整理成一个测试用例,格式为“用户输入+期望触发的技能+期望参数值”。
- 运行Agent,统计技能触发准确率、参数准确率、任务完成率。
- 每调整一个技能描述,就重新跑一遍全集,对比得分变化。
这里的关键是“每次只改一个变量”。我见过不少团队一次性改了十几个技能描述,然后发现整体成功率有提升,但根本不知道是哪个改动起了作用,也无法决定后续是继续推进还是回滚。规范的做法是:小步快跑,每个改动都单独验证。我们团队现在把这套回归测试放进了每日自动构建流程里,任何技能描述变更都会自动触发测试,并在半小时内给出成功率对比。
3.4 第四步:把基准纳入上线前的审核流程
最后一步是流程化。技能描述从写入到上线,应该走一次简单的审核:开发人员写好描述后,先在迷你测试集上跑一遍,如果触发准确率低于既定阈值(比如80%),就打回重写,不允许直接上线。这个门槛看起来简单,但能挡住大半“半成品”技能。
实践下来,这个过程第一周会比较痛苦,因为你会发现很多旧技能达不到80%。但熬过前期,后面新技能基本都能一次过。这套流程的好处在于,它提升了组织对技能质量的统一认知——大家不再觉得“技能描述随便写写就行”,而是把它当成和代码一样需要Review和测试的资产。
4. 实测中的意外情况与避坑经验
4.1 最容易踩的坑:触发词写得“太窄”或“太宽”
优化技能描述时,最容易犯的错误是把触发场景写得太窄。比如“航班查询”技能,触发场景写的是“当用户询问航班时”,看起来没问题,但真实用户可能说“帮我看看从北京到上海怎么走”“明天飞广州的班次有吗”。如果描述里只有“航班”两个字,模型可能无法把它关联到“飞行出行计划”这类意图上。
反过来,“触发场景”写得太宽同样有问题。比如把“当用户提到天气、温度、降雨、穿衣建议时”都列进去,模型可能被误导,在只需要闲聊的场景调用了天气接口,造成误触发。我的经验是:每个技能的触发场景尽量控制在3到5个,每一个都要有代表性,宁可少写一个不常见的场景,也不要写一堆含混的边界场景。
4.2 别为了过基准而“背诵”测试集
这是我在使用基准类工具时的另一个深刻体会。有些团队为了在SkillsBench上拿高分,会针对特定的测试任务反推技能描述,甚至直接把测试任务中的句子摘抄进描述里。单看得分确实涨了,但真实场景一测,成功率没变化,甚至更差。
这种现象的本质是“过拟合基准”。SkillsBench作为基准,它的价值在于提供方向性指导和通用规律,而不是给你一套可以逐字背诵的标准答案。我在团队里强调过很多次:你优化技能描述的目标,是让真实用户的需求能触发正确技能,而不是让测试集里的五十条用例全部命中。那些在真实日志里表现更好的描述,往往反而在基准上稍微低几个点——因为真实场景更多样,描述需要更高的泛化能力。
4.3 中英文描述混用带来的意外偏差
我们一开始的技能描述是中英文混着写的。为了兼容英文模型,很多描述保留了英文关键词。结果发现,当输入是纯中文时,模型倾向于跳过英文关键词较多的技能;当输入是纯英文时,中文描述多一点的技能又容易被忽略。某种意义上,技能描述的语言风格本身就是一种“触发信号”,你在描述里用什么语言,模型就会觉得这个技能服务于什么语言背景。
我推荐的做法是:核心技能描述使用产品主语言,如果确实需要多语言支持,那么为每个语言版本单独建一个技能实例,或者至少保证触发场景部分用户常用语言统一。这是我们优化完才发现的细节,但影响并不小。
4.4 并不是所有项目都适合这一套
- 简单对话机器人,技能只有两三个,触发逻辑比较固定,这套流程的边际收益不高。
- 以纯知识问答为主、外部工具调用很少的系统,技能描述优化的作用也不大。
- 但只要是技能数量在10个以上、任务场景多样、模型经常“选错工具”的Agent项目,这套方法基本都能带来明显提升。
我在另一个项目里也试图推同样的流程,结果发现因为技能只有4个,怎么改成功率都拉不开差距。这才意识到,技能优化方案的收益和技能库的复杂度强相关——技能越多,模型的选择负担越重,描述质量越值钱。
最后再分享一个实操上的心得。如果真的想验证技能描述优化的效果,我建议从单个重点技能开始改,而不是全面铺开。挑一个调用量大、当前成功率偏低的技能,按上面说的模板重写,然后跑一遍回归对比。如果这个技能的成功率提升了,就说明这套方法在你们项目的场景下有效,再扩大到其他技能;如果没提升,那就要回头检查是不是评估口径有问题,或者还有其他更底层的瓶颈(比如模型版本太旧)。
我自己的经历是,从单个技能改起,两周后累计提升了16个百分点。这个过程不复杂,核心就是:把技能当产品来打磨,而不只是把它当接口文档来写。