1. 从“skills”这个热词说起:它到底在解决什么问题
最近半年,不管是在技术社区还是开发者群里,“skills”这个词出现的频率高得离谱。你随便翻一下热搜词列表就能看到:skills、codex skills、claude agent skills、skills开发、skills推荐、find skills、agent skills测试……这些词扎堆出现,说明一件事:围绕 AI 编程助手的能力扩展机制,正在成为一线开发者真正关心的东西。
我最早接触这个概念是在折腾 Claude Code 和 Codex 的时候。当时我的困惑很具体:这些 AI 编程工具本身已经能读写文件、跑命令、改代码了,但为什么还要搞一个叫 skills 的东西?后来用多了才明白,skills 本质上是给 AI 助手装“技能包”——把一套可复用的操作流程、领域知识、工具调用方式打包成一个标准单元,让 AI 在遇到特定任务时能直接调用,而不是每次从零开始猜。
打个生活化的比方:AI 助手就像一个刚入职的聪明新人,脑子好使但不懂你们公司的规矩。skills 就是你写给它的《岗位操作手册》——遇到什么场景、按什么步骤、用哪些工具、注意哪些坑,全写清楚。它照着做,输出质量立刻从“能用”跳到“靠谱”。
这篇文章我想把 skills 这件事从头到尾讲透。包括它为什么会出现、核心机制是什么、怎么从零开发一个自己的 skill、在 Claude Code 和 Codex 里怎么落地、踩过哪些坑、以及我实测下来比较稳的一套工作流。适合三类人看:一是刚开始用 AI 编程助手、想搞清楚 skills 到底值不值得投入的新手;二是已经在用 Claude Code 或 Codex、但还没系统化沉淀自己技能包的中级用户;三是想给团队做 AI 能力标准化的技术负责人。不管你是哪一类,看完应该都能直接上手抄作业。
2. skills 的核心机制拆解:它凭什么让 AI 变聪明
2.1 一句话说清 skills 的本质
skills 的本质是结构化的能力封装。它不是简单的提示词模板,而是一个包含元数据、触发条件、执行步骤、工具依赖、输出规范的完整单元。你可以把它理解成一个“函数”——有输入、有处理逻辑、有输出,只不过这个函数是给 AI 看的,不是给编译器看的。
为什么需要这种封装?因为大模型有个天然缺陷:上下文窗口有限,而且注意力会稀释。你把一堆操作规范全塞进系统提示词里,模型在长对话中很容易“忘记”或者“串味”。skills 的做法是把能力拆成独立模块,只在需要的时候加载对应的那一个。这就像你电脑里装了几十个软件,但不会同时全打开——用哪个开哪个,内存和注意力都省下来了。
2.2 skills 和普通提示词、plugin 的区别
很多人搞不清 skills、plugin、agents 这几个概念的关系。我用一张表说清楚:
| 概念 | 本质 | 加载方式 | 典型用途 |
|---|---|---|---|
| 提示词 | 一段文字指令 | 每次手动输入或固定在系统提示 | 简单问答、单次任务 |
| skills | 结构化能力包 | 按需触发或显式调用 | 可复用的多步骤流程 |
| plugin | 外部程序扩展 | 安装后常驻或按需调用 | 接入外部工具、API |
| agents | 自主决策主体 | 独立运行或嵌套调用 | 复杂任务的自动编排 |
关键区别在于:提示词是“说”,skills 是“教”,plugin 是“接”,agents 是“派”。skills 处在中间层,它既不像提示词那么随意,也不像 plugin 那样需要写代码接外部系统,而是把“怎么做一件事”的知识和流程固化下来。
2.3 skills 的目录结构与元数据规范
一个标准的 skill 通常是一个目录,里面至少包含一个主描述文件。以我实际用的结构为例:
my-skill/ ├── SKILL.md # 主描述文件,包含元数据和执行说明 ├── scripts/ # 可选的辅助脚本 │ └── helper.py ├── templates/ # 可选的模板文件 │ └── output.md └── references/ # 可选的参考资料 └── api-doc.mdSKILL.md是核心,它的头部通常用 YAML frontmatter 写元数据:
--- name: api-endpoint-generator description: 根据数据模型定义自动生成 RESTful API 端点代码 version: 1.0.0 triggers: - "生成API" - "create endpoint" - "写接口" tools: - read_file - write_file - run_command ---这里有几个细节值得说。name要短且唯一,别用中文,因为很多工具链对文件名的处理还是 ASCII 友好。description是给模型看的,要写清楚“这个 skill 干什么、什么时候用”,模型靠它来判断是否触发。triggers是显式触发词,用户说到这些词时优先加载。tools声明这个 skill 需要哪些工具权限,这是个安全边界——不需要的工具就别声明,减少误操作风险。
2.4 为什么 skills 现在才火起来
其实“能力封装”这个思路不新鲜,早年的工作流引擎、RPA 工具都在做类似的事。skills 之所以现在爆发,是因为三个条件同时成熟了:第一,大模型的理解能力足够强,能读懂自然语言写的操作手册并忠实执行;第二,AI 编程助手开始支持动态加载外部能力,不再是一锤子买卖的提示词;第三,社区形成了事实上的标准结构,大家写的 skill 能互相复用。
我个人的判断是,skills 会成为 AI 编程时代的“npm 包”——未来你评估一个 AI 助手好不好用,不光看模型本身,还要看它的 skill 生态丰不丰富。这也是为什么热搜里会出现find skills、skills推荐、skills官方下载这类词,大家已经在找现成的轮子了。
3. 从零开发一个自己的 skill:完整实操流程
3.1 先想清楚:什么样的任务值得做成 skill
不是所有事都值得封装。我踩过的第一个坑就是什么都想做成 skill,结果维护成本比收益还高。判断标准很简单:这个任务是否重复出现、步骤是否相对固定、输出是否有明确标准。三个都满足,才值得做。
举个例子,“帮我改个 bug”不值得做 skill,因为每次 bug 都不一样。但“根据数据库表结构生成 CRUD 接口代码”就值得,因为步骤固定:读表结构 → 生成模型 → 生成路由 → 生成测试 → 写文档。这种重复性高、流程清晰的任务,做成 skill 后效率提升非常明显。
我一般用这个清单来筛选:
- 每周至少执行 2 次以上
- 步骤超过 3 步且顺序基本固定
- 涉及多个工具或文件的协同操作
- 有明确的“做完了”的判断标准
- 新手容易做错、需要经验判断的环节
3.2 手把手写第一个 skill:以“接口代码生成器”为例
我拿一个真实做过的 skill 来演示。需求是:给一个数据模型定义文件,自动生成对应的 RESTful 接口代码,包括路由、控制器、服务层和单元测试。
第一步,建目录:
mkdir -p ~/.claude/skills/api-endpoint-generator cd ~/.claude/skills/api-endpoint-generator touch SKILL.md第二步,写元数据头:
--- name: api-endpoint-generator description: 读取数据模型定义,生成完整的RESTful API代码,包含路由、控制器、服务层和测试。当用户要求生成接口、创建API端点、或提到endpoint generation时使用。 version: 1.0.0 triggers: - "生成接口" - "生成API" - "create endpoint" - "写CRUD" ---第三步,写执行说明。这部分是 skill 的灵魂,要写得像给一个聪明但不懂你项目的新人看的操作手册:
## 执行步骤 1. 读取用户指定的模型定义文件,确认字段名、类型、是否必填、关联关系 2. 检查项目现有的目录结构,确定代码应该放在哪个目录 3. 按照项目现有的代码风格生成以下文件: - 路由文件:定义 HTTP 方法和路径 - 控制器:处理请求参数校验和响应 - 服务层:业务逻辑 - 测试文件:覆盖正常流程和边界情况 4. 运行项目的 lint 和测试命令,确认生成代码能通过 5. 输出生成的文件清单和需要人工确认的地方 ## 注意事项 - 字段命名遵循项目现有的命名规范,不要自己发明 - 如果模型有外键关联,需要生成对应的关联查询 - 分页参数默认使用 page 和 pageSize - 所有接口必须包含错误处理第四步,测试。写完不代表能用,要实际跑几个案例验证。我会准备三个测试用例:一个简单模型、一个带关联的复杂模型、一个边界情况(比如字段全是可选)。跑完看输出是否符合预期,不符合就回去改说明。
3.3 让 skill 更可靠的三个技巧
技巧一:把判断逻辑写清楚,别让模型猜。比如“根据项目风格生成代码”这种话太模糊,模型会自由发挥。改成“先读取项目根目录的.eslintrc和现有 controller 文件,提取命名规范和代码结构,再按这个模式生成”,模型就有明确依据了。
技巧二:设置检查点。在关键步骤后加一句“确认 XXX 后再继续”,让模型有机会自我校验。我实测下来,加了检查点的 skill 出错率能降一半以上。
技巧三:提供反面案例。在说明里写“不要这样做”往往比“要这样做”更有效。比如“不要生成 console.log 调试语句”“不要修改模型定义文件本身”,这些明确的禁止项能避免很多低级错误。
3.4 skill 的版本管理与迭代
skill 是要迭代的。我建议用 git 管理 skill 目录,每次修改都提交,这样能追溯哪个版本效果好。版本号遵循语义化版本:修 bug 升 patch,加功能升 minor,改结构升 major。
迭代的触发点通常是:用了三次以上发现同一个问题、项目技术栈变了、或者社区出了更好的写法。我一般每个月回顾一次自己常用的 skill,把反复出现的问题固化到说明里。
4. 在 Claude Code 和 Codex 里落地 skills 的实战细节
4.1 Claude Code 的 skills 加载机制
Claude Code 对 skills 的支持相对成熟。它的加载逻辑是:启动时扫描 skills 目录,读取所有SKILL.md的元数据,建立索引。当用户输入触发词或任务描述匹配到某个 skill 的 description 时,就把那个 skill 的完整内容加载进上下文。
这里有个实操细节:skills 目录的位置很关键。全局 skill 放在用户主目录下的配置目录里,项目级 skill 放在项目根目录的特定文件夹里。项目级的优先级更高,适合放跟这个项目强相关的 skill。我一般把通用的放全局,把项目特有的放项目里。
另一个细节是加载顺序。如果多个 skill 的触发词重叠,Claude Code 会按优先级和匹配度排序。所以写 description 时要尽量精确,避免跟别的 skill 抢触发。我遇到过两个 skill 都写了“生成代码”作为触发词,结果经常加载错的那个,后来把触发词改具体就好了。
4.2 Codex 的 skills 使用方式
Codex 这边的机制略有不同,它更强调 skill 作为“可调用工具”的一面。在 Codex 里,skill 可以声明自己需要哪些底层能力,然后 Codex 在运行时按需注入。热搜里codex skills、codex好用的skills这些词热度高,说明大家确实在找 Codex 生态里的 skill 资源。
Codex 的一个特点是它对 skill 的输入输出格式要求更严格。因为 Codex 经常被用在自动化流程里,skill 的输出需要能被下游程序解析。所以写 Codex 用的 skill 时,我会在说明里明确指定输出格式,比如“以 JSON 格式输出,包含 files 数组和 summary 字段”。
4.3 跨工具复用 skill 的兼容性处理
理想情况是一个 skill 在 Claude Code 和 Codex 里都能用,但实际会有差异。我的做法是:核心逻辑写一份,工具特定的适配层分开写。比如执行步骤是通用的,但工具声明和输出格式针对不同平台各写一份,用条件判断或者放在不同的子目录里。
具体操作上,我会在SKILL.md里用注释标记平台特定的部分:
<!-- platform: claude-code --> tools: - read_file - write_file <!-- platform: codex --> capabilities: - file_io - shell_exec然后在加载时根据平台选择对应的配置。这样维护一份核心逻辑,适配成本可控。
4.4 本地模型接入时的注意事项
热搜里有个词是claude code 调用lmstudio的本地模型,说明不少人想在本地跑。本地模型用 skills 时有个现实问题:上下文窗口通常比云端模型小。这意味着 skill 的说明不能写太长,否则加载进去就没剩多少空间给实际任务了。
我的应对策略是:本地模型用的 skill 要精简,把详细说明拆成多个小 skill,按需加载。另外本地模型的指令遵循能力可能弱一些,说明要写得更直白,少用抽象表述,多用具体例子。
5. 常见问题与排查技巧实录
5.1 skill 不触发或触发错误怎么办
这是最高频的问题。排查顺序我总结成一张表:
| 现象 | 可能原因 | 排查方法 | 解决方式 |
|---|---|---|---|
| 完全不触发 | 目录位置不对 | 检查 skills 目录路径 | 移到正确的配置目录 |
| 完全不触发 | 元数据格式错误 | 检查 YAML 头是否合法 | 用 YAML 校验工具验证 |
| 偶尔触发 | 触发词太泛 | 看是否跟其他 skill 冲突 | 改具体触发词 |
| 触发错的 skill | description 太相似 | 对比两个 skill 的描述 | 差异化描述,明确边界 |
| 加载后不执行 | 说明太模糊 | 看模型是否理解了步骤 | 把步骤拆得更细更具体 |
我踩过最坑的一次是 YAML 头里用了中文引号,导致解析失败,但工具不报错,只是静默不加载。后来养成习惯,写完先用工具校验一遍元数据。
5.2 skill 执行结果不稳定的处理
同样的 skill,有时候输出很好,有时候一塌糊涂。这种不稳定通常来自三个地方:一是说明里有歧义,模型每次理解不一样;二是依赖的外部状态变了(比如项目结构改了);三是任务本身太复杂,超出了单个 skill 的处理能力。
我的处理办法是加约束、加检查、拆任务。加约束是把模糊表述改成明确规则;加检查是在关键节点让模型自检;拆任务是把大 skill 拆成几个小 skill 串起来用。实测下来,一个 skill 的执行步骤超过 7 步就该考虑拆分了。
5.3 权限与安全边界设置
skills 能调用工具,就有误操作风险。我给自己定的规矩是:最小权限原则。一个 skill 只声明它真正需要的工具。比如只是生成代码的 skill,就不该有删除文件的权限。涉及写操作的 skill,我会在说明里加一句“修改前先备份或确认”。
另外,从外部来源获取的 skill 一定要先审一遍再装。热搜里skills官方下载、前任skills官方下载这类词说明大家在找现成资源,但第三方 skill 可能包含你不想要的工具调用或数据外发行为。我的习惯是装之前先读一遍SKILL.md,看它声明了哪些工具、有没有可疑的外部调用。
5.4 性能与上下文占用的优化
skill 加载会占上下文,加载太多会拖慢响应、增加成本。优化思路是:按需加载、精简内容、缓存结果。按需加载靠精确的触发条件;精简内容是把说明里不必要的解释删掉,只留可执行的部分;缓存结果是把 skill 执行中产生的中间结果存下来,下次复用。
我实测过一个对比:一个写得很啰嗦的 skill(说明 2000 字)和一个精简版(说明 500 字),执行同样任务,精简版速度快 30% 左右,输出质量基本持平。所以别把 skill 当文档写,要当操作指令写。
6. 我实测下来的一套 skills 工作流
6.1 日常开发中的 skill 组合使用
我现在的工作流是这样的:早上开始干活前,先看今天要做什么。如果是重复性任务,先想有没有现成 skill;没有就快速写一个。写代码时,用“代码生成”类 skill 起骨架,用“代码审查”类 skill 检查,用“测试生成”类 skill 补测试。三个 skill 串起来,一个功能的开发时间能压缩一半左右。
关键是skill 之间要能衔接。比如代码生成 skill 的输出格式,要能被代码审查 skill 直接读取。我在写 skill 时会考虑上下游,把输出格式设计成通用的结构,方便串联。
6.2 团队协作中的 skill 共享
团队里用 skill,最大的问题是标准不统一。我的做法是建一个共享的 skill 仓库,大家把自己写的 skill 提交上去,定期评审。评审看三点:触发条件是否清晰、步骤是否可复现、有没有安全隐患。通过评审的 skill 打上版本标签,团队成员按需拉取。
这里有个经验:别追求大而全的 skill。团队里最容易失败的就是那种想覆盖所有情况的“万能 skill”,最后谁都看不懂。反而是小而专的 skill 活得好,一个 skill 干一件事,组合起来用。
6.3 持续迭代与效果度量
怎么知道一个 skill 好不好用?我跟踪三个指标:触发准确率(该触发时触发、不该触发时不触发)、执行成功率(一次跑通的比例)、人工修正率(输出需要改多少)。这三个指标每周看一次,哪个下降就优化哪个。
触发准确率低就改触发词和 description;执行成功率低就细化步骤;人工修正率高就补充约束和示例。这套度量方法用下来,我的核心 skill 成功率从最初的六成左右提到了九成以上。
6.4 给新手的入门建议
如果你刚开始接触 skills,我的建议是从模仿开始。先找几个社区里评价好的 skill,读它们的SKILL.md,理解结构。然后挑一个你每天都要做的重复任务,照着写一个。别一上来就追求完美,先跑通,再迭代。
另外,别急着装一堆 skill。我见过有人装了上百个 skill,结果触发混乱、互相干扰。我的建议是保持精简,常用的不超过十个,每个都经过实际验证。skill 的价值在于精而不在于多。
最后分享一个我踩过的坑:早期我写的 skill 说明里全是“应该”“尽量”“最好”这种软性表述,结果模型执行时经常偷懒。后来全改成“必须”“禁止”“如果 X 则 Y”这种硬性规则,执行稳定性立刻上来了。写 skill 不是写建议书,是写操作规程,语气要硬,规则要死。