news 2026/9/8 22:12:27

Agent Skills实战:从设计到落地,构建可复用的AI能力包

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Agent Skills实战:从设计到落地,构建可复用的AI能力包

说真的,最近一年我几乎天天在跟Agent打交道。框架从LangChain换到CrewAI再换到官方SDK,折腾一圈之后才弄明白一件事:真正决定一个Agent好用不好用的,往往不是模型选得多大、框架铺得多全,而是你到底给它配了什么样的skills。

这词这两年快被说烂了,但能讲到点子上的人真不多。很多人把它理解成“长一点的prompt”,也有人把它跟function calling混为一谈,其实都不准确。Skills的本质,是给AI一套“可复用、可执行、还能自己判断什么时候用”的能力包。它解决的不是“模型怎么说”的问题,而是“模型怎么做”的问题。

这篇文章不聊虚的。我会把一个skill从设计思路、内部结构到落地的完整过程摊开来讲,最后手把手带大家写一个能生成和解析二维码的skill,并接进Agent里跑通。正在做Agent应用的朋友可以把它当工程参考;就算你不写代码,看完也能理解为什么同一个模型在不同人手里,效果能差出几条街。

1. 先想清楚:Agent Skills到底在解决什么问题

1.1 从一次失败的批量文件处理说起

上个月我接了个活儿,帮朋友把十几个CSV文件合并清洗,再转成Excel。一开始图省事,直接在对话里把需求丢给AI,让它“写段代码帮我把这堆CSV处理了”。模型确实给了一段Python,我复制到终端跑,报错,粘贴回去让它改,再跑,再报错。来来回回折腾了七八轮,最后我放弃了,干脆自己写。

这事给我刺激挺大。问题不在于模型写不出能跑的代码,而在于它只负责“给建议”,不负责“把事办成”。代码要放到什么目录、依赖装没装、文件编码对不对、有没有权限写文件——这些执行层面的破事,纯prompt根本覆盖不到。

后来我换了思路,把“CSV合并清洗”做成了一个skill。目录里放好脚本,SKILL.md里写清楚依赖、调用方式、出错怎么处理。再让同一个模型处理同样的任务,它自己判断“这活儿适合用csv_processor技能”,然后调用脚本,几分钟后直接把合并好的Excel给我。

同样一个模型,差别就这么大。原因很简单:prompt给的是“说法”,skill给的是“做法”。

1.2 Skills与Prompt、Function Calling、RAG的本质区别

很多朋友问我,skills跟function calling到底是不是一个东西。这里用一张表说明白。

方案机制优点局限典型场景
Prompt用指令约束模型输出灵活、零成本不真正执行,结果不稳定写文案、总结、翻译
Function Calling预先定义好函数接口,模型选择调用可控性强、输出结构化每个能力都要提前暴露接口,扩展麻烦查天气、下单、查库存
RAG检索外部知识库,拼进上下文让模型获得最新/私有知识只解决“知道什么”,不解决“会做什么”客服问答、企业知识库
Skills打包脚本+说明文档,模型自主调度可复用、可执行、扩展成本低需要调试描述和脚本,门槛略高批量文件处理、图像操作、系统运维

补充一下,function calling和skills并不冲突,很多场景两者一起用:skill负责把“一个完整任务”拆成流程,流程里的单个步骤可以再走function calling调用接口。但从开发体验上说,skill的粒度更接近人的任务习惯,而且它把“能力+使用说明+错误处理”打包成了一个整体,方便复用和分发。

1.3 什么场景才值得上Skills,什么场景别硬凑

不是所有任务都值得做成skill。我自己的判断标准就三条:高频复用、逻辑确定、需要外部执行。高频复用指的是你隔三差五就要做一遍的活儿,比如图片压缩、PDF转Word、日志分析;逻辑确定指的是流程稳定,不需要模型自由发挥;需要外部执行指的是涉及文件、系统命令、网络请求这类模型本身碰不到的东西。

反过来,纯创意任务、需要大量主观判断的任务、一次性的临时任务,都不适合上skill。道理很简单:skill把流程固化了,相当于把“人类的熟练工”变成了“自动流水线”,流水线适合重复劳动,不适合开盲盒。

还有一个容易踩的坑:为了上skill而上skill。有人觉得Agent不配几个skill就不高级,非要把“写周报”也做成skill。结果是脚本越来越复杂,模型调用越来越混乱,维护成本直线上升。说句实在话,三行prompt能搞定的需求,千万别硬套skill。

2. 解剖一个Skill:目录结构、SKILL.md与描述写作规范

2.1 最小可用的Skill目录长什么样

一个标准的skill,从文件结构上看其实特别简单,通常就两三样东西。以我现在的代码库为例:

qr-skill/ ├── SKILL.md └── scripts/ ├── generate_qr.py └── decode_qr.py

SKILL.md是技能的说明书,也是模型唯一会主动去读的文件。scripts目录放的是真正干活的脚本,模型不会直接读脚本源码,它只认说明书上的调用方式。这一点特别关键:模型就像一个从没来过你家的实习生,它不关心你柜子里怎么布局,你给它一份图文并茂的说明书,它就按说明书操作。

有些复杂一点的skill还会带assets目录放静态资源,或者带requirements.txt管理依赖,但这些都是锦上添花。一个最小可用的skill,只要SKILL.md加一个能跑的脚本就够了。

2.2 SKILL.md写法:description是灵魂,正文是说明书

SKILL.md的结构分两块:开头的YAML frontmatter和正文。

frontmatter里最重要的就是description。这个字段决定模型在什么情况下会想起你的skill,写得好不好,直接决定它是“被频繁调用”还是“躺在仓库里吃灰”。我的经验是:先写清楚“做什么”,再写“输入是什么、输出是什么”,最后补一句“在什么情况下使用”。必要的时候加个负例,比如“当你需要实时网络数据时不要用本技能”,能有效防止模型乱调用。

正文部分则是给真正动手时看的操作手册。一个合格的SKILL.md正文至少要有:环境要求、依赖安装命令、每个脚本的调用方式、常见错误处理。这里强烈建议把if-then规则写进去——比如“如果出现ModuleNotFoundError,执行pip install XXX”。因为模型遇到报错时会回头看说明书,你写好了,它能自己排查,能省掉你大量人工干预。

2.3 命名和描述里那些让我返工好几次的坑

这块我踩过不少坑,说说几个印象深的,给大家当参考。

第一个坑是name用中文或者名字起得太泛。最早我做PDF处理skill时,名字直接叫“pdf工具”,结果它跟另一个叫“pdf_analyzer”的技能总是被模型搞混。后来我把名字改成带功能指向的动词短语,比如pdf_merge_extract,歧义小了很多。名字要短,但范围要清晰,这是基调。

第二个坑是description写一堆形容词。我见过有人写“这个技能非常强大,可以高效处理各种文件”,这种话模型看了等于没看。description要去形容词化,直接用“动作+对象”来描述,比如“将PDF文件中的指定页面提取为单独的图片文件”。模型做的是语义匹配,它不关心你的技能牛不牛。

第三个坑是没写负例。我做过一个search_web技能,没写“不要在需要本地文件操作时使用”,结果模型在处理本地日志任务时也要去搜索网页,平白多等几十秒。加上负例之后,这种跑偏行为就基本消失了。

3. 实操:从零构建一个二维码生成与解析Skill

理论聊再多,不如动手跑一个。接下来用一个二维码生成与解析的skill走完整流程,这个例子简单、容易验证,几分钟就能看到成果。

3.1 环境准备:选库和安装依赖

先说明一下我的环境:macOS + Python 3.11,全程用虚拟环境隔离依赖。为什么强调虚拟环境?后面常见问题里会细说,先记住这个习惯。

需要装的库有三个:qrcode负责生成二维码,Pillow负责图像读写,pyzbar负责解析二维码内容。装起来也快:

python -m venv qr-skill-env source qr-skill-env/bin/activate pip install qrcode Pillow pyzbar

选pyzbar而不直接调zbar的原因很简单:它有Python绑定,省去一堆C语言编译的麻烦。不过它也有自己的坑——Windows上经常因为缺少Visual C++运行库而加载失败,这个放到后面细聊。

3.2 写脚本:生成和解析二维码的核心代码

脚本放在qr-skill/scripts/目录下,逻辑很简单。生成脚本接收两个参数:第一个是要编码的文本内容,第二个是输出图片路径,不传默认用output.png。

generate_qr.py:

import qrcode import sys import os def main(): if len(sys.argv) < 2: print("用法: python generate_qr.py <内容> [输出路径]") sys.exit(1) data = sys.argv[1] output = sys.argv[2] if len(sys.argv) > 2 else "output.png" img = qrcode.make(data) img.save(output) print(f"二维码已保存: {os.path.abspath(output)}") if __name__ == "__main__": main()

解析脚本就一个参数,图片路径,输出图片里携带的文本内容。

decode_qr.py:

import sys from PIL import Image from pyzbar.pyzbar import decode def main(): if len(sys.argv) < 2: print("用法: python decode_qr.py <图片路径>") sys.exit(1) path = sys.argv[1] img = Image.open(path) results = decode(img) if not results: print("未识别到二维码") sys.exit(1) for r in results: print(r.data.decode("utf-8")) if __name__ == "__main__": main()

两个脚本加起来不到40行。先单独在终端里分别测一遍,确认生成和解析都没问题,再往下接Agent。这里有个习惯值得分享:脚本必须能独立运行,不依赖Agent框架。因为排查问题时,独立脚本比嵌在框架里好调试一万倍。

3.3 写SKILL.md:让模型知道什么时候该用它

脚本就绪后,把SKILL.md写好。这一步是skill质量的分水岭。

--- name: qr_code_processor description: 生成二维码或解析二维码图片内容。当你需要把文本、URL链接转换成二维码图片,或者从二维码图片中提取文本内容时,使用本技能。 --- # 二维码处理技能 本技能提供二维码的生成与解析能力。 ## 环境要求 - Python 3.10+ - 依赖库:qrcode、Pillow、pyzbar ## 安装依赖 pip install qrcode Pillow pyzbar ## 功能一:生成二维码 将指定文本或URL转换为二维码图片。 python scripts/generate_qr.py "<文本内容>" "<输出图片路径>" ## 功能二:解析二维码 从二维码图片中提取文本内容。 python scripts/decode_qr.py "<图片路径>" ## 参数顺序说明 生成二维码时,第一个参数必须是文本内容,第二个参数才是输出路径。 ## 错误排查 - 提示 ModuleNotFoundError: pyzbar 时,先执行 pip install pyzbar - 解析不出内容时,确认图片是清晰的正向二维码,避免反光或遮挡

这里要想清楚的是description怎么写。我特意在开头写了“生成二维码或解析二维码图片内容”,这是主触发条件;然后补上“当你需要把文本、URL链接转换成二维码图片”这样的具体场景,目的是帮助模型做语义匹配。正文里的“参数顺序说明”是血的教训——第一次测试时模型把路径当成了文本内容,加上这一段之后立刻好了。

3.4 接入Agent实测:两轮对话验证效果

SKILL.md写好后,把它放进Agent的skills目录,然后启动对话测试。

我这边用的Claude Agent SDK,配置好后,第一轮测试直接说:“帮我生成一个二维码,内容是https://example.com”。

日志显示模型先浏览了SKILL.md,提取了关键信息,然后执行了:

python scripts/generate_qr.py "https://example.com" "/tmp/qr_output.png"

几秒钟后返回了二维码图片和绝对路径。

第二轮测试反向来:“解析一下这张图片里的内容”——把上一轮生成的图片路径丢给它。模型同样调用了qr_code_processor技能,只是换成了decode_qr.py脚本,顺利输出了“https://example.com”。

整个过程几乎没有额外干预。这种体验跟纯prompt时代完全不同:模型不再只是“嘴上说说”,它是真的把活干完了。

3.5 迭代优化:把模型搞错的参数顺序修回来

第一次测试其实没那么顺利。最开始我写的SKILL.md里并没有“参数顺序说明”这一段,结果模型执行生成脚本时把参数顺序搞反了,输出路径变成了二维码内容,图片直接保存成了乱码文件名。

排查过程不复杂:打开Agent日志,看到模型跑了generate_qr.py,但参数顺序不对。我在SKILL.md里加了一句“第一个参数必须是文本内容,第二个参数才是输出路径”,重新测试,一次通过。

这个案例想说明的是:模型不会像人一样猜你的心思,说明书上写得多细,它才能做得多准。任何你认为“理所当然”的约定,都要白纸黑字写进去。越细越好,这不是啰嗦,是给AI看的代码注释。

4. 常见问题与排查技巧实录

最后这部分,把我在实际开发中遇到的高频问题整理一下,都是真金白银踩出来的经验。

4.1 模型就是不调用Skill,问题出在哪

这是被问得最多的一个问题。我通常建议大家按这个顺序排查。

第一步,确认skill在不在Agent的技能列表里。很多框架需要显式注册或者放在指定目录,放错位置模型根本看不到。

第二步,检查description写没写清楚。问自己一个问题:如果我是模型,看到一个任务,能不能只凭这段描述判断该不该用这个skill?如果description里全是“强大”“便捷”“智能处理”这类虚词,赶紧改掉。

第三步,缩短触发路径。有的朋友把skill描述写得特别长,模型甚至来不及看到就被截断了。实际测试下来,150字以内的description表现最稳定。

最后,如果前面的都排查了还不行,可以在对话里主动提示“用qr_code_processor技能处理”。在低压场景下,模型会照着你的提示走。不过这只是排查手段,如果每次都要手动提示,说明description还是有问题。

4.2 依赖环境冲突与跨平台坑

这一项最磨人。skill要在不同机器上跑,环境不一致就会出现各种玄学问题。

最常见的就是pyzbar在Windows上缺DLL。明明pip install成功了,一加载就报OSError。网上方案不少,但最省心的就是装Visual C++ Redistributable,或者干脆用conda单独建一个环境装pyzbar。我在Windows上踩过两小时的坑之后,现在统一建议:涉及图像和二维码的skill,优先在Linux或macOS上跑,省心太多。

第二个是依赖冲突。skill多了以后,每个都pip install,最后global环境乱七八糟。我现在所有skill都强制配requirements.txt,并在SKILL.md里写明用虚拟环境。这样一个skill坏了,不影响其他技能和主项目。

4.3 输出结果不稳定,怎么规范脚本输出

模型读完脚本输出之后,要把它展示给用户或者作为下一步操作的输入。如果输出里混着调试信息、warning、中文乱码,轻则影响体验,重则导致后续解析失败。

我的做法是让脚本的输出“机器可读”。能输出JSON就输出JSON,至少也要保证正常结果只有一行关键信息,其他都往标准错误里写。二维码这种简单场景,直接一行文本输出就够了;复杂一点的场景,比如批量处理文件,统一输出JSON,包含成功、失败、结果的路径。

另外编码问题也要注意。Windows的终端默认编码不是UTF-8,中文输出经常变乱码。在脚本开头加import sys; sys.stdout.reconfigure(encoding="utf-8"),能避免一多半编码血案。

4.4 常见问题速查表

问题现象可能原因解决方法
模型完全不用skillskill没注册/目录不对检查框架文档,放到正确目录
模型用错skillname太泛/描述模糊重命名,细化description
参数顺序传错SKILL.md没写清参数约定在正文中显式写明顺序
pyzbar加载报错Windows缺VC++运行库装Redistributable或用conda
中文输出乱码终端编码不是UTF-8脚本内强制stdout重设为utf-8
脚本执行超时默认超时时间太短增大Agent的超时配置
skill依赖冲突全局环境被污染使用虚拟环境+requirements.txt
模型处理完不给出结果脚本print信息过少让脚本打印关键输出和绝对路径

最后聊一点我自己的体会。skills这东西,入门门槛其实很低,但要做好很难。难的不是写脚本,而是把脑子里的隐性知识一点点变成模型能读懂的文字和能执行的步骤。我见过写得很好的skill,description精确到连负例都写清楚,正文里塞满了if-then规则,模型跑起来极少翻车;也见过写得很潦草的,脚本一切正常,但你得在旁边盯着,时刻准备帮模型收拾烂摊子。

另外劝大家一句,别一上来就憋大招。我最早就是从今天这个二维码skill起步的,后来陆续做了PDF处理、Excel清洗、视频抽帧,难度一步一步往上加。skills这东西,一个能稳定跑通的,比十个写着玩的半成品强得多。真想玩好Agent,就从写好自己的第一个skill开始。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 22:10:41

AI编程助手实战:用Claude Code提速开发全流程

1. 快速原型&#xff1a;从零到可运行看板只花了一个午休做开发这几年&#xff0c;我见过太多好想法死在“写代码太慢”这一步。需求评审时说得头头是道&#xff0c;一落到代码上&#xff0c;光搭项目骨架、配路由、连数据库就能磨掉一整天。直到我把 Claude Code 正式用在日常…

作者头像 李华
网站建设 2026/9/8 22:09:02

基于ResNet的水果图像分类系统实战:从数据准备到部署

简介&#xff1a;基于深度残差网络&#xff08;ResNet&#xff09;的水果分类识别系统完整代码包&#xff0c;面向具备一定Python基础、希望快速落地图像分类项目的开发者与学生&#xff0c;尤其适合需要完成课程设计、毕业设计或工程演示的入门者。项目以水果分类为例&#xf…

作者头像 李华