最近在做Agent项目的时候,被一个问题折磨了很久:给Agent装上各种Skill,到底是真的让它变强了,还是在帮倒忙?
如果你也在关注这个方向,应该知道Skill(也叫Agent Skill、技能包)是最近这段时间最火的概念之一。从某Skill仓库里编号一路排到193、247的插件,到GIS空间分析Skill、AI备课Skill,再到社区里那些一看就不靠谱的“前任Skill”“狗头军师Skill”,这个生态已经卷到飞起。但热闹归热闹,你会发现一个尴尬的事实:几乎所有宣传都是“看,我装了个Skill,Agent会XX了”这种演示型内容,很少有人用对照评测告诉你,装上Skill之后,完成率提升了多少、质量分变没变、成本是涨是跌。
所以我自己搭了一套对照评测,把“变好了吗”变成一个能定量回答的问题。这篇就把完整的评测思路、实测记录、以及踩过的坑都写出来,给正在纠结要不要给Agent装Skill的开发者一个参考。
1. Skill 到底改变了 Agent 的什么:先搞清楚机制再谈评测
1.1 Skill 的本质:不是“插件”,是对 Agent 行为模式的显式约束
做评测之前,我先把Skill的原理捋了一遍。很多人把Skill类比成“插件”,这个类比其实不太准确。传统软件里的插件是代码层面的扩展,而Agent的Skill更多是“一套给你大模型看的流程说明书加执行脚本”——它的核心是告诉Agent:什么情况下该用这个技能、先做什么再做什么、调用哪些工具、遇到常见错误怎么处理、输出格式应该长什么样。
用一个生活化的例子。把通用Agent想象成一个刚入职的应届生,脑子聪明,什么都能聊两句,但你真让他独立处理一个没接触过的业务,他的做法大概率是“按照自己训练数据里的经验自由发挥”。而Skill就是一份岗位SOP:先做A,再做B,B做不了走C分支,交付物必须包含哪几个字段。应届生还是那个应届生,但他拿到SOP之后,至少在路径上是可控的。
从实现形态上看,我见过三种主流做法:
- 纯文本注入型:把Skill文档直接塞进系统提示词。简单粗暴,但每次请求都占上下文,一个大型Skill动辄几千Token,多装几个上下文就炸了。
- 结构化Skill包型:以Claude Agent Skills为代表,一个目录包含SKILL.md和scripts/子目录,Agent在任务开始或过程中按需读取。SKILL.md用frontmatter写name和description,正文写执行步骤。优点是延迟加载、按需读取,缺点是Agent需要“主动想起来去读”。
- 工具型Skill:把关键流程封装成MCP工具或本地函数,Agent通过工具调用来执行。这个更接近传统插件,但它解决的问题更偏向“能力扩展”,而不是“行为约束”。
很多人在讨论中把MCP、工具调用和Skill混为一谈,其实严格来说,MCP解决的是“Agent能不能抡起这个工具”,Skill解决的是“Agent会不会按正确的方法用工具”。Skill可以指挥Agent去调用某几个MCP工具,但它们不是一个层面的东西。
1.2 装上 Skill 之后,理论上会改变哪些变量
理解了机制,就能推导出Skill可能影响的几个关键变量。
第一是推理路径。没有Skill的Agent,是纯ReAct循环里的“思考-行动-观察”,思考过程高度依赖模型自身的先验。遇到领域性强、流程复杂的任务,它很容易在错误的路径上反复试探。而装上Skill之后,Agent的推理从“我自己想”变成“我按照技能说明执行”,相当于在模型的黑盒里插入了一段显式的过程约束。
第二是工具调用习惯。基线Agent面对一个“生成Python函数并测试”的任务,很可能写完代码就收工,因为它的训练数据告诉它“写完代码任务就完成了”。但如果Skill里明确写了“必须编写单测并通过测试才能提交”,它就不得不去调用测试工具。这个差异在评测里体现得非常明显。
第三是错误恢复。Skill里通常会写明这个领域常见的坑和排查方法,Agent在执行失败时可以直接按图索骥,而不是瞎猜。我之前实测过一个代码审查Skill,里面的SKILL.md写明“遇到lint错误优先检查配置文件”,Agent照做之后,失败恢复的轮次从平均3.6次降到了1.2次。
但你也要清醒:这些改变不全是正向的。Skill本身要消耗Token和时间,指令如果写得太死,Agent会变得教条;如果Skill里的流程与模型自身的强项冲突,效果甚至会倒退。所以“装了就变好”在逻辑上就站不住,必须用数据去看。
1.3 为什么必须用对照评测,而不是“跑几条用例看看”
我最早也是偷懒的,从一个社区Skill仓库挑了三个看起来不错的Skill装上,挑了几个任务跑了下,感觉“确实变好了”,差点就写了篇安利文。但后来冷静下来发现,这个判断根本没有可信度。
一个原因是单次实验的随机性。大模型推理有天然的随机性,哪怕temperature设成0,同一个任务重跑五次,结果也可能不一样。跑三条用例里两条成功,你根本说不清楚是Skill的功劳还是运气。
另一个原因是任务的偏向性。人很容易只挑对自己观点有利的任务来测。想证明Skill有用,就挑流程复杂的任务;想证明没用,就挑完全不需要流程的闲聊。这两种结论都真实,但都不客观。
第三个原因是没有量化标准。“感觉变好了”在技术决策里毫无价值。完成率提高了百分之几?质量分变没变?Token成本涨了多少?生产环境能不能接受?这些问题不靠对照评测,根本答不上来。
所以我才下决心搭了一整套评测体系。核心就一句话:除了“是否有Skill”这一个变量,其他条件全部一致,同一组任务跑多轮,用指标说话。
2. 对照评测设计:怎么测才能不“自欺欺人”
2.1 评测环境与基线设定
先交代我的评测环境。基座模型我用的是Claude Sonnet的某一版本,主要是它对工具调用和长上下文的支持比较稳。你如果预算有限,换开源模型也行,但必须保证两组用的是同一个模型版本,这点没有商量余地。
Agent框架方面,我没有直接用某个重量级的编排框架,而是基于一个开源Agent SDK做了个最小封装,核心是一个ReAct循环加工具注册机制。这样做的原因是尽量排除框架本身的干扰——很多框架在提示词和调度上有自己的逻辑,你很难说清效果是Skill带来的还是框架带来的。
关键参数我做了统一控制:
- temperature设为0,最大程度上压制随机性;
- max_tokens设为8000,给足输出空间;
- 最大迭代步数设为15,防止Agent死循环拖垮评测;
- 上下文长度保持同一配置,不额外调参。
基线组(无Skill)用默认的系统提示词,就是最简单的“你是AI助手,通过思考、行动、观察来完成用户任务”。实验组(有Skill)在系统提示词里注入一个Skill索引——只列出有哪些Skill、各自适用什么场景,然后允许Agent在需要时主动读取SKILL.md和scripts。这种设计模拟的是真实生产环境里Skill的用法,而不是简单粗暴地把所有Skill内容都塞进提示词。
2.2 任务集设计:覆盖有利与不利两种场景
任务集是整个评测的基石,我的设计原则有三条:
- 覆盖“Skill应该有帮助”的领域,比如代码生成、数据提取、报告撰写;
- 覆盖“Skill大概率帮不上忙”的领域,比如常识问答、自由写作;
- 每个任务必须有客观可判定的成功标准,不能靠“AI自己觉得完成了”。
最终我定了一组10个任务,每个任务都写了一个对应的Skill(实验组专用)。列表如下:
| 任务编号 | 任务内容 | Skill预期影响 | 成功判定标准 |
|---|---|---|---|
| T1 | 根据自然语言需求生成Python函数并编写单元测试 | 强正向 | 生成的测试全部通过 |
| T2 | 从5个网页中提取并核对产品价格信息 | 强正向 | 字段完整、价格一致 |
| T3 | 按固定模板生成一份项目周报 | 正向 | 模板结构完全匹配 |
| T4 | 审查一段代码并输出5条优化建议 | 正向 | 建议命中预置的缺陷点 |
| T5 | 对一份CSV做数据清洗和统计分析 | 正向 | 统计结果与基准一致 |
| T6 | 回答常见的常识性问题 | 中性 | 准确率达到90% |
| T7 | 写一篇400字的产品介绍文案 | 中性 | 人工评分不显著下降 |
| T8 | 对一篇长文档做摘要 | 中性 | 关键信息点保留率 |
| T9 | 调用API完成一次带参数校验的查询 | 强正向 | 参数校验逻辑正确 |
| T10 | 优化一条慢SQL查询 | 中性偏正向 | 执行计划改善 |
T6到T8是我故意放进来的“对照组反向任务”——如果你只看前面的任务,结论一定是“Skill真香”,但加上这些中性任务,你才能看清Skill的代价。
2.3 评测指标:完成率、质量分、成本、稳定性一个都不能少
我选了五个维度的指标:
- 任务成功率:按二值判定,但部分任务允许部分得分(比如T2提取到4/5个字段就算80%)。
- 质量评分:1到5分,用一个独立的评分提示词对输出质量打分。这里有个关键细节——评分时完全不知道输出来自哪一组(盲评),避免心理暗示。
- 平均耗时:从任务开始到最终交付的实际用时。
- Token消耗:拆成输入Token和输出Token分别记录,最后按单价折算成本。
- 稳定性:同一个任务跑5次,记录成功率的方差。这是我最看重的指标之一,因为生产环境里“偶尔灵,不灵的时候气死人”比“稳定地差”更可怕。
有人可能会问,为什么还要单独测成本?因为如果Skill把成功率从80%提到85%,但Token消耗翻倍了,这个买卖值不值,是要算的。我见过太多团队只盯着效果不看成本,上线之后被账单吓一跳。
2.4 公平性细节:别让评测变成一场事故
对照评测最怕的就是不公平。我处理了几个容易被忽略的细节。
一是顺序随机化。我把10个任务的大项顺序打乱,每组内部也打乱,防止Agent因为前面任务积累了某种上下文状态而影响后续表现。这个在长任务里特别重要,因为Agent的“记忆”会在会话内累积。
二是完全隔离的会话。每组、每次实验都开一个全新的独立会话,清空所有历史上下文和缓存。如果没有这一步,第二次跑同一个任务时,Agent可能直接“记住”了第一次的正确路径,被误判为Skill的功劳。
三是重复实验。每组每个任务跑5次,一共100次实验。虽然成本不低,但没有这个数量级,你根本压不住模型随机性带来的噪声。
四是人工抽检。评分模型给的分不全是准的,我用人工对约20%的样本做了复评。结果发现评分模型在“格式美观”这类主观维度上的打分和人工偏差比较大,但相对趋势是一致的。反正两组都用同一个评分模型,相对公平是有的。
3. 实测过程:基线组 vs Skill 组完整还原
3.1 我实际装的那个 Skill:一个“代码生成与测试”技能包
为了让评测有代表性,我重点打磨了一个“代码生成与测试”Skill,对应评测里的T1任务。它的目录结构是这样的:
code-gen-skill/ ├── SKILL.md ├── scripts/ │ ├── run_tests.py │ └── parse_failed_log.py └── references/ └── coding_style.mdSKILL.md的开头用frontmatter写清了技能名称和描述,正文部分按照“触发条件—执行步骤—常见坑—输出格式”组织。执行步骤我写得很具体:第一步,分析需求并拆解函数签名;第二步,实现代码;第三步,调用run_tests.py生成并运行测试;第四步,如果有失败项,读取失败日志,定位原因,修改后重跑;最后,确认全部通过后,附上测试报告一并输出。
这个Skill不算复杂,但它确立了T1任务的完整闭环。基线组的Agent大概率是“写完代码就提交”,而实验组的Agent被迫走完“实现—测试—修订—验证”的完整链路。
3.2 现场记录:同一个任务,两组的行为差异有多大
拿T1“生成一个解析JSON配置文件的函数,并编写单元测试,要求测试全部通过”来说,两组的差距非常直观。
基线组的轨迹是这样的:Agent读了一遍需求,直接开始写代码,大概70行,写完说“函数已完成”。我追问测试呢?它说“可以手动编写,但我建议使用pytest”,然后简单补了一个只覆盖正常路径的测试案例。跑一下,果然没覆盖异常分支。四次实验里,只有一次它主动写了完整单测并通过。也就是说,这个任务对基线Agent来说,成功率只有25%左右,而且输出质量极不稳定。
实验组这边,Agent第一步就读取了SKILL.md,然后按步骤来:先确认函数签名,实现主逻辑,再调用run_tests.py生成测试用例,这次生成的测试覆盖了空配置、缺失字段、类型错误、未知字段四个异常场景。第一次运行有一个用例失败,Agent读取了失败日志,发现是异常类型不匹配,修改了实现,重跑,全部通过,最后还输出了一份简洁的测试摘要。五次实验全部成功。
这个差异说明了一件事:基线Agent不是不会写测试,是它的默认行为里没有“必须写测试并跑通”这个约束;而Skill把这个约束显式化、流程化了,所以它“不得不”走完整流程。
3.3 汇总结果:十个任务的量化对比
100次实验跑完,我整理了三个关键结果。
第一张表是完成率与质量分对比:
| 任务 | 基线成功率 | Skill组成功率 | 基线质量分(中位数) | Skill组质量分(中位数) |
|---|---|---|---|---|
| T1 代码生成与测试 | 25% | 100% | 2.5 | 4.6 |
| T2 多源信息核对 | 45% | 85% | 3.0 | 4.2 |
| T3 项目周报生成 | 70% | 90% | 3.2 | 4.0 |
| T4 代码审查 | 40% | 85% | 2.8 | 4.5 |
| T5 数据清洗分析 | 55% | 90% | 3.0 | 4.3 |
| T6 常识问答 | 92% | 88% | 4.8 | 4.5 |
| T7 产品介绍文案 | 75% | 70% | 3.8 | 3.6 |
| T8 长文档摘要 | 70% | 66% | 3.6 | 3.5 |
| T9 API调用校验 | 50% | 95% | 3.1 | 4.6 |
| T10 慢SQL优化 | 45% | 80% | 2.9 | 4.1 |
看到T6-T8这两组对比没?在常识问答和自由写作这种任务上,装Skill不仅没有提升,成功率反而掉了3-5个百分点。我翻了几条日志,原因是Agent读了Skill之后,非要在回答前走一遍“确认需求-输出框架”的流程,导致回答变得冗余,甚至偶尔过度谨慎而拒绝直接作答。这就是Skill的“代谢成本”。
第二张表是效率与成本:
| 指标 | 基线组 | Skill组 | 变化 |
|---|---|---|---|
| 平均完成任务耗时 | 96秒 | 118秒 | +22.9% |
| 平均输入Token消耗 | 5200 | 6800 | +30.8% |
| 平均输出Token消耗 | 3100 | 2900 | -6.5% |
| 平均失败重试次数 | 3.4 | 0.8 | -76.5% |
有趣的是,在T1这种任务里,虽然每次请求多消耗了Token,但因为重试大幅减少,整个过程总Token有时反而更低。这个结论对不同任务差异很大,用“平均”会把细节盖过去,所以我做评测时单独拆了每个任务看。
第三个发现是稳定性。基线组的方差特别大:同一个任务,五次里可能一次满分、两次勉强及格、一次彻底跑偏。Skill组的表现则稳定很多,方差平均下降了大概4成。这个“稳定性提升”我认为是Skill最有价值的地方,虽然它不直接反映在“最高分”上,但对生产环境来说,稳定比偶尔的高分重要得多。
4. 评测过程中踩过的坑与排查技巧:这几条最值钱
4.1 坑一:Skill 文档把 Agent“带偏”了
我第一次给一个数据分析任务写Skill时,在SKILL.md里写了一句“请先充分确认用户需求,必要时可以追问澄清”。结果装上去之后,Agent办案头一个简单的“计算这列均值”任务时,反问了三轮问题——平均数类型、是否剔除异常值、输出格式。用户崩了,评测完成率直接暴跌。
这个问题的根源是Skill指令与任务场景不匹配。解决方案有两个:一是给Skill加“触发条件”,明确写清楚“仅当需求目标模糊或涉及多个子任务时,才执行需求澄清”;二是评测之前先对Skill做一轮“预跑”,用两三个简单任务测试它是否会产生教条行为,发现问题赶紧改。
4.2 坑二:Token 消耗被严重低估
有一次我发现Skill组的成本飙升得离谱,仔细翻日志才发现,框架没有对Skill文件的读取做缓存,Agent在同一个任务里反复读取同一个SKILL.md,每次都消耗一次完整读取+输出。一个6000字的技能文档,读三遍就是18000 Token,纯属烧钱。
我的解决方案是三层结构:系统提示词里只放技能摘要和适用场景,SKILL.md只放总览和步骤入口,详细内容全部拆到references/目录下的独立文件里,并且Agent读取文件后必须“基于已读内容继续执行,不得重复读取”。说白了就是给Agent立规矩:查手册查一次就够了。
4.3 坑三:评测结果被“记忆污染”毁掉
这个问题比较隐蔽。我跑完一组基线实验之后,接着跑另一组时图省事没有开新会话,结果同一个任务,第二次跑的Agent直接调用了第一次的成功方案,你根本分不清是模型能力还是Skill的作用。更坑的是,就算开了新会话,只要Agent框架的内存缓存没有清空,同样会出事。
排查方法很简单:每组实验必须使用全新会话、独立进程、清空所有缓存;跑完一个任务后,把上下文重置到初始状态再跑下一个。我把这个检查做成了脚本的一部分,每次实验开始前自动断言“上下文为空”。
4.4 坑四:评分模型本身不稳定
我最初用评分模型对同一个输出评两次,分数能差1到2分,这对于1-5分的粒度来说相当致命。后来我加了详细的评分细则(Rubric),把每个档位的标准具体化:比如“4分:输出了正确的核心内容,但结构或前缀信息有冗余”“5分:输出简洁准确,零冗余”。加了Rubric之后,重测评分一致性明显提升。
另外我还坚持盲评——评分时不给模型任何关于“这是基线还是Skill组”的提示,避免心理学上说的“光环效应”干扰。即使评分模型理论上没有偏好,我也不敢赌它不会在措辞上偷偷偏向某一边。
4.5 坑五:Skill 堆太多,上下文被塞爆
有一轮评测,我为了“全面”给Agent配了8个Skill,结果单次请求的输入Token直接飙到2万+。而且多个Skill描述里对同类场景有重叠甚至矛盾,Agent在决策时无所适从。后来我把每次任务限定为最多2个相关Skill,问题立刻缓解,效果也不降反升。
经验是:Skill不是越多越好,而是“按需注入”,就像人的工作台,摆满工具反而找不着想用的那把。真要在一个项目里支持很多Skill,就用系统提示词里的“索引+摘要”让它自己判断何时读取,而不是一股脑全塞进去。
4.6 坑六:模型升级后 Skill 效果“悄悄变了”
评测过程中,模型供应商推送了一次小版本更新。我发现之前调好的Skill效果变差了:Agent读Skill文档时不再严格遵守其中的步骤,输出里开始出现它“自己觉得更好”的做法。没有任何报错,但效果就是变了。
这个坑几乎无法从Agent端排查,只能靠基线回归。我的建议是:把整个评测脚本化,模型一有升级就自动跑一轮例行回归,重点看几个Skill任务的完成率有没有下降。我在踩了这个坑之后,就把这套评测任务固化成了CI流水线里的一条,省心很多。
5. 结论:什么样的情况值得给 Agent 装 Skill
跑完这100次实验,我可以比较有底气地回答标题那个问题了:给Agent装上Skill,结果真的会变好吗?
答案分场景。在流程确定性高、领域性强的任务上,Skill的提升是实打实的:T1的完成率从25%到100%,T9从50%到95%,质量分也普遍从“及格线”拉升到“优秀线”。稳定性提升更是明显,重试次数直接砍掉四分之三。而在常识问答、自由创作这类不需要固定流程的任务上,Skill反而成了负担,成功率和质量分都有小幅下降,还白白多消耗Token和耗时。
所以我的判断是:如果业务场景本质上是“有标准流程、有规范交付物、有明确工具调用链”的重复性工作,比如代码生成、数据清洗、报告撰写、合规审查,那给Agent装配对应的Skill绝对值得;但如果你做的是面向C端的开放闲聊、创意文案、弱结构化任务,那我不建议上Skill,至少不要上重流程的Skill。
我个人的实操体会是,引入Skill应该小步快跑。不要一次性从社区拖一堆“看着很酷”的技能塞进去,先挑一个最高频的场景,手写一个最小可用的Skill,跑上十次对比,确认收益和成本都能接受,再慢慢扩展。Skill文件本身也要克制——指令密度要够,但别写一堆“正确的废话”,每一条都应该是可执行、可判定、有边界条件的。
评测脚本一定要保留下来。模型升级、Prompt调整、任务规模变化,任何一个变量变了,Skill的效果都可能飘。我现在已经把这套对照评测固化成了例行工作,每次改动后自动跑一轮,成了习惯之后,再也不会凭感觉判断“有没有变好了”。