
做 agent 开发有段时间了最近圈子里讨论最密的一个词就是 agent skills。简单说它就是给 AI agent 加上一批可复用的专业技能包遇到特定任务时agent 会读取技能描述调用对应的脚本、模板或流程把原本靠“临时发挥”的对话变成“按套路办事”的稳定能力。我身边不少从 agent 框架、Claude Skills 一路折腾过来的朋友最近都在聊怎么把技能包设计得更好用。这篇就聊聊我对 agent skills 的理解、开发路径和一些踩过的坑适合想给 agent 加技能、正在做 agent 框架选型或者单纯好奇“skills 和 tools 到底啥区别”的读者。1. agent skills 是什么从“会说话”到“会干活”1.1 从一个尴尬场景说起我在做一个内部流程 agent 的时候发现模型虽然能听懂“把这份报表转成 PDF”但每次生成的结果格式都不一样有时候加密有时候不加密有时候页边距很怪甚至有一次直接输出了一堆 Markdown 文本而不是文件。后来我把“转 PDF 的完整操作步骤加上参数清单”写成一个说明文件再配一个小脚本agent 遇到需求时自动读取并执行输出瞬间稳定了。这就是 agent skills 的价值把反复出现的任务固化成可复用、可验证、可分享的能力单元。你可以把它理解成一个“插件包”但又不完全是插件因为它不只是代码而是“模型如何理解任务 如何执行任务”的组合体。具体来说一个技能包通常包含一段给模型看的自然语言说明书以及一组用来实际干活的脚本或模板。模型负责判断“现在该用哪个技能、怎么用”脚本负责保证“输出的结果是确定性的”。1.2 skills 和 tools、插件、工作流到底有什么边界很多朋友容易把 skills 和 tools 划等号我一开始也这样。后来在架构设计里反复琢磨才理清它们之间的相对关系tools 更像是 agent 可以调用的“函数”颗粒度小有明确的输入输出比如发一个 HTTP 请求、读一个文件、执行一段代码。skills 是面向“一个完整任务的能力包”内部可能包含多个 tools、提示词模板、脚本、校验规则甚至包含子技能。plugin 或 workflow 往往更强调平台集成和流程编排而 skills 更强调“模型如何知道在什么时候用它”。这个边界不是行业严格标准不同 agent 框架的实现差异很大。比如有的框架把 skills 直接实现为“带描述的 tool”有的框架则做成独立的“技能加载器”。但理解这个分层能帮助你设计技能不要把 skills 做成一个巨大的 tool也不要把 tools 硬塞进技能里而是按职责划分。1.3 为什么“skills”突然成了热门话题模型能力之外工程化需求是主因。单个提示词或工具已经无法覆盖复杂任务比如“整理会议纪要并生成待办事项”这种任务既需要理解语义又需要调用日历接口、写文件、格式化输出如果全靠 agent 临时组合很容易出错。这时候把“知识、脚本、校验、示例”打包成一个技能就能大幅提升稳定性。另一方面Claude Skills、Codex skills 这类项目把技能包做得像应用商店一样容易安装社区里开始出现各种 skills 下载平台、推荐清单和教程。甚至有的 agent 框架已经开始内置“官方市场”你可以一键安装别人写好的技能包也可以把自己的技能包提交上去。生态起来了自然讨论就多了。2. 从零开发一个 agent skill完整实操过程2.1 最小技能包的标准结构以社区常见的约定为例一个最小技能包通常包含三个部分SKILL.md技能说明文件用自然语言写清楚技能名称、适用场景、触发条件、使用步骤、注意事项。scripts/一个或多个可执行脚本负责真正“干活”比如生成文件、调用接口、做数据转换。assets/模板、数据、参考文档等静态资源供模型或脚本读取。这种结构为什么会流行因为它对模型很友好SKILL.md是自然语言写的索引模型可以直接理解“什么时候该用、怎么用”脚本是确定性的执行逻辑一旦运行结果不会因为模型心情变化而漂移。两者配合既灵活又可控。提示目录命名推荐用 kebab-case比如pdf-converter、web-card-generator。不要用空格和中文路径很多框架在解析技能目录时会因为路径问题加载失败。2.2 三步写出第一个可用技能以“生成网页卡片组件”为例我们做一个真实能用的前端开发技能目标让 agent 根据用户描述生成一个卡片组件的 HTML CSS 片段。第一步写SKILL.md# Card Generator 生成响应式卡片组件的 HTML/CSS 代码。 适用场景用户提到“卡片”“card”“组件”“产品卡片”“用户卡片”等词。 使用步骤 1. 分析用户描述确认卡片用途、尺寸、主色调。 2. 参考 assets/card_template.html 中的基础结构。 3. 生成可独立运行的 HTML 片段内联 CSS 样式。 4. 自检确认包含 card__header、card__body、card__footer 三个必须类名。 注意事项 - 所有样式类使用 card- 前缀避免污染全局。 - 不要使用 alert()不要内联事件处理器。 - 如果用户未指定颜色默认使用 #4F46E5。第二步在assets/card_template.html里放一个基础模板方便模型参考div classcard div classcard__header标题/div div classcard__body内容区域/div div classcard__footer操作按钮/div /div style .card { border: 1px solid #e5e7eb; border-radius: 12px; padding: 16px; max-width: 360px; } /style第三步写一个校验脚本scripts/validate.sh检查生成的代码里是否包含必须类名#!/bin/bash # 校验生成的卡片组件代码 input_file$1 for class_name in card__header card__body card__footer; do if ! grep -q $class_name $input_file; then echo 缺少必须类名: $class_name exit 1 fi done echo 校验通过把整个文件夹放到 agent 的技能加载目录重启会话测试。当你对 agent 说“帮我生成一个介绍产品的卡片组件主调蓝色”它读取SKILL.md后会按照步骤生成带正确类名的组件。我实测下来加了这套结构后生成的组件代码基本能直接用了。2.3 安装技能包手动拷贝、Git 拉取与市场安装不同 agent 框架对技能安装的方式差别很大但大体可以归为三类手动拷贝把技能文件夹直接放到 agent 配置的skills目录下。简单直观适合个人本地调试。缺点是没有版本管理改坏了只能靠备份。命令安装比如某些 CLI 工具支持skills install git-url从远程仓库拉取技能包并自动放到正确位置。适合团队协作版本可追溯。市场安装从框架内置的官方市场或第三方技能平台搜索、安装比如“装一个 GitHub 协作技能”“装一个 PDF 处理技能”。适合快速使用现成能力。我的建议是团队内部技能包用 Git 仓库管理配合 Tag 打版本依赖清晰个人实验就用手动拷贝改起来最快。对外分享时再考虑发到公共技能平台让更多人使用。2.4 前端开发类 skills 的细节优化前端开发是 skills 里比较热门的方向但它有几个典型的坑我一个个说。第一模型生成的代码容易“太有自己的想法”。你让它写个按钮它可能给你写出一套 BEM CSS Variables 动画库的复杂结构。解决方法是在SKILL.md里明确技术栈和样式方案比如“使用 Tailwind utility class不要使用自定义 CSS 文件”或者“所有样式内联禁止引入外部框架”。第二缺少可访问性约束。很多模型组件没有 aria-label、没有 alt 属性、对比度也不达标。可以在 SKILL.md 里加一条基础要求“所有交互元素必须包含可访问性标注图片必须提供替代文本”。第三负面约束比正面约束更有效。我试过写“请输出美观的代码”结果模型自由发挥改成“不要使用 alert、不要内联事件处理器、不要引入外部 CDN、不要生成超过 200 行的代码”之后输出规范多了。因为这些“禁止项”是明确可检查的模型更容易执行。3. 底层原理与架构设计为什么技能包要这么设计3.1 触发机制靠描述文件做意图匹配一个自然的问题是agent 怎么知道该用哪个技能绝大多数框架的实现方式是“语义路由”。agent 收到用户消息后会把当前对话内容和技能目录里的SKILL.md摘要一起交给模型由模型判断是否需要使用某个技能以及使用哪一个。这相当于把“路由决策”交给了模型本身而不是写死的规则。所以SKILL.md写得越具体触发就越准确。比如“当用户提到 PDF、转 PDF、导出 PDF 时优先使用本技能”就比“处理文档”好用得多。我在实践中发现在描述里加“优先使用”这四个字能明显降低技能之间的误触发。3.2 上下文管理技能包如何影响 token如果把所有技能内容一次性塞进上下文token 会很快爆炸。比如你有 20 个技能每个SKILL.md加脚本 2000 token光技能描述就吃掉 4 万 token还没开始干活呢。主流做法是“两阶段加载”先把每个技能的“标题 一句话描述”注入上下文模型判断命中某个技能后再真正读取该技能的完整 SKILL.md 和相关资源。所以技能描述要短小精准把长内容放到脚本或 assets 里按需读取。这也是为什么SKILL.md开头必须有一句高度浓缩的“技能摘要”它直接影响上下文窗口的利用效率。3.3 安全边界控制技能到底能做什么技能包本质上是一段可执行代码 模型指令权限控制做不好会很危险。我见过一个团队因为技能脚本里硬编码了数据库连接串最后日志里把整个连接信息打出来了。安全设计至少要考虑这几层只读操作、局部文件写入、网络请求、命令执行等操作按风险等级分开。对需要执行任意命令的技能最好放到沙箱容器里限制 CPU、内存、网络访问。密钥通过环境变量注入不要写进技能代码。技能脚本里避免使用全局路径只允许在项目目录内读写文件。注意如果你的 agent 能访问生产环境技能里一定要做好最小权限设计。宁可多写几条校验也别把“删除数据库”这种操作暴露给模型。3.4 多技能协作与 agent 架构复杂任务往往需要多个技能协作。比如“整理会议纪要并发送邮件”可能需要“文档解析技能”和“邮件发送技能”。架构上有几种常见模式串行调用agent 按顺序调用技能前一个技能的输出作为后一个技能的输入。并行调用多个独立技能同时执行最后合并结果。技能路由由一个“调度技能”决定调用哪些子技能适合任务分支多的情况。多 agent 协作每个子 agent 绑定一组 skills通过消息队列或共享内存协作。在多 agent 场景中技能包需要定义清晰的输入输出协议最好用 JSON Schema 描述参数避免歧义。比如“邮件发送技能”的入参应该是{ to: userexample.com, subject: 会议纪要, body: ..., attachments: [] }这样其他技能或 agent 调用时就知道该传什么字段。没有这个约束两个技能之间传参全靠模型猜很容易出问题。4. 常见问题与排查技巧实录4.1 技能没有被触发或者总是选错技能这是新手遇到最多的问题。原因通常有三类描述不够具体、多个技能描述相似、模型版本对指令遵循能力不足。我建议按这个顺序排查简化复现只保留一个技能看它是否被触发。如果单独放着能触发说明是技能之间的描述冲突。检查描述里的触发词是否和用户实际表述匹配。比如用户说“出个图”你的技能里只有“画图”“生成图片”这些词就很容易漏触发。对比多个技能的描述确保场景差异化。比如“生成卡片组件”和“生成表单组件”描述里都写了“组件”但一个强调“卡片”一个强调“表单”模型就能更好区分。我通常会在SKILL.md开头加一句“当用户提到 XX、XX、XX 时优先使用本技能”效果提升非常明显。4.2 上下文过长或者指令冲突技能包文件太多、说明太长会让模型在读取时抓不住重点。我踩过的坑是把一个技能的所有参考资料都塞进SKILL.md结果模型生成时反而忽略了核心步骤。建议每个技能包控制在 10 个文件以内SKILL.md 不超过 500 字详细内容放到 assets 或脚本里。指令冲突通常是“通用约束”和“技能专属逻辑”打架。比如底层 prompt 说“优先用开源方案”但某个技能为了特定业务写死了“必须用商业组件”模型就会很纠结。解决办法是把团队级约束上移到底层系统 prompt技能里只描述自身的专业逻辑不要重复写全局规则。4.3 脚本执行环境不一致本地能跑放到服务器上就挂多半是依赖路径、Python 版本、环境变量的问题。我归纳了几个有效做法技能包自带requirements.txt或Dockerfile。脚本开头做环境检查比如“如果 Python 3.10退出并提示”。使用#!/usr/bin/env python3这类 shebang而不是写死/usr/bin/python。还有一个很隐蔽的问题Windows 和 Linux 的换行符不一致导致 shell 脚本执行时报“bad interpreter”。统一在 Git 里配置*.sh text eollf就能解决。4.4 调试技巧实录调试 agent skills 比普通程序麻烦因为中间隔了一层模型推理。我常用的调试方法有这几种开启 agent 的 verbose 日志看模型选择了哪个技能以及实际读取了哪些文件。单独手动执行技能脚本确认脚本本身没问题再排查调用层。做“最小复现”只保留一条用户消息和一个技能逐步加回复杂度直到问题复现。记录一次完整运行轨迹包括模型输出、脚本输出、最终结果方便改动前后对比。有时候模型输出看起来合理但脚本执行报错这时候问题就在脚本参数解析上。检查技能脚本是否严格按照 SKILL.md 里定义的参数格式接收输入。4.5 常见问题速查表现象可能原因快速解法技能不触发描述不够具体补充触发词和典型使用场景总是选错技能多个技能描述相似强化差异化关键词弱化共用词输出格式漂移缺少校验脚本加入输出校验和自动修正逻辑上下文过长技能内容太多压缩描述把长内容移入脚本/assets多次调用结果混乱技能间依赖关系不清定义 JSON Schema 参数协议或拆分子 agent脚本权限过大沙箱配置缺失限制网络、文件路径、执行权限本地能跑线上挂环境不一致使用固定版本依赖 环境检查最后分享一个我自己的经验刚开始做 skills 时我总想做一个“万能技能”把什么功能都塞进去结果SKILL.md写了三千字模型反而不知道该听谁的。后来我把技能拆成多个小组件每个只做一件事比如“生成卡片”“生成表单”“校验样式”每个技能几十行说明命中率高维护也轻松。如果你也在折腾 agent skills一个小建议从最小可用的技能脚本开始先解决一个具体的重复性任务验证流程跑通后再做扩展。别一上来就搞复杂编排技能和技能之间的协作永远是在单个技能稳定之后才需要考虑的事。