1. 从"skills"这个热词说起:它到底在解决什么问题
最近一段时间,不管是在技术社区还是开发者群聊里,"skills"这个词出现的频率高得离谱。很多人第一次看到它,会以为是某种新的编程语言特性,或者某个框架的插件系统。但如果你真的去翻一翻围绕 Claude Code、Codex、各类 agents 的讨论,就会发现大家嘴里的 skills 其实指向一个很具体的东西:给 AI 编程助手预置的一套可复用的能力包。
我最早接触这个概念,是因为团队里有人在用 Claude Code 做日常开发,结果发现每次让它处理特定任务时,都要重复写一大段提示词,比如"帮我按这个规范生成组件""帮我检查这段代码的安全问题"。写多了就烦,而且不同人写的提示词质量参差不齐,输出结果自然也不稳定。后来有人提出:能不能把这些反复用到的指令、流程、约束条件打包成一个固定的东西,让 AI 每次都能按同一套标准来干活?这就是 skills 诞生的最朴素动机。
说白了,skills 就是把"你怎么跟 AI 说话"这件事标准化、模块化。它不是一个抽象概念,而是一组实实在在的文件和配置,里面写清楚了某个任务该怎么做、按什么顺序做、注意哪些坑、输出成什么格式。你可以把它理解成给 AI 助手准备的"作业指导书"——以前你得口头交代一遍,现在直接把指导书递过去,它照着执行就行。
这个思路一旦成立,价值就非常明显了。对于个人开发者来说,skills 能帮你把重复劳动压缩掉;对于团队来说,skills 能保证所有人用 AI 产出的东西风格一致、质量可控;对于更复杂的 agents 场景来说,skills 就是让多个 AI 协作时不跑偏的"共同语言"。所以你会看到,围绕 skills 的讨论迅速从"这是什么"变成了"有哪些好用的 skills""怎么自己写 skills""skills 和 plugin 有什么区别"。
这篇文章不打算给你堆一堆概念,而是想把这几个月我在实际使用和折腾 skills 过程中积累的东西讲清楚。包括它背后的运行逻辑、怎么从零写一个能用的 skill、常见的坑在哪里、以及当 skills 和 Claude Code、Codex 这些工具结合时要注意什么。如果你正在用或者准备用 AI 编程助手,这篇内容应该能帮你少走不少弯路。
2. skills 的运行机制:它凭什么能让 AI "记住"你的要求
2.1 从提示词工程到能力封装,中间差了什么
很多人会把 skills 和"写一段好的提示词"混为一谈,觉得不就是把提示词存成文件吗?这个理解只对了一半。提示词工程解决的是"这一次怎么问",而 skills 解决的是"这一类任务以后都怎么问"。前者是一次性的,后者是可复用的。
我举个实际例子。假设你要让 AI 帮你写一个 React 组件。普通的做法是每次打开对话框,输入"帮我写一个 React 组件,用函数式写法,带 TypeScript 类型,样式用 CSS Modules,不要用 any"。这段话你写十次就是十次,写一百次就是一百次。而 skill 的做法是:把这段话连同更细的规范——比如命名用 PascalCase、props 必须定义 interface、事件处理函数用 handle 开头——全部写进一个结构化的文件里。以后你只需要说"用组件 skill 写一个用户卡片",AI 就会自动加载那套规范。
这里的关键差异在于上下文的组织方式。普通提示词是散落在对话里的,AI 每次都要重新理解;而 skill 是有固定结构的,它通常包含几个部分:触发条件(什么时候用这个 skill)、执行步骤(先做什么后做什么)、约束规则(不能做什么)、输出格式(结果长什么样)。这种结构让 AI 在加载 skill 时,能快速抓住重点,而不是在一大段自然语言里猜你的意图。
2.2 skill 文件里到底装了什么
虽然不同工具对 skill 的具体格式要求不一样,但核心组成是相通的。我拿自己写的一个代码审查 skill 来拆解,你可以对照着看。
第一部分是元信息。包括这个 skill 叫什么、什么场景下触发、适用哪些文件类型。这部分的作用是让 AI 知道"我现在该不该用这个 skill"。比如你写了一个专门审查 Python 的 skill,那遇到 JavaScript 文件时就不应该触发它。
第二部分是执行流程。这是 skill 的骨架,通常用有序列表或者分步骤的方式写。比如代码审查 skill 的流程可能是:先检查语法错误,再看类型标注是否完整,然后检查边界条件处理,最后看有没有安全隐患。每一步还可以附带具体的检查点。
第三部分是约束和禁忌。这部分特别重要,因为 AI 很容易"过度发挥"。比如你要求它审查代码,它可能顺手把代码重构了。所以在 skill 里要明确写:只报告问题,不修改代码;如果发现问题,按严重程度分级;不确定的地方标注出来而不是瞎猜。
第四部分是输出模板。规定结果用什么格式呈现。是表格、列表还是分段描述?严重问题用什么标记?这些都要写清楚,否则每次输出格式都不一样,后续处理起来很麻烦。
提示:skill 文件不是越长越好。我见过有人写了一个两千行的 skill,结果 AI 加载后反而抓不住重点。一般来说,单个 skill 控制在几百行以内,把最关键的规则写清楚就够了。
2.3 为什么 skills 能和 agents 配合得这么好
单独看 skill,它只是一个静态的说明书。但当它和 agents 结合时,威力就出来了。Agent 的本质是"能自主决策并执行多步任务的 AI",而 skill 给它提供了"做某类任务时的标准操作程序"。
打个比方,agent 像一个新入职的员工,能力很强但不知道你们公司的规矩。Skill 就是员工手册,告诉他报销怎么走流程、代码提交有什么规范、跟客户沟通要注意什么。没有 skill 的 agent,每次都要你手把手教;有了 skill,它就能按既定规则自主运转。
在实际的 agents 场景里,通常会有一个 skill 库,agent 根据当前任务自动匹配并加载对应的 skill。比如一个负责前端开发的 agent,遇到"新建页面"任务时加载页面脚手架 skill,遇到"性能优化"任务时加载性能检查 skill。这种动态加载机制,让一个 agent 能覆盖多种任务类型,而不需要为每种任务单独训练一个模型。
3. 动手写第一个 skill:从需求拆解到落地验证
3.1 先想清楚:什么任务值得做成 skill
不是所有事情都值得封装成 skill。我踩过的坑是,一开始兴致勃勃地把各种零碎要求都写成 skill,结果维护成本比收益还高。后来总结出一个判断标准:这个任务是否高频、是否有固定套路、是否容易因为人为疏忽而出错。三个条件同时满足,才值得做成 skill。
高频很好理解,一天要用好几次的才值得封装。有固定套路指的是任务步骤相对稳定,不会每次都有大变化。容易出错则是指人工做的时候经常漏掉某些环节,或者不同人做出来的结果差异很大。
按这个标准,我目前保留的 skill 主要有几类:代码审查、组件生成、接口文档编写、提交信息规范化、以及特定框架的脚手架搭建。而那些一次性的、探索性的任务,我从来不做成 skill,因为做了也用不了几次。
3.2 把"老手直觉"翻译成可执行步骤
写 skill 最难的地方,是把你自己做这件事时的直觉拆解成明确的步骤。因为老手做很多事情是"下意识"的,你问他怎么做,他说"就那样做啊"。但 AI 需要的是明确的指令。
我的方法是边做边记录。比如我要写一个"生成 API 接口"的 skill,我就先自己手动做一遍,做的过程中把每个决策点记下来:为什么先定义请求参数而不是响应结构?为什么错误码要用这个格式?为什么这个字段要加校验?把这些"为什么"写进 skill,AI 才能理解背后的逻辑,而不是机械执行。
还有一个技巧是找反例。想想你见过哪些做得不好的情况,把这些反面案例写进 skill 的禁忌部分。比如"不要生成没有错误处理的接口""不要用模糊的类型定义""不要在响应里暴露内部字段"。反例往往比正例更能约束 AI 的行为。
3.3 一个可复用的 skill 模板长什么样
下面是我自己常用的一个 skill 结构模板,你可以直接拿去改。注意不同工具的语法可能有差异,但结构是通用的。
# Skill 名称:API 接口生成 ## 触发条件 - 用户要求生成新的 API 接口 - 涉及 RESTful 风格的 HTTP 接口 ## 前置检查 1. 确认接口的 HTTP 方法和路径 2. 确认请求参数和响应结构 3. 确认错误处理策略 ## 执行步骤 1. 定义请求参数类型,包含必填/选填标注 2. 定义响应结构,区分成功和失败两种情况 3. 编写接口处理逻辑,包含参数校验 4. 添加错误处理,覆盖参数错误、权限错误、服务错误 5. 生成接口文档注释 ## 约束规则 - 所有参数必须有类型定义 - 错误响应必须包含错误码和可读消息 - 不允许在响应中暴露数据库字段名 - 分页接口必须包含总数和页码信息 ## 输出格式 - 代码文件按项目现有结构放置 - 附带接口文档注释 - 如有新增依赖,单独列出这个模板的好处是结构清晰,AI 加载后能快速定位到关键信息。你可以根据具体任务调整章节,但建议保留"触发条件""执行步骤""约束规则"这三个核心部分。
3.4 写完怎么验证 skill 真的有效
Skill 写完不是就完了,必须验证。我的验证方法是用三个不同复杂度的任务去测试:一个简单任务看基本流程是否跑通,一个中等任务看约束规则是否生效,一个边界任务看异常处理是否到位。
比如测试 API 生成 skill 时,我先让它生成一个最简单的 GET 接口,看基本结构对不对。然后生成一个带分页和筛选的复杂接口,看它有没有漏掉分页参数。最后故意给一个矛盾的输入,比如"生成一个不需要参数的 POST 接口",看它会不会提出质疑而不是硬编。
验证过程中发现的问题,要回写到 skill 里。我一般会迭代三到五轮,才能让一个 skill 稳定下来。第一版往往会有各种遗漏,这很正常,不要指望一次写完美。
4. skills 和 Claude Code、Codex 结合时的实战细节
4.1 Claude Code 里 skills 的加载逻辑
Claude Code 对 skills 的支持,核心思路是按需加载。它不会一次性把所有 skill 都塞进上下文,而是根据当前任务判断该用哪个。这个机制的好处是节省上下文窗口,坏处是如果 skill 的触发条件写得不够明确,可能该加载的时候没加载。
我在实际使用中发现,Claude Code 判断是否加载某个 skill,主要看 skill 描述里的关键词和当前任务的匹配度。所以写 skill 描述时,要把可能触发的场景词都覆盖到。比如一个"代码审查"skill,描述里最好同时包含"review""检查""审查""代码质量"这些词,提高匹配概率。
另外要注意的是 skill 的优先级。如果你有多个 skill 可能匹配同一个任务,Claude Code 会按某种顺序选择。我一般会把最常用的 skill 放在前面,或者在描述里写清楚适用边界,避免误触发。
4.2 Codex 场景下 skills 的适配要点
Codex 和 Claude Code 在 skill 处理上有些差异。Codex 更偏向于把 skill 当作一种"配置"来对待,它期望 skill 的格式更结构化、更接近机器可读的规范。这意味着你在写 skill 时,要减少自然语言的模糊表述,多用明确的规则和条件。
我踩过的一个坑是,把为 Claude Code 写的 skill 直接搬到 Codex 上用,结果因为描述太"口语化",Codex 理解偏差很大。后来我调整了写法,把"尽量用简洁的命名"改成"命名长度不超过 20 个字符,使用小写字母和连字符",效果就好多了。
还有一个细节是 Codex 对 skill 的版本管理更敏感。如果你更新了 skill,最好在文件里标注版本号和变更说明,否则可能出现新旧行为不一致的情况。
4.3 本地模型接入时的注意事项
有些朋友会用本地模型来跑 skills,这时候要注意模型的上下文长度和指令遵循能力。本地模型通常比云端模型小,对长 skill 的处理能力有限。我的建议是,如果要用本地模型,把 skill 拆得更细一些,每个 skill 只做一件事,避免一个 skill 里塞太多步骤。
另外本地模型对格式的敏感度更高。你在 skill 里写的输出模板,最好用非常明确的标记,比如用特定的分隔符或者固定的标题层级,帮助模型理解结构。我试过用纯自然语言描述输出格式,本地模型经常跑偏,改成用代码块示例后就稳定多了。
5. 那些没人告诉你但一定会踩的坑
5.1 skill 冲突:当两个 skill 同时想接管任务
这是最常见的问题。你写了一个"通用代码审查"skill,又写了一个"Python 代码审查"skill,结果审查 Python 代码时,两个 skill 都觉得自己该上场,输出就乱了。
解决办法是明确优先级和适用范围。通用 skill 的描述里写"适用于所有语言,但特定语言有专用 skill 时优先使用专用 skill"。专用 skill 的描述里写清楚只适用于哪种语言。这样 AI 在匹配时就能做出正确选择。
如果冲突还是频繁发生,那就考虑合并。把通用 skill 和专用 skill 整合成一个,用条件分支来处理不同语言的情况。虽然文件会大一些,但至少不会打架。
5.2 上下文污染:skill 加载太多导致 AI "精神分裂"
有一次我同时加载了五六个 skill,结果 AI 的输出风格变得很奇怪,一会儿用这个规范,一会儿用那个规范。后来才明白,skill 之间如果有风格冲突,同时加载就会互相干扰。
我的经验是单次任务加载的 skill 不超过三个。如果确实需要多个 skill 配合,那就把它们组织成一个"复合 skill",在里面明确执行顺序和各自负责的部分。比如"前端页面开发"这个复合 skill,可以包含"组件生成""样式规范""接口调用"三个子部分,按顺序执行。
5.3 过度约束:把 AI 管得太死反而不好用
写 skill 的时候很容易陷入"什么都想管"的陷阱。我早期写的一个 skill,光约束规则就列了三十多条,结果 AI 执行时畏首畏尾,稍微遇到规则没覆盖的情况就卡住了。
后来我学会了抓大放小。只约束那些真正重要的、容易出错的地方,其他细节留给 AI 自己判断。比如代码审查 skill,我只强制要求"必须报告安全问题"和"必须标注严重程度",至于报告用什么措辞、按什么顺序排列,就不管了。这样 AI 反而发挥得更好。
5.4 版本失控:改了 skill 之后行为不一致
Skill 是会迭代的,但迭代之后如果没有版本管理,就会出现"昨天还好好的,今天怎么变了"的情况。特别是团队协作时,你改了 skill,别人不知道,用起来就会困惑。
我的做法是在 skill 文件头部维护一个变更记录,每次修改都记一笔:改了什么、为什么改、影响范围是什么。如果是团队共用,还要通知相关的人。另外重要 skill 的修改最好经过验证再合并,不要直接改主版本。
6. 从"能用"到"好用":skills 的进阶玩法
6.1 让 skill 自己进化:基于反馈的迭代机制
Skill 不是写完就固定的,好的 skill 会随着使用不断优化。我现在的做法是,每次用 skill 处理任务后,如果发现输出有问题,就立刻记录下问题点,攒够几个就统一更新 skill。
更进一步的做法是让 AI 自己提改进建议。在 skill 里加一条规则:"执行完成后,如果发现规则有模糊或不合理的地方,请指出。"这样 AI 在用的过程中会帮你发现 skill 的缺陷。我试过这个方法,确实能发现一些自己想不到的问题。
6.2 skill 组合:用多个小 skill 拼出复杂能力
单个 skill 的能力有限,但组合起来就很强。我的思路是把复杂任务拆成多个原子 skill,然后用一个调度 skill 来编排。比如"新功能开发"这个复杂任务,可以拆成"需求分析""接口设计""代码实现""测试编写"四个原子 skill,调度 skill 负责按顺序调用它们,并在中间传递上下文。
这种做法的好处是每个原子 skill 都很简单,容易维护和复用。缺点是调度逻辑需要额外设计,而且上下文传递容易出问题。我一般只在任务确实复杂、且会反复出现时才这么做。
6.3 团队协作:怎么让大家的 skill 保持一致
团队里每个人都可以写 skill,但如果不统一管理,很快就会乱套。我们的做法是建立一个共享的 skill 仓库,所有人写的 skill 都提交到这里,经过 review 后才能合并。Review 的重点是:触发条件是否明确、约束规则是否合理、输出格式是否统一。
另外我们还会定期清理不再使用的 skill。有些 skill 是特定项目用的,项目结束后就没用了,留在仓库里只会增加干扰。我一般每个季度过一遍,把三个月内没被调用过的 skill 归档。
7. 关于 skills 的几个常见误解
7.1 "skills 就是提示词模板"
这个误解最普遍。提示词模板是静态的文本替换,而 skill 是动态的能力封装。Skill 可以根据上下文决定是否加载、加载哪部分、按什么顺序执行。它比提示词模板灵活得多,也复杂得多。
7.2 "skill 写得越详细越好"
详细是好事,但过度详细会适得其反。前面说过,skill 太长会导致 AI 抓不住重点。而且太详细的 skill 维护成本很高,改一个地方可能牵动全身。我的建议是先写核心规则,遇到问题再补充,不要一开始就追求面面俱到。
7.3 "有了 skills 就不需要人管了"
Skill 是辅助工具,不是自动驾驶。它能把重复劳动标准化,但不能替代人的判断。特别是遇到 skill 没覆盖的情况,还是需要人来决策。我见过有人完全依赖 skill 输出,结果出了错都不知道,这是很危险的。
8. 我个人的一些使用心得
折腾 skills 这几个月,最大的体会是:skill 的质量取决于你对任务的理解深度。如果你自己都没想清楚这件事该怎么做,写出来的 skill 一定是模糊的。所以写 skill 之前,先花时间把任务拆解清楚,比急着动手写更重要。
另一个体会是不要追求一步到位。我第一个 skill 改了七八版才稳定下来,中间推翻重来过好几次。这很正常,skill 本身就是随着使用不断打磨的。刚开始写得粗糙没关系,用起来发现问题再改就是了。
还有就是保持 skill 的简洁。我现在写 skill 的原则是:能用三行说清楚就不用五行,能用一个规则解决就不写两个。简洁的 skill 更容易维护,也更容易被 AI 正确执行。
最后说一个实际的小技巧:如果你不确定某个规则该不该写进 skill,就先不写,观察几次。如果发现 AI 确实经常在这个地方出错,再补进去。这样能避免 skill 里塞太多不必要的约束。