最近 AI 编程圈里,不管你在哪个开发者群潜水,应该都被 “Skills” 这个词刷屏了。Claude Code 在推 Skills,Codex 在推 Skills,Cursor 和 OpenCode 也都跟进,GitHub 上几乎每天都有新的 AI Skills 仓库冒出来。更夸张的是,一些团队已经把自己的代码规范、接口文档、测试套路全部封装成 Skills 丢给 AI Agent 用,效率提升比我刚入坑时预想的高很多。
我特意花了一个多星期,把社区里能翻到的 Skills 相关文档、示例和“翻车现场”都过了一遍,自己也手写并调试了好几个。这篇就从一个实际使用者的角度,聊聊 Skills 到底是什么、为什么突然这么火、一个能用的 Skills 内部长什么样、怎么从零写一个自己的,以及最近社区里关于某些 Skills 作者的“瓜”和避坑经验。
1. Skills 在 AI 编程里到底是个什么角色
1.1 一句话理解:给 AI 发了一本岗位 SOP
以前我们让 AI 写代码,基本靠“对话引导”。你告诉它“用 React 写个登录页”,它现场发挥,每次结果都带点随机性。遇到复杂任务,你得像带实习生一样,把需求拆成几十条,一步步喂给它,中间还得不停纠偏。
Skills 改变的是这件事的底层逻辑。它不再是一段临时说说的 prompt,而是一整套“技能包”:里面包含任务背景、操作步骤、验收标准、参考示例,甚至配套的脚本和资源文件。AI Agent 会在合适的场景下自动翻开这个技能包,按里面的流程干活。
我用一个组内新人能听懂的比喻:MCP 是给 AI 开通数据库权限、浏览器权限这些“工具权限”;而 Skills 是给 AI 发一本岗位 SOP 手册。手册里写清楚了遇到什么情况先做什么、再做什么、做到什么程度算合格。
这才是 Skills 最近火爆的本质原因——大家终于意识到,与其每次用嘴皮子调教 AI,不如把优秀的工作方法沉淀成一个文件包,让 AI 自己按流程执行。
1.2 为什么偏偏是这个时候爆发
几个信号叠加在一起,把 Skills 推上了风口。
第一,主流 Agent 编程工具集中更新。Claude Code 从某个版本开始把 Skills 作为一等公民,Codex 也支持从本地目录加载 Skills,Cursor、OpenCode 这些工具陆续跟进。工具链一旦统一,社区的内容积累速度就会指数级上升。
第二,官方文档把“最小可用格式”定下来了。虽然各家实现略有差异,但核心都是一个 Markdown 文件,带 metadata(比如 name 和 description),把操作步骤写清楚。这个格式门槛很低,普通开发者看十分钟就能上手,所以一下子冒出来大量示例和模板库。
第三,也是我觉得最关键的:大家发现 AGENTS.md 和 SKILL.md 能组合成一套很稳定的“数字员工流程”。AGENTS.md 写项目总纲,Skills 管具体动作,Agent 在项目里既知道上下文,又有标准作业程序可依。相比以前每次对话都要重新“教育”模型,这套组合明显更接近真实团队的工作方式。
1.3 Skills 和普通 Prompt、MCP 是一回事吗?
不少朋友容易把它们搞混,我直接给一个最省心的区分:
- 普通 Prompt 是“一次性口述”——你说完就没了,下次还得再说。
- MCP 是“给 AI 接外设”——让 AI 能调用某个外部工具或数据源。
- Skills 是“给 AI 的作业流程”——它封装了做一件具体事情的方法论,可能用到 MCP,也可能不依赖任何 MCP。
举个例子,我想让 AI 帮我做接口测试用例设计。用普通 Prompt,我得把项目的接口定义、测试规范、边界值设计方法完整贴一遍。而如果我有一个“测试用例设计 Skills”,AI 发现当前任务是接口测试时,会自动读取技能包里的流程,先整理接口清单、再按规则生成用例矩阵、最后对照检查项自查。整个过程稳定、可复用、可版本管理,团队里任何人用 AI 产出质量都差不多。
这也是我强烈建议团队尽早沉淀 Skills 的原因:个人 prompt 是私房菜,Skills 是连锁店标准配方。
2. 拆一个成熟的 Skills,看看里面到底有什么
2.1 目录结构:不是只有那个 Markdown
很多人以为 Skills 就是一个 Markdown 文件,其实一个完整的 Skills 通常是一个目录,最常见的长这样:
~/your-skill-name/ ├── SKILL.md ├── assets/ │ └── template.html ├── references/ │ └── company-style-guide.md └── scripts/ ├── extract_api.py └── render_report.shSKILL.md 是入口文件,也是 AI 最先读取的内容;assets 放静态模板、图标这类资源;references 放参考资料,比如团队编码规范、接口约定;scripts 放可执行脚本,让 AI 可以跑一些实际动作。
从工程化角度来看,这个结构很像一个小型开源项目。SKILL.md 相当于 README + 使用手册,references 相当于文档中心,scripts 相当于工具函数库。拆得越清晰,AI 加载的时候就越知道该拿什么东西。
2.2 SKILL.md 的 metadata:AI 靠它决定“什么时候找你”
每个 SKILL.md 开头都有 metadata 区,Claude 和 Codex 的细节略有差别,但核心两个字段是共通的:name 和 description。
--- name: api-test-case-design description: 用于接口测试用例设计。当用户要求为 REST API 生成测试用例、补充边界测试或审查接口覆盖度时使用,不要用于 UI 自动化测试。 ---这里有个很多人忽略的关键点:AI 不会每次把所有 Skills 都读一遍,它是靠 description 来决定“这个任务要不要加载这个技能包”的。所以 description 不是写给人类看的简介,而是写给模型看的路由规则。
我见过太多人把 description 写成“用于生成测试用例”,结果 AI 在写 UI 测试、性能测试的时候也把它加载进来,既浪费上下文,又容易输出不相关的内容。
正确做法是像上面例子那样,把触发场景写清楚,再明确写一句“不要用于 XX 场景”。这种排除法能让路由准确率高一个量级。
2.3 正文怎么写,AI 才会“照做”
SKILL.md 的正文没有强制的统一格式,但社区里跑得好、口碑好的 Skills,几乎都有这几个层次:
- 操作目标:这个技能包最终要交付什么。
- 前置条件:开始前需要哪些输入、环境变量或权限。
- 执行步骤:按编号一步一步来,避免模型自由发挥。
- 完成标准 / 自检清单:怎么判断这次任务做完了、合格了。
- 兜底策略:遇到常见异常该怎么处理。
我自己测试下来,效果最大的一招是:把“怎么做”换成“做到什么标准算完”。比如“分析接口入参”是一个模糊指令,模型可能只列几个参数就交差。但如果我在步骤里写“对照 OpenAPI 文档逐个枚举每个接口的必填/可选/默认值参数,输出参数清单并标注类型约束”,模型的完成度会明显提升。
这背后的原理其实不复杂:模型在生成时倾向于“尽快完成用户指令”。如果你的指令里没有明确的完成边界,它会按自己的默认标准收尾。而步骤清单和自检清单就是在帮它锁死“完成”的定义。
2.4 脚本和参考资料是“重武器”
纯文本的 Skills 能解决的问题有限。真正“高级”的 Skills 往往带 references 或 scripts。
references 的好处是:不用把所有背景知识塞进 SKILL.md 正文,AI 可以在需要时深入查阅。比如做一个前端代码审查 Skills,references 里放一份团队的可访问性规范,比把规范全部抄进 SKILL.md 要省 token 得多。
scripts 更关键。Skill 本质上是让 AI 编排动作,但如果一个动作必须读文件系统、调接口、跑测试,纯靠模型“想象”是不行的。Skill 里可以写清楚:先运行某脚本读取接口定义,再基于脚本产出结果继续生成内容。相当于让模型既当指挥官,又能随时调用工具兵。
3. 手把手:从零写一个可复用的测试用例 Skill
3.1 先选一个足够小的场景
我建议你第一次写 Skills 的时候务必定一个非常小的需求,不要一上来就想做一个“全流程测试平台”之类的巨无霸。我踩过的坑就是一开始野心太大,想做一个“研发效能助手”,结果 SKILL.md 写了一千多行,AI 每次加载都吃大量上下文,而且经常抓不住重点。
后来我把场景切成一个个小块,先做了一个**“基于 OpenAPI 文档的接口测试用例生成 Skills”**。这个场景足够聚焦,验证起来也简单:丢一个接口定义文件进去,看它能不能输出完整的测试用例文档。
3.2 规划目录:个人级还是项目级
我想在 Claude Code 里跑,所以目录放在个人级目录:
~/.claude/skills/api-test-case/ ├── SKILL.md ├── references/ │ └── test-case-template.md └── scripts/ └── parse_openapi.py如果你只是想在某一个项目里用,那放在项目的.claude/skills/下就行。Codex 对应的路径也类似,逻辑是“全局技能放用户目录,项目技能放项目目录”。
目录命名我建议全小写加中划线,不要用空格,也不要使用大写。有些解析器在大小写混用的情况下会出奇怪的问题,一次踩坑之后我就老实了。
3.3 写 SKILL.md 的核心步骤
我最终的 SKILL.md 大致分这么几块:
--- name: api-test-case-design description: 基于 OpenAPI/Swagger 或接口定义文档生成接口测试用例。当用户要求为 REST API 设计接口测试用例、补充异常场景或生成接口测试清单时使用。 --- # API 测试用例生成 ## 任务背景 本技能用于将后端接口定义转化为可直接导入测试管理平台的测试用例,覆盖正常路径、异常路径和边界条件。 ## 执行步骤 1. 读取接口定义文件。优先寻找项目根目录下的 openapi.yaml / openapi.json / swagger 文件;如果找不到,询问用户提供接口文档路径。 2. 运行脚本解析接口,提取路径、请求方法、参数约束和响应码: ```bash python scripts/parse_openapi.py <api-file>- 针对每个接口,按下面的模板生成用例:
- 正常路径:至少 1 条完整成功请求。
- 参数校验:必填缺失、类型错误、边界值(最小值、最大值、长度限制)。
- 业务异常:依赖状态不满足、资源不存在、权限不足。
- 响应断言:不仅断言 HTTP 状态码,还要断言关键响应体字段。
- 输出为 Markdown 表格,每个接口一个小节,最终汇总到
test-cases.md。
完成标准
- 覆盖输入接口定义中 100% 的路径。
- 每个路径至少包含 1 条正常用例 + 3 条异常/边界用例。
- 所有用例的请求方法、URL、请求体和预期结果完整可执行。
注意事项
- 不要臆造接口定义之外的字段。
- 如果接口文档缺失响应结构,先标注“待补充”,不要编造。
这段文字看起来简单,但我前后改了很多版,最后固定的做法参考了一些成熟技术写作的原则:**步骤要原子化,每条都有明确的动作对象或产出物**,而不是随便写一句“分析接口合理性”就完了。 ### 3.4 用脚本让技能“干重活” 纯靠模型去读一个几百行的 OpenAPI 文件很浪费 token,而且模型在解析复杂 YAML 时容易出错。我在 script 里做了“初筛”,把接口定义提炼成一个精简的 JSON 供模型使用。 ```python #!/usr/bin/env python3 import json, sys, yaml from pathlib import Path def load_api(path: Path): if path.suffix.lower() in [".yaml", ".yml"]: with open(path, "r", encoding="utf-8") as f: return yaml.safe_load(f) return json.loads(path.read_text(encoding="utf-8")) def extract_endpoints(api: dict) -> list: endpoints = [] for path, methods in api.get("paths", {}).items(): for method, op in methods.items(): if method.lower() in ("get", "post", "put", "delete", "patch"): params = [] for p in op.get("parameters", []): params.append({ "name": p.get("name"), "in": p.get("in"), "required": p.get("required", False), "type": p.get("schema", {}).get("type", "unknown") }) endpoints.append({ "path": path, "method": method.upper(), "summary": op.get("summary", ""), "params": params, "request_body": bool(op.get("requestBody")), }) return endpoints if __name__ == "__main__": api_file = Path(sys.argv[1]) api = load_api(api_file) print(json.dumps(extract_endpoints(api), ensure_ascii=False, indent=2))这样模型拿到的不是一坨原始 YAML,而是经过预处理的精确清单。它在生成测试用例时,直接基于结构化数据写表格就行,答案的准确率明显提高。这也反映了一个通用的设计思路:Skill 里能通过脚本代劳的粗活、累活,就不要让模型从头算。
3.5 安装到不同工具中
不同客户端的路径和格式要求不完全一样,我实测过的几种情况见下表:
| 工具 | 推荐位置 | 说明 |
|---|---|---|
| Claude Code | ~/.claude/skills/或项目.claude/skills/ | 官方文档里有详细说明,支持个人级和项目级 |
| Codex | ~/.codex/skills/或项目.codex/skills/ | 需要 SKILL.md 的 metadata 里有 name 字段 |
| OpenCode | 通过 CLI 导入 | 部分版本支持opencode skills add命令 |
安装后最好重启一次会话,然后通过工具的/skills或类似命令确认新技能已经被加载。如果工具没有内置查看命令,可以故意用一个能触发该 Skill 的请求,看它是否自动加载。
3.6 测试闭环:别急着对外发布
把 SKILL.md 写完、脚本跑通后,我第一次测试的时候用的不是真实接口,而是一个自己构造的 mock OpenAPI 文件。这样做的好处是,我知道所有“正确答案”,能非常清楚地判断 AI 是否按照技能里的步骤生成用例。
我强烈建议你也这样测一轮:给一个只有 3 个接口的小文件,看 AI 的输出是否包含自检清单要求的所有内容。如果它跳步、漏项,就说明 SKILL.md 里的指令粒度还不够细。迭代两三次之后,再拿真实项目文档去测。这样能避免在调优过程中被庞大的业务细节干扰。
4. 为什么你的 Skills 经常不生效?问题排查实录
4.1 症状一:明明写了 Skill,AI 就是不调用
这是评论区里出现最多的问题。大多数时候不是工具坏了,而是 SKILL.md 里的 description 写得不够“可路由”。
举个例子,你把 description 写成“一个测试技能”,模型根本不知道什么任务跟它相关。AI Agent 的加载机制本质上是一个匹配过程:用户请求里的语义和 description 里的语义越接近,命中的概率越高。
排查方法很简单:把自己假装成一个用户,把你期望触发这个 Skill 的话术拿到 description 里比对。如果你都看不出这两者之间的关联,那模型自然更看不出来。修法就是加关键词、加触发场景、加排除条件。
4.2 症状二:加载了,但行为完全不符合预期
这种“听劝但不听话”的情况通常有三个原因。
第一是步骤写得太“散文化”。模型执行的时候需要的是明确动词加宾语,而不是“请充分考虑各种情况”这种正确的废话。
第二是缺少自检清单。如果步骤结束后没有一个“完成标准”强制约束,模型很容易输出一个“看起来差不多”的半成品。我把“完成标准”加到测试用例 Skill 里之后,漏路径的情况基本消失。
第三是 SKILL.md 文件太大,模型在加载时无法判断哪些内容与当前任务相关。如果一个技能包超过几百行,我建议把细节移到 references 里,正文只保留流程骨架。
4.3 症状三:放的位置没生效
很多工具区分“用户级 Skill”和“项目级 Skill”,两者的优先级不一样;同时,SKILL.md 的文件名、目录名如果大小写不一致,也可能导致加载失败。老实说,这类问题最折腾人,我的建议是先跑一个官方文档里的最小示例,确认路径和格式 OK,再替换成你自己的内容。
4.4 常见问题速查表
| 表现 | 大概率原因 | 建议操作 |
|---|---|---|
| 完全不触发 | description 与用户意图语义不匹配 | 重写 description,加入具体触发词和排除词 |
| 偶尔触发,不稳定 | description 过于宽泛,被其他技能抢占 | 缩小范围,多写场景,避免与其他技能重叠 |
| 触发了但质量差 | SKILL.md 步骤不清晰,没有验收标准 | 把步骤拆细,增加“完成标准”清单 |
| 找不到技能 | 路径放错或目录名不规范 | 检查目录完整路径,重启会话 |
| 加载后很占 token | 正文太长,参考资料入库 | 把细节移到 references 中 |
4.5 排查问题时的“最小复现”思路
我跟很多同行交流后发现,Skills 调试和写代码调试遵循同样的规律——最小复现永远是最省时间的。先做一个只含一个动作的最小 Skill,放在一个空目录里,跑通之后再往里面加步骤、加脚本。不要一上来就在一个 800 行的 SKILL.md 里排查问题,那会消耗太多耐心。
5. Skills 越来越多,“找资源和避坑”才是正经事
5.1 想用别人写好的 Skills,去哪里找
社区里的 Skills 资源目前处于爆发期,想找现成的,主要是这几个渠道:
- 各家的官方示例仓库和官方博客,质量最稳,示例代码可以直接跑通。
- GitHub 上的 awesome 类仓库,比如 awesome-claude-skills、awesome-agent-skills,但收录质量参差不齐。
- 一些独立开发者会把自己沉淀的 Skills 发布到个人博客或开源仓库,这类往往最贴近真实业务场景,价值很高。
找的时候建议大家看几个硬指标:README 里有没有写清楚适用场景和边界、SKILL.md 里有没有完整的 metadata 和步骤说明、最近有没有维护记录。只看标题和截图就安装,大概率踩坑。
5.2 聊聊“作者的瓜”:现象是真实的
这个标题既然说了“文末附作者的瓜”,我得兑现,但不能点具体人,因为真假是非不是一两句能说清的。这段时间社区里讨论最多、我也实际踩过一些的,是下面几类现象。
第一类是**“搬运打包卖钱”**。有人把 GitHub 上开源的 Skills 仓库原封不动或略微改名,就放到付费平台上去卖。很多刚入门的朋友不知道原版是免费的,稀里糊涂就付费了。判断方法不复杂:把 Skill 里的描述性句子随便摘几句,放到搜索框里搜一下,如果出来的是一堆相似开源项目,那这个很可能是搬运货。
第二类是**“夹带私货”**。这一点我希望大家格外重视:Skill 不只是给 AI 读的文档,里面还可能有脚本,而脚本是会被 Agent 实际执行的。万一你在网上下一份来路不明的 Skill,里面 scripts/ 目录放了一个安装时自动执行 curl、把用户环境信息发到某个服务器的命令,后果是很严重的。这个风险比普通插件更高,因为它披着“提效工具”的外衣,普通用户很少会逐行检查脚本内容。
第三类是**“先免费引流,再偷偷改协议”**。有些作者先用免费 Skill 吸引大量安装,用户量起来之后把仓库改成“禁止商用”或者塞进付费墙,甚至把 Skill 的编排逻辑设计成依赖作者自己的付费 API。到时候你换一个 API key 就没法用,等于被绑定了。这也是为什么最好一开始就选择授权清晰、不依赖特定中转服务的 Skills。
第四类是**“过度包装”**。比如把一个很基础的“总结 .md 文件”功能包装成“项目级智能助手”,描述写得天花乱坠,还配一堆看似高大上的架构图。实际跑到真实项目里,效果远不如自己二十分钟手写的专用技能。
我不主张一杆子打死所有商业化的 Skills 作者,毕竟持续维护需要收益,这是正常的事。但从使用者角度,在安装任何一个第三方 Skill 前,都值得多问一句:它到底干了什么、凭什么值得我信任?
5.3 收到一份新 Skills,先做三个安全检查
我现在拿到一份陌生的 Skills,流程基本固定,你可以直接抄作业:
- 打开 SKILL.md 从头到尾读一遍,重点看描述里有没有藏着不属于当前任务的“额外动作”,比如读取敏感文件、调用不明外部接口。
- 审视 scripts/ 目录下所有脚本,不要求你精通代码,但至少要搜索几个高危模式:
curl、wget、eval、base64 -d、os.system、subprocess。如果这些命令的目标地址是不明域名,基本可以判定不干净。 - 先放在测试项目里运行一次,观察输出日志。确认它不会去碰项目之外的文件、不会触发额外网络请求,再放到日常目录中使用。
5.4 我的经验:自己写,通常比到处找更好
可能有人觉得网上现成的 Skills 那么多,没必要自己写。但我的真实体会是,最贴合自己工作流的 Skill 一定是你自己写的那一个。
因为 AI 编程的个人风格差异太大了:你习惯先看测试还是先写注释、你的项目里有哪些特殊流程、你的团队规范长什么样,这些信息别人不可能比你自己更清楚。网上找到的通用 Skill 能解决 70% 的需求,剩下 30% 的细节,才是真正拉开使用体验差距的地方。
而写作的过程本身,也是在帮你重新审视自己的工作流程。我为了写“接口测试用例设计 Skills”,把自己平时嘴上说的一套测试方法老老实实落成了文字,才发现里面有不少地方连我自己都没想清楚。就冲这一点,写一遍就不亏。
写在最后的一点体会
如果你也想开始尝试 Skills,我的建议是先挑一个你平时重复次数最多、但又不需要太多创造力的小任务,把它做成一个最简单的 SKILL.md 文件,用起来再说。别急着学那些花哨的交叉引用、脚本编排、上下文注入之类的技巧,先把一个“能触发、能按流程产出、有验收标准”的闭环跑通,再慢慢往里面加东西。
我自己在这一个多星期里,最大的收获倒不是终于把某个技能调得多么聪明,而是意识到一个趋势:AI 编程的竞争点正在从“模型会不会”转向“人会不会把经验结构化地喂给模型”。Skills 刚好提供了一种低门槛、可积累、可协作的方式来做这件事。
我自己当前在项目里用得最多的其实是一个代码审查辅助技能,一开始就是照着本文的思路写了三十行 SKILL.md,后面随着团队规范更新慢慢迭代。如果你手头有一个特别适合做成 Skill 的场景,欢迎在评论区聊聊你的思路,我也很好奇大家在实际落地中最卡壳的是哪一步。