最近在给智能体搭实际干活的能力时我深入研究了一下业界热议的Agent Skills方案。以前做AI应用大部分精力花在调提示词、配工具调用但模型能调工具和模型能“自己想办法完成一件现实任务”之间隔着一条很深的沟。Agent Skills就是冲着这条沟去的它给模型提供的不是一个个孤立的函数接口而是一整套包含说明文档、脚本、依赖、示例在内的“技能包”让模型读完说明之后真的能把一件事从头做到尾。这篇内容我就从机制原理、技能包结构、实际配置过程到各种踩坑完整拆一遍这套方案希望能帮看完的人直接照着搭出自己的技能体系。1. Agent Skills到底是什么1.1 从“对话式AI”到“能动手的AI”先说个直观感受。传统的对话式AI用户说一句模型回一句聊得再好也停留在“嘴皮子”层面。后来有了工具调用模型可以调API、查数据库、发请求但这仍然是“按开发者预设的接口”去请求模型本身并不理解接口背后那套完整的工作流。Agent Skills要改变的就是这件事。它的思路很直接把“完成一类现实任务所需的所有东西”打包成一个文件夹里面有一份用Markdown写成的技能说明文档有可执行脚本有依赖清单有参考资料。当用户的请求命中某个技能时模型会先读这份说明文档理解这个技能是干什么的、怎么用、有哪些约束然后自己去执行脚本、处理文件、读取结果最后把结果整理给用户。这套机制最早是某头部AI研究机构在2025年初公布的当时配合年度模型版本更新一起放出官方称之为Agent Skills中文社区一般翻译成“智能体技能”。它不是把技能写死在模型参数里而是让模型通过阅读文档和操作文件系统在运行时“学会”调用外部工具所以技能的扩展性极强。你不需要重新训练模型只要往技能目录里多放一个文件夹模型立刻就能获得一项新能力。换句话说模型还是那个模型但它的“手”变多了。每一次新增技能都相当于给智能体配了一套新的“装备”让它能处理原来做不了的现实任务。1.2 与传统函数调用的关键区别很多人在第一次接触Agent Skills时都会下意识认为它只是函数调用的升级版实际上两者在设计哲学上有本质区别。传统的Function Calling/工具调用逻辑是开发者定义好函数的名称、参数JSON Schema、描述模型根据用户输入选择合适函数并生成结构化参数然后由外部程序执行这个函数并返回结果给模型。整个过程模型扮演的是“决策者”但决策空间非常受限——参数怎么传、异常怎么处理、结果怎么格式化这些都在开发阶段定死了模型没办法在执行过程中改变策略。Agent Skills则把“执行层”大大拓宽了。一个技能包里的SKILL.md文档本质上是一份“给模型看的使用手册”而脚本是真正的执行者。模型在调用技能时不只是输出一个参数JSON而是会先阅读技能说明理解执行步骤甚至可以根据执行中出现的中间结果调整后续动作。比如处理一份格式特殊的PDF同一个技能在面对不同文件时可能会走的处理路径完全不同这就是“智能体”和“工具调用器”之间最大的差别。再往深一层看函数调用是结构化的、确定性的接口握手而技能调用是语义化的、目标导向的任务执行。前者适合“查天气”“算个税”这种静态接口后者适合“把这一堆混乱文件整理成结构化表格”这种开放式任务。实际项目中两者也经常混用但如果你想让模型具备独立完成工作流的能力只靠函数调用是不够的。1.3 为什么说这是“现实世界技能“现实世界技能”这个说法我觉得有两个层面的含义。第一层是字面上的Agent Skills处理的往往是文件、命令、脚本、外部API这些真实世界的对象模型通过它们跟现实环境发生交互。比如读取一个Excel文件调用Python脚本做数据清洗把生成的可视化图片保存到本地目录再把路径返回给用户。这些操作不再是“生成一段文字让你自己去复制粘贴”而是模型自己动手把结果落在磁盘上。对很多业务场景来说产出的不是文本回复而是实际的文件、格式转换结果、数据分析图表这些才有现实使用价值。第二层是机制上的它让AI真正具备了“围绕一个目标自己组织过程”的能力。以前你让AI“帮我把这个月的数据做成周报PPT”它只能给你写大纲或者生成VBA脚本你还是得自己操作。有了技能之后模型可以直接调用PPT生成脚本读取数据文件套用模板输出一个能打开的PPT文件甚至再跑一遍检查程序确认没有格式错误。这个过程中模型读文档、执行代码、看报错、再做修正跟你自己做这件事的路径本质上是一致的这就叫“现实的技能”。可以说Agent Skills是对“AI能干什么”这个问题的一次重新定义。以前是“能回答什么”现在变成了“能完成什么”完成的标准不是生成文本而是现实结果。2. 一个技能包的完整解剖2.1 目录结构与核心文件一个标准的Agent Skills技能包在文件系统里就是一个独立目录典型结构大致是这样的my-skill/ ├── SKILL.md ├── dependencies.json ├── scripts/ │ ├── run.py │ └── helpers/ │ └── file_utils.py ├── references/ │ ├── guide.md │ └── toc_template.docx ├── assets/ │ └── logo.png └── tests/ └── test_run.py这个目录没有强制到字段级但核心成员基本是固定的。SKILL.md是灵魂后面单独讲。scripts目录放可执行脚本模型的“手”主要就是通过执行这些脚本来干活。references目录放参考资料可以是文档模板、说明文件也可以是脚本运行所需要读取的指导文件。assets目录放静态资源比如图片、字体、样本数据。tests目录推荐保留因为技能脚本一旦出问题模型可以在执行后自动跑一遍测试来验证结果这个能力在复杂任务里非常有用。dependencies.json用来声明技能运行所需的依赖包它的作用跟Python项目的requirements.txt类似但多了一层用途模型在执行技能前会先检查依赖是否安装缺少的话可以自行安装。在设计上依赖声明越精确越好版本锁定能避免很多“昨天还能跑今天挂了”的灵异事件。有个细节很多人第一次接触时会忽视技能包不一定只能有一个脚本。做得好的技能会把一个大任务拆成多个可组合的小脚本通过命令行参数互相调用。这样不仅模型执行时更灵活你手动调试单个步骤也方便得多。2.2 SKILL.md才是灵魂如果说脚本是技能的手脚那SKILL.md就是技能的大脑说明书。模型在执行技能前读的就是这份文档。文档写得清不清楚直接决定了模型能不能正确使用这个技能所以它的地位远比脚本本身重要。SKILL.md虽然没有统一标准模板但业内普遍认为一份好文档至少要包含这几块内容# 技能名称PDF表格提取工具 ## 功能描述 从PDF文件中提取表格数据输出为CSV格式。支持单页和多页PDF适合处理财务报表、 产品目录、调研报告等含表格结构的文档。 ## 适用场景 - 银行对账单表格提取 - 问卷调查结果整理 - 纸质文档数字化归档 ## 不适用场景 - 扫描版图片型PDF需要使用OCR技能 - 复杂合并单元格表格可能丢失部分结构信息 ## 使用方法 ### 基本用法 python scripts/run.py --input pdf_path --output csv_path ### 参数说明 - --inputPDF文件路径必填 - --output输出CSV路径默认与输入文件同目录 - --page指定页码从1开始不传则处理全部页面 - --password加密PDF的密码可选 ## 示例 提取指定PDF的所有表格 python scripts/run.py --input ./data/report.pdf --output ./data/report_tables.csv 提取第二页到第四页的表格 python scripts/run.py --input ./data/report.pdf --output ./data/report_tables.csv --page 2-4 ## 注意事项 - 遇到加密PDF需先解锁建议由调用方确认密码权限 - 输出CSV统一使用UTF-8编码防止中文乱码 - 若提取结果为空检查PDF是否真的含表格而不是脚本报错这份文档的精髓在于“给模型看”这个定位。模型是阅读者它不会像人一样自动脑补缺失信息所以文档里的每个描述都要直白、具体、可操作。功能描述要清楚边界适用场景和不适用场景都很重要——模型判断要不要用这个技能靠的就是这段描述使用步骤要给出确切的命令示例参数说明要逐个列出注意事项是实战经验沉淀能帮模型少走弯路。我见过不少团队把SKILL.md当成给人类开发者看的README来写结果模型调用时经常判断失误。判断失误的根源就是文档里缺少“不适用场景”的负面描述模型遇到模糊任务时会过于乐观地选择技能然后执行失败。后来大家都意识到SKILL.md本质上是在教模型做决策正面例子和反面例子必须成对出现。2.3 为什么用文件系统而不是参数协议Agent Skills选择文件系统作为“接口”这个选型值得单独说。很多人会觉得既然模型调用外部能力为什么不直接定义一套JSON协议像工具调用那样结构化原因其实很实际。真实世界里的技能形态千差万别有的技能要跑一个1000行的Python脚本有的技能只是调用一个命令行工具有的技能需要读取一堆模板文件。如果把这些全部抽象成统一的参数协议光是设计协议的开销就比技能本身还要大。而文件系统天然就是各种形态程序的共同语言——脚本在文件系统里数据在文件系统里模型通过读写文件来跟现实交互这跟一个人用电脑的路径是完全一致的。用文件系统还有一个额外的好处版本管理和分发变得非常简单。技能包就是一个普通目录你可以把它放进Git仓库用Git做版本控制可以打包成压缩包分发别人解压后放到技能目录就能用。在这一点上Agent Skills跟软件分发的模式很像生态化的路径也走得通。模型端的配合也很关键。在训练阶段模型就见过大量的“阅读文档→执行脚本→查看结果”的路径所以这套机制在推理时对模型来说是“熟悉的味道”。这也是Agent Skills方案能快速落地的深层原因——它没有要求模型学会一种全新的交互范式而是借用了一套模型已经理解的、人类使用计算机的自然方式。3. 实操从零给智能体配上文档处理技能3.1 设计技能包之前要想清楚的事动手写技能包前最忌讳的是“想到什么就写什么”。做Agent Skills和写普通脚本有个很大区别普通脚本的使用者是人很多细节不用说清楚人能结合上下文自动补全而技能的使用者是模型它没有你的项目背景不知道某个字段为什么重要所以你必须把“决策上下文”写清楚。我第一次做技能包时就吃了这个亏。当时想做一个“会议纪要格式化”技能脚本写好之后SKILL.md只写了“输入原始会议记录输出格式化纪要”模型调用时完全不知道自己该输出什么格式、要不要保留发言人、待办事项怎么提取结果跑出来的东西惨不忍睹。后来参照成熟技能包的做法在文档里加入明确的输入输出格式、处理步骤清单和一条完整示例效果立竿见影。所以设计阶段建议回答三个问题这个技能要解决什么类型的任务边界在哪哪些任务它不负责这个技能需要哪些输入中断/异常情况下该怎么处理模型执行完这个技能后能看到什么结果才能判断任务确实完成了这三个问题的答案就是你SKILL.md的主要骨架。3.2 编写SKILL.md的具体思路接上面说的我以一个实际的技能包举例。假设我们需要一个“会议纪要整理”技能目标是输入一份含糊的原始会议记录文本输出一份结构清晰的会议纪要。首先定义技能边界。这个技能只负责整理文字内容不负责录音转写也不负责根据纪要生成待办跟踪表——那些是另一个技能的活。目录结构很简单meeting-notes/ ├── SKILL.md ├── dependencies.json └── scripts/ └── format_notes.pySKILL.md的关键内容是执行步骤。给模型写执行步骤不能像教程一样“第一步怎样第二步怎样”而要像标准操作流程一样每一步都写清楚目标和验收标准。比如## 处理流程 1. 读取输入文本识别参会人、日期、会议主题等元信息 2. 将正文按讨论主题分段保留原始讨论脉络 3. 为每个主题提炼结论判断是否存在待办事项 4. 按“主题、结论、待办事项”的结构输出最终纪要 5. 输出结果严格遵循模板格式不得自行增加章节这个步骤看起来简单但实际写的时候每条背后都有血的教训。第2条“按讨论主题分段”不是为了好看而是模型如果不分段一口气输出的纪要不具备可读性第5条“不得自行增加章节”是因为模型经常自由发挥加一段“会议意义”之类的废话导致下游流程无法解析。示例部分也要写足既有完整的理想输入输出示例也要有处理模糊信息的示例。比如原始文本中有“小王说预算有点紧大家想想办法”格式化后应该是“主题预算讨论结论预算偏紧需调整待办产品线重新梳理预算方案”。这样的示例对模型理解任务帮助极大。写到这里你会发现SKILL.md的质量直接决定了技能质量的上限。脚本写得再漂亮也弥补不了文档的决策缺陷。3.3 配置技能目录与权限技能包本身写好后要把技能目录放进客户端能识别的位置。不同客户端配置方式不同但核心逻辑是一样的客户端有一个技能目录配置项指向包含所有技能包的根目录每个技能包是该根目录下的一个子目录。比如你的技能根目录是/data/skills那么里面可以放多个技能/data/skills/ ├── meeting-notes/ ├── pdf-extractor/ ├── image-resizer/ └── web-summarizer/客户端启动时会扫描这个目录把每个子目录里的SKILL.md载入原始上下文或作为可用技能索引供模型在运行时检索。这里有一个很容易踩的坑技能根目录里不要放无关文件尽量保持“一个子目录一个技能”的干净结构。如果根目录下还有散落的配置文件会被客户端误识别为技能包导致模型面向一堆无意义文档严重影响检索效率。权限配置是另一个重点。Agent Skills里的脚本是替模型执行的而模型又是被用户使用的这就形成一个链条用户的一句话可能最终触发一段任意代码在你的机器上运行。所以权限必须分清层次。实际操作中我会把技能脚本限制在“只允许操作技能目录下的文件”外部路径一律拒绝。有些客户端支持白名单机制允许你写明技能可访问的数据目录这里建议宁可先收紧等跑通了再逐步放宽也不要一开始就开一个大宽权限让技能脚本可以读写整个磁盘。3.4 实际操作流程与效果复盘配置完毕后我用一次真实任务做了端到端测试。给模型发了一段话“帮我整理一下今天下午产品讨论会的记录原始内容在/incoming/product_meeting.txt整理好后输出到/done/meeting.md。”模型的处理路径大致是这样的先读取输入文件内容确认这是会议记录整理任务决定调用meeting-notes技能阅读SKILL.md理解处理流程执行python scripts/format_notes.py --input /incoming/product_meeting.txt --output /done/meeting.md脚本执行成功读取输出文件确认内容格式最后回复用户处理结果。这次测试里最让我惊讶的是模型在中间步骤的自主性。输入文件里其实混着一些非会议内容的闲聊模型没有机械地把所有文本都填进模板而是真的按SKILL.md里的步骤先识别主题再判断哪些内容应该被剔除最终输出的纪要只保留了有效讨论内容。这比我预想的要聪明也说明脚本的设计和SKILL.md中“按主题分段”“确定结论”的强约束是有效的。不过也有值得注意的失败案例。同一套技能在另一台没有安装某个依赖包的机器上跑挂了。模型执行脚本时报ModuleNotFoundError然后自己阅读了dependencies.json尝试用命令行安装依赖再重新执行脚本——整套动作一气呵成。但这个行为是否应该被允许其实有争议。如果你跑的技能在受限环境里没有安装依赖的权限模型的这类自主行为反而会导致失败循环。这也是我后来在SKILL.md里专门加一条“如果依赖缺失不要自动安装直接报错并告知用户”的原因——把环境决策权交还给用户比让模型自作主张更安全。实操经验总结下来设计一个稳定的技能包的要点是一靠SKILL.md把决策写清楚二靠脚本把一件事做扎实三靠权限把风险控制住。三者缺一不可。4. 高频应用场景与技能粒度的选择4.1 值得优先复用的技能场景清单Agent Skills的优势体现在它能在“开放式现实任务”里持续发挥作用。如果你准备上手我建议优先从这几类高频场景开始因为它们任务边界清晰、结果可验证、回报直接。第一类是文档转换与提取。把PDF转成Markdown、从Excel提取数据、把网页正文抽成纯文本、批量重命名文件等。这类技能适合作为入门练手因为脚本逻辑简单判断成功与否很直观文件生成得对不对、内容提取得全不全一查便知。第二类是数据分析与可视化。让模型读取CSV、JSON数据做统计计算输出图表文件。这类技能要让模型学会先探察数据结构再决定用哪种图表表达最后保存图片。对很多业务者来说这是最能直观感受到AI“干活”价值的场景。第三类是内容聚合与结构化。把一堆非格式化的信息比如网页链接、聊天记录、邮件摘要整理成固定结构的文档。这类技能强依赖SKILL.md里的输出示例写得好不好直接决定最终结构是否符合要求。第四类是本地工具链的“AI化作”封装。比如把一套Git工作流封装成技能把运维巡检脚本封装成技能把数据清洗管线封装成技能。这样做的好处是让模型能安全地复用你团队里已经验证过的工具而不是每次临时拼凑。4.2 技能粒度太大太小都坑技能粒度是Agent Skills设计里最微妙的问题。粒度太大一个技能想覆盖所有情况SKILL.md就会变得又长又复杂模型看文档的时间和理解错误的概率都上升粒度太小技能数量爆炸模型在检索时难以快速判断应该用哪个反而拖慢响应。我见过一个反例某团队把一个“上传文件”操作拆成了五个技能——上传图片、上传文档、上传压缩包、上传音视频、上传其他五个技能的脚本几乎一样只有文件类型校验不同。结果模型接到“帮我把这份报告发上去”的任务时反复识别文件类型最终选择困难还偶尔选错。这个教训说明技能划分应该是任务导向的而不是文件类型导向的。粒度划分的一个实用准则是站在用户意图的粒度去划让一个技能对应一类用户会直接提出的完整请求。比如“整理会议纪要”是一个完整意图“上传文档”本身如果只是操作的一环那它更适合做成内部函数而不是独立技能。技能是给模型看的菜单菜单上的每道菜都应该是一道菜而不是一味配料。4.3 Skill与工具调用的组合模式实际项目中Agent Skills不是要取代工具调用而是和工具调用协同。一个比较稳健的组合模式是外部API交互比如发消息、查天气、支付继续用传统工具调用因为它们接口固定、延迟敏感、需要结构化参数而文件处理、脚本执行、多步骤数据整理这类执行型任务交给Agent Skills。比如一个业务助手里模型需要调用通讯录API查询联系人工具调用然后把联系人信息填入一份邀请函模板Agent Skills。模型先通过工具调用拿到数据再调用技能生成邀请函文件最后通过另一个工具把邀请函发出去。这种混合架构既保留工具调用的稳定低延迟又引入技能执行的开放灵活性。需要注意的一点是当工具调用和技能都可以完成同一件事时要明确优先级避免模型随机选择。比如你既有一个“发送邮件”函数调用又有一个“发送邮件”技能模型就可能两种都试造成重复发送。解决办法是收敛入口同一类能力只保留一种。5. 踩坑记录与排查速查表5.1 模型不调用技能时的排查方向“我明明把技能目录配好了模型就是不理它”这是群里出现频率最高的问题。遇到这种情况先别急着怀疑客户端有Bug按顺序排查看一眼。先看SKILL.md的头部描述是否清晰。模型判断调用哪个技能主要靠的是文档里的功能描述和适用场景。如果描述写得太抽象比如“处理文档”模型很难把用户的具体请求跟技能对上号。正确的描述是“将PDF文件中的表格提取为CSV格式”越具体越容易被正确触发。再看技能目录是否被客户端正确扫描。有些客户端有缓存机制技能的变更不会立刻生效。排查时直接问模型“你能看到哪些可用的技能”或者检查客户端日志里的技能加载记录。接着看候选技能是否过多。如果技能目录里有几十个技能模型在检索时容易出现“选择困难”特别是多个技能的描述有部分重叠时。解决方案是精简技能数量或者优化各技能的描述让边界更清晰。最后检查用户请求与技能描述的语义匹配。有些模型对间接请求的理解能力较弱比如用户说“帮我把那份合同提出来”但技能描述写的是“从PDF提取表格”模型可能识别不到这是提取任务。可以在SKILL.md的适用场景里多写几个同义变体帮助模型建立关联。5.2 技能脚本执行失败时的通用定位法脚本执行失败是整个链路里最让人头疼的环节因为错误可能在脚本本身、依赖环境、输入数据三个层面同时存在。我的定位顺序是先看脚本能否在命令行直接跑通再单独用一段输入样本测试脚本逻辑最后拿到模型侧看日志确认命令拼接是否正确。最常遇到的坑是路径问题。模型从对话中提取的输入路径可能有引号、空格、相对路径等各种情况如果脚本没有做好参数规范化轻则文件找不到重则命令注入。强烈建议所有技能脚本在处理外部输入时统一用绝对路径再做一次参数合法性检查凡是不匹配预期格式的输入一律拒绝执行。第二坑是依赖环境不一致。技能在本地调试得好好的但模型运行在沙箱环境里可能没有同样的Python版本、没有项目依赖甚至连命令行工具的路径都不一样。解决思路是让技能在启动时做环境自检比如检查依赖包版本、检查外部命令是否存在必要时输出清晰的错误信息让模型能理解并反馈给用户而不是干等一个模糊的异常。第三坑是编码问题。处理中文内容时乱码是家常便饭。排查思路是约定所有技能输出统一用UTF-8编码并且在脚本里强制指定编码不要依赖系统默认值。这个坑在Windows环境尤其常见很多人本地是GBK编码放到Linux沙箱就乱套。检查完这些再针对具体的报错信息去搜索基本能解决九成问题了。5.3 几条独家实操经验最后分享几条平时开发中不太会被官方文档提到但能让你少踩很多坑的经验。第一条SKILL.md一定要写“失败示例”。大部分文档都只写“我要做什么”很少写“我不能做什么”但对模型来说一条“如果遇到扫描模糊的PDF请直接告知用户使用OCR技能不要强行提取”的负面示例效果胜过十条正面描述。这对模型的决策质量提升非常大。第二条给技能脚本加审计日志。你的模型调用技能成功了几次、失败了几次、中间走了什么分支这些数据一定要留。我见过不少团队把技能部署上去就再也不管等到用户投诉才发现某个技能已经悄悄挂了三个月。审计日志不复杂就按需把关键步骤的执行时间、输入摘要、退出码、输出路径记录下来一旦技能退化复盘起来会轻松很多。第三条技能版本管理务必要做。技能不是写完就固定了你很可能今天加一个场景描述明天修一个脚本Bug后天调整输出格式。没有版本管理你根本不知道某个行为变更是哪次改动引起的。建议每个技能目录都挂在一个独立的Git仓库下SKILL.md和脚本的每次变更都有迹可循。第四条做技能包上线前一定要拿不同难度和不同风格的输入样例测试一遍。只用一个理想样本测过就上线很容易被现实中千奇百怪的输入击穿。我在本地维护了一个测试输入集最少的十个样本起测覆盖正常输入、边界输入、异常输入、空输入全部通过才往生产放。第五条注意技能的“可逆性”设计。凡是可能修改源文件、删除数据、覆盖内容的技能都要在SKILL.md中要求先做备份。比如你让模型帮着你批量重命名文件改之前就要把原文件名和路径记录下来万一改错了能还原。这是对用户负责也是对自己负责——等真的误删了用户文件后悔都来不及。写到这里Agent Skills从机制原理到落地配置已经完整走了一遍。上面这些经验是我在几个真实项目里一点点踩出来的每一步的背景、坑位和原因都写得比较清楚照着实践应该能少走不少弯路。如果你正打算给智能体配一套可复用、可维护的现实任务执行能力这套方案确实值得认真试一次。