1. 从“skills”这个热词说起:它到底在解决什么问题
最近半年,不管是在技术社区还是开发者群聊里,“skills”这个词出现的频率高得离谱。你随便翻一下热搜词列表,能看到claude code、codex、agents、plugin、agent skills测试、codex skills、claude agent skills: a first principles deep dive这些词反复出现。很多人第一反应是:这不就是个“技能”吗,有什么好聊的?但真正上手用过 Claude Code 或者 Codex 的人会明白,这里的 skills 不是抽象概念,而是一套实实在在的、可复用、可组合的能力封装机制。
我先把话说直白一点:skills 本质上就是给 AI 编程助手(agent)准备的“技能包”。你可以把它理解成手机里的 App——手机本身能打电话、能上网,但真正让它变得好用、能解决具体问题的,是你装的那些 App。Claude Code、Codex 这些工具本身提供了基础的对话、代码生成、文件读写能力,而 skills 就是让它们学会“做某件具体事情”的插件式扩展。
那它解决了什么问题?核心就三个:
第一,重复劳动的问题。你每次让 AI 帮你写一个 React 组件,都要重新解释项目规范、目录结构、命名习惯,烦不烦?skills 可以把这些规则固化下来,一次配置,次次生效。
第二,能力边界的问题。原生 agent 只会通用操作,但你要它去调用某个内部 API、执行某个特定构建流程、按照团队规范生成测试用例,它不会。skills 就是给它补课。
第三,一致性的问题。团队里五个人用 AI 写代码,五个人得到五种风格。skills 让所有人的 AI 助手遵循同一套标准,输出结果可预期。
适合谁来研究这个?我的判断是:凡是日常用 Claude Code、Codex、Cursor 这类 AI 编程工具写代码的人,都应该花时间搞懂 skills。尤其是团队里的技术负责人、工具链维护者,以及那些想让 AI 真正融入自己工作流而不是当玩具玩的人。小白也能看懂,因为我会从最基础的概念讲起,但我会假设你至少用过一次 Claude Code 或者 Codex,知道它们大概是怎么回事。
接下来我会从设计思路、核心机制、实操配置、常见坑四个维度,把 skills 这件事彻底讲透。内容基于我自己的使用经验和社区里大量实践者的反馈整理,不是官方文档的复述,而是“一个天天用的人会怎么想、怎么做”。
2. skills 的整体设计与核心思路拆解
2.1 为什么是“技能”而不是“配置”或“插件”
很多人第一次接触 skills 会问:这跟配置文件有什么区别?跟 plugin 有什么区别?我一开始也这么想,后来用多了才理解设计者的意图。
配置(config)是静态的,比如你设置一个settings.json,告诉工具用哪个模型、超时时间多少。它不包含“怎么做一件事”的逻辑。插件(plugin)是功能性的,比如给编辑器装一个 Git 插件,它增加的是工具本身的能力。而skills 介于两者之间:它既不是纯配置,也不是纯功能,而是“面向任务的能力封装”。
打个比方:配置是你告诉厨师“少放盐”,插件是你给厨房添了一台烤箱,而 skills 是你给厨师一本菜谱,上面写着“做红烧肉要先焯水、再炒糖色、最后小火炖四十分钟”。厨师本身会做饭,但有了这本菜谱,他就能稳定地做出你想要的这道菜。
这个设计思路的好处是:skills 是可组合的。你可以有一个“写 React 组件”的 skill,一个“写单元测试”的 skill,一个“提交代码前检查”的 skill,它们可以串联起来,形成一个完整的工作流。而配置和插件很难做到这种任务级别的编排。
2.2 skills 的核心构成:描述、触发、执行
拆开来看,一个 skill 通常包含三个关键部分:
- 描述(description):告诉 agent 这个 skill 是干什么的、什么时候该用它。这部分极其重要,因为 agent 是根据描述来决定是否调用某个 skill 的。描述写得模糊,agent 就不知道该不该用。
- 触发条件(trigger):什么情况下激活这个 skill。可以是用户显式调用,也可以是 agent 根据上下文自动判断。比如你输入“帮我写个登录页面”,agent 会自动匹配到“前端组件生成”这个 skill。
- 执行逻辑(execution):具体怎么做。这部分可以是一段提示词(prompt),也可以是一组操作步骤,甚至可以调用外部脚本或工具。
我实测下来,描述和触发条件的质量,直接决定了一个 skill 好不好用。很多人写 skill 只关注执行逻辑,结果 agent 根本不知道什么时候该用它,等于白写。
2.3 与 Claude Code、Codex 的集成方式
Claude Code 和 Codex 对 skills 的支持方式略有不同,但核心逻辑一致:它们都提供了一个 skill 注册机制,让你把自定义能力挂载到 agent 上。
在 Claude Code 里,skills 通常放在特定目录下,每个 skill 一个文件夹,里面包含描述文件和执行逻辑。Claude Code 启动时会扫描这些目录,把可用的 skills 加载进来。当你发出指令时,agent 会根据 skill 的描述判断是否调用。
Codex 这边,skills 的概念更偏向于“可复用的提示模板 + 工具调用”。你可以把一组常用的操作封装成一个 skill,然后在对话中通过特定语法触发。Codex 的 skills 更强调与代码仓库的交互,比如“按照项目规范生成 commit message”这种。
两者共同的思路是:把重复的、有固定套路的任务,从“每次重新描述”变成“一次定义、反复调用”。这就是 skills 最大的价值。
2.4 为什么现在 skills 这么火
我觉得有几个原因叠加在一起:
一是AI 编程工具本身成熟了。一年前大家还在纠结“AI 写的代码能不能用”,现在更多人关心“怎么让 AI 写得符合我的要求”。skills 正好解决后者。
二是agent 概念普及了。大家开始理解,AI 不只是聊天机器人,而是可以执行多步任务的代理。既然是代理,就需要“技能”来扩展能力边界。
三是社区生态起来了。热搜词里能看到claude 国内安装skills 官方市场、codex好用的skills、skills推荐这些,说明已经有人在分享、在推荐、在讨论哪些 skills 好用。有生态就有动力。
四是企业级需求驱动。团队用 AI 写代码,最怕风格不统一、质量不可控。skills 提供了一种标准化的手段,让 AI 的输出可预期、可审计。
3. 核心细节解析与实操要点
3.1 skill 的描述怎么写才有效
这是我最想强调的一点。描述不是写给人看的,是写给 agent 看的。所以它的写法跟普通文档完全不同。
一个有效的描述应该包含:
- 任务类型:这个 skill 处理什么类型的任务。比如“生成 React 函数组件”。
- 触发场景:什么情况下应该用。比如“当用户要求创建新的 UI 组件时”。
- 输入要求:需要用户提供什么信息。比如“组件名称、props 定义、样式要求”。
- 输出格式:产出什么。比如“一个 .tsx 文件,包含类型定义和样式”。
我见过太多人把描述写成“这是一个很好用的 skill”,这种描述 agent 看了等于没看。描述要具体、可判断、有边界。
提示:描述里避免用“可能”“也许”“根据需要”这类模糊词。agent 需要明确的判断依据,模糊描述会导致误触发或漏触发。
3.2 触发机制的设计技巧
触发机制分两种:显式触发和隐式触发。
显式触发就是用户明确说“用某某 skill”。这种方式简单直接,但需要用户记住 skill 的名字,体验不够顺滑。
隐式触发是 agent 根据上下文自动判断。这种方式体验好,但对描述质量要求极高。我的经验是:先用显式触发跑通流程,再逐步优化描述,让隐式触发也能准确工作。
一个实用技巧是:在描述里加入“反例”。比如“这个 skill 用于生成 React 组件,不用于生成 Vue 组件”。这样 agent 在遇到 Vue 相关请求时就不会误触发。
另一个技巧是:给 skill 起一个语义明确的名字。react-component-gen比component-helper好,因为前者一看就知道干什么,后者太泛。
3.3 执行逻辑的三种写法
执行逻辑可以很简单,也可以很复杂。我把它分成三种:
第一种:纯提示词。就是一段自然语言指令,告诉 agent 怎么做。适合逻辑简单、不需要外部工具的场景。比如“生成一个符合 Airbnb 规范的 ESLint 配置”。
第二种:提示词 + 模板。在提示词基础上,提供输出模板。比如“按照以下模板生成组件文件:先 import,再类型定义,再组件函数,最后 export”。这种方式能保证输出结构一致。
第三种:提示词 + 脚本调用。最复杂但最强大。skill 可以调用外部脚本,比如运行一个代码生成器、调用一个 API、执行一个构建命令。这种方式适合需要与外部系统交互的场景。
我的建议是:从第一种开始,够用就不升级。很多人一上来就想搞最复杂的,结果维护成本高得吓人。skills 的核心价值是“稳定复用”,不是“功能炫酷”。
3.4 目录结构与文件组织
一个典型的 skill 目录结构是这样的:
skills/ react-component/ skill.md # 描述和触发条件 prompt.md # 执行逻辑 templates/ component.tsx # 输出模板 unit-test/ skill.md prompt.mdskill.md放描述和触发条件,prompt.md放具体执行逻辑,templates/放模板文件。这种分离的好处是:修改描述不影响执行逻辑,修改执行逻辑不影响描述。
有些实现会把所有内容放在一个文件里,用 frontmatter 区分。两种方式都行,关键是保持一致性。团队里用哪种,就统一用哪种,别混着来。
3.5 参数化与动态输入
好的 skill 不是死板的,而是能接受参数的。比如“生成组件”这个 skill,应该能接受组件名称、props 列表、样式方案等参数。
参数化的实现方式通常是在提示词里用占位符,比如{{componentName}}、{{props}}。agent 在调用时会把实际值填进去。
这里有个坑:参数太多会导致 agent 不知道该填什么。我的经验是,一个 skill 的参数控制在 3 到 5 个以内。超过这个数,就应该拆成多个 skill,或者让 skill 自己去推断。
注意:参数命名要清晰。
name不如componentName,style不如styleSolution。agent 对命名的敏感度比你想象的高。
4. 实操过程与核心环节实现
4.1 环境准备:Claude Code 与 Codex 的 skills 目录
先说 Claude Code。安装完成后,skills 通常放在用户目录下的.claude/skills/或者项目目录下的.claude/skills/。前者是全局 skill,所有项目都能用;后者是项目级 skill,只对当前项目生效。
我建议:通用型 skill 放全局,项目特定 skill 放项目目录。比如“生成 commit message”这种通用 skill 放全局,“生成这个项目的 API 客户端”放项目目录。
Codex 这边,skills 的存放位置取决于你用的是哪个版本。较新的版本支持在项目根目录下创建.codex/skills/目录。具体路径建议查一下你所用版本的文档,因为这块变化比较快。
配置完成后,重启工具,让它重新扫描 skills 目录。有些版本支持热加载,有些不支持。不确定的时候,重启是最稳妥的。
4.2 从零写一个 skill:以“生成 React 组件”为例
我来完整走一遍流程。
第一步:创建目录
mkdir -p .claude/skills/react-component/templates第二步:写描述文件skill.md
--- name: react-component description: 生成符合项目规范的 React 函数组件。当用户要求创建新的 UI 组件、页面片段或可复用 React 组件时使用。不适用于 Vue、Angular 或其他框架。 trigger: - 用户要求创建 React 组件 - 用户要求生成 UI 组件 - 用户提到 .tsx 文件创建 ---这里我特意加了“不适用于 Vue、Angular”,就是为了防止误触发。
第三步:写执行逻辑prompt.md
请按照以下规范生成 React 函数组件: 1. 使用 TypeScript,文件扩展名为 .tsx 2. 组件名使用 PascalCase 3. Props 使用 interface 定义,命名为 {{componentName}}Props 4. 样式使用 CSS Modules,文件名与组件同名 5. 导出使用 named export,不使用 default export 6. 组件内部先写类型定义,再写组件函数 组件名称:{{componentName}} Props 列表:{{props}} 样式要求:{{styleRequirement}}第四步:添加模板templates/component.tsx
import styles from './{{componentName}}.module.css'; export interface {{componentName}}Props { {{props}} } export function {{componentName}}({}: {{componentName}}Props) { return ( <div className={styles.container}> {/* 组件内容 */} </div> ); }第五步:测试
在 Claude Code 里输入:“帮我创建一个 UserCard 组件,接收 name 和 avatar 两个 props”。观察 agent 是否自动调用了这个 skill,输出是否符合规范。
我实测下来,第一次通常不会完美。可能需要调整描述、补充触发词、修改模板。迭代两三次是正常的。
4.3 参数传递与模板渲染的细节
参数传递这块有几个细节值得说。
占位符格式要统一。有的实现用{{param}},有的用${param},有的用[param]。选定一种,全项目统一。混用会导致渲染失败。
默认值处理。不是所有参数都必须传。可以在提示词里写“如果未提供样式要求,默认使用 CSS Modules”。这样 agent 就知道怎么处理缺失参数。
参数校验。如果某个参数是必须的,在描述里写清楚“必须提供组件名称”。agent 在缺少参数时会主动询问用户,而不是瞎猜。
模板渲染的边界情况。如果参数值包含特殊字符,比如<、>、&,可能会破坏模板结构。我的做法是:在提示词里提醒 agent 对特殊字符做转义,或者在模板里用安全的方式插入。
4.4 多 skill 组合与工作流编排
单个 skill 好用,但真正强大的是组合。
举个例子:我有三个 skill——react-component(生成组件)、unit-test(生成测试)、lint-check(检查代码规范)。我可以让 agent 按顺序执行:先生成组件,再生成测试,最后跑 lint 检查。
组合的方式有两种:
一种是链式调用。用户说“创建一个 UserCard 组件并生成测试”,agent 先调用react-component,再调用unit-test。
另一种是嵌套调用。unit-testskill 内部可以引用react-component的输出作为输入。
我建议:先从链式调用开始,因为逻辑清晰、容易调试。嵌套调用虽然灵活,但出问题时很难定位是哪个环节的锅。
提示:组合 skill 时,注意输出格式的兼容性。前一个 skill 的输出,要能被后一个 skill 正确解析。最好在描述里明确输入输出格式。
4.5 在 Codex 中配置 skills 的实操记录
Codex 的 skills 配置跟 Claude Code 略有不同。我以较新版本为例。
首先,在项目根目录创建.codex/skills/目录。然后每个 skill 一个子目录,里面放config.json和prompt.md。
config.json大概长这样:
{ "name": "api-client-gen", "description": "根据 OpenAPI 规范生成 TypeScript API 客户端", "triggers": ["生成 API 客户端", "根据接口文档生成代码"], "parameters": ["specPath", "outputDir"] }prompt.md里写具体逻辑,可以引用参数。
配置完成后,在 Codex 对话里输入“根据 docs/openapi.yaml 生成 API 客户端到 src/api/”,agent 应该能识别并调用。
我踩过的坑是:Codex 对触发词的匹配比较严格。如果用户说的词跟triggers里的不完全一致,可能不会触发。解决办法是多写几个同义词,比如“生成 API 客户端”“创建 API 客户端”“根据接口文档生成代码”都写上。
5. 常见问题与排查技巧实录
5.1 skill 不触发怎么办
这是最高频的问题。排查思路如下:
| 可能原因 | 排查方法 | 解决方案 |
|---|---|---|
| 描述不清晰 | 检查description是否具体 | 补充任务类型和触发场景 |
| 触发词不匹配 | 对比用户输入和triggers | 增加同义词和变体 |
| 目录位置错误 | 确认 skills 目录路径 | 放到正确的全局或项目目录 |
| 未重启工具 | 检查是否重新加载 | 重启 Claude Code 或 Codex |
| 优先级冲突 | 是否有其他 skill 抢先匹配 | 调整描述,增加区分度 |
我的经验是:八成问题出在描述上。描述写得太泛,agent 不知道什么时候该用;写得太窄,又匹配不到。多写几个具体场景,比写一堆抽象词有用。
5.2 skill 触发了但输出不对
这种情况通常是执行逻辑的问题。排查方向:
- 提示词是否明确:有没有说清楚步骤、格式、约束。
- 模板是否正确:占位符有没有写错,模板文件是否被正确加载。
- 参数是否传对:agent 填进去的值是否符合预期。
- 上下文是否干扰:对话历史里有没有冲突信息。
我遇到过一次,skill 生成的组件总是缺少类型定义。查了半天发现是提示词里写了“生成组件”,但没写“包含类型定义”。agent 就按最简方式生成了。提示词要写到“傻瓜都能执行”的程度,别假设 agent 会自己补全。
5.3 多个 skill 冲突怎么处理
当两个 skill 的描述有重叠时,agent 可能随机选一个,或者选错。
解决办法:
第一,明确边界。在描述里写清楚“这个 skill 用于 X,不用于 Y”。
第二,设置优先级。有些实现支持在配置里指定优先级,数字大的优先。
第三,合并 skill。如果两个 skill 经常一起用,考虑合并成一个,减少冲突。
第四,用显式触发。在关键场景下,让用户明确指定用哪个 skill,避免歧义。
5.4 性能问题:skill 太多会不会变慢
会。每个 skill 都需要 agent 在决策时进行评估。skill 数量多了,决策时间会变长,误触发概率也会增加。
我的建议是:全局 skill 控制在 10 个以内,项目级 skill 控制在 5 个以内。超过这个数,就要考虑合并或归档。
另外,定期清理不用的 skill。我每两周会 review 一次 skills 目录,把一个月没用过的删掉或移到归档目录。保持精简,比堆数量重要。
5.5 团队协作中的 skill 管理
团队用 skills,最大的问题是版本不一致。张三改了 skill,李四不知道,结果两人用 AI 生成的代码风格不一样。
我的做法是:把 skills 目录纳入版本控制。跟代码一样,skill 的修改也要走 PR、要 review。这样谁改了什么、为什么改,都有记录。
另外,给 skill 写变更日志。在skill.md里加一个changelog段落,记录每次修改的内容和原因。这样新人接手时能快速了解来龙去脉。
注意:不要把个人偏好的 skill 放进团队共享目录。团队 skill 应该是“大家都认可的标准”,而不是“某个人觉得好用”。
5.6 常见错误速查表
| 错误现象 | 可能原因 | 快速修复 |
|---|---|---|
| skill 完全不触发 | 目录路径错误 | 检查.claude/skills/或.codex/skills/ |
| 触发但输出为空 | 模板文件缺失 | 确认templates/下有对应文件 |
| 参数未替换 | 占位符格式不匹配 | 统一使用{{param}}格式 |
| 输出格式混乱 | 提示词缺少格式约束 | 在提示词里明确输出结构 |
| 多个 skill 抢触发 | 描述边界模糊 | 增加“不适用于”说明 |
| 修改后不生效 | 未重启工具 | 重启 Claude Code 或 Codex |
| 团队风格不一致 | skill 未纳入版本控制 | 把 skills 目录加入 Git |
6. 进阶玩法:让 skills 真正融入日常工作流
6.1 把 skills 和 Git hooks 结合
我试过一个挺有意思的玩法:把 skill 跟 Git hooks 结合。比如在pre-commit里调用一个 skill,让它检查即将提交的代码是否符合规范。
具体做法是:写一个 skill 叫pre-commit-check,描述是“检查代码是否符合项目规范”。然后在.git/hooks/pre-commit里调用 Claude Code 或 Codex 的命令行接口,传入变更文件列表,让 agent 执行这个 skill。
这样每次提交前,AI 都会自动检查一遍。发现问题就阻止提交,并给出修改建议。实测下来,能拦住不少低级错误。
6.2 用 skills 做代码审查
代码审查是 skills 的绝佳应用场景。你可以写一个code-reviewskill,描述是“对指定文件进行代码审查,检查命名规范、潜在 bug、性能问题”。
然后在 PR 流程里,让 agent 自动对变更文件跑这个 skill,把审查结果作为评论贴到 PR 上。这样人工审查者只需要关注业务逻辑,不用再纠结格式问题。
我自己的项目里,这个 skill 帮我省了不少时间。尤其是那些“忘了处理边界情况”“变量命名不一致”的问题,AI 比人眼更敏感。
6.3 skills 的版本管理与团队共享
前面提过要把 skills 纳入版本控制,这里展开说一下具体怎么做。
目录结构建议:
project/ .claude/ skills/ shared/ # 团队共享 skill react-component/ unit-test/ local/ # 个人 skill,不提交 my-experiment/.gitignore里排除local/目录,只提交shared/。这样个人实验不影响团队,团队标准又能统一。
版本管理策略:
- 主分支上的 skills 是稳定版,所有人可用。
- 新 skill 先在 feature 分支开发,测试通过后合并。
- 重大修改要写迁移说明,通知团队成员。
共享方式:
除了 Git,还可以把 skills 打包成 npm 包或内部工具包,通过包管理器分发。这种方式适合跨项目复用。不过要注意版本兼容性,不同项目的 Claude Code 版本可能不同。
6.4 从社区获取现成 skills 的注意事项
热搜词里有claude 国内安装skills 官方市场、codex好用的skills、skills推荐,说明社区里已经有不少现成 skill 可以拿来用。
我的建议是:可以用,但要审查。拿到一个别人的 skill,先看它的描述是否清晰、执行逻辑是否合理、有没有安全隐患。尤其是那些会调用外部脚本或 API 的 skill,一定要确认它做了什么。
另外,不要直接复制到团队目录。先放到个人目录测试,确认好用再推荐给团队。每个人的工作流不同,别人觉得好用的,你不一定适用。
6.5 skills 的未来扩展方向
从目前的发展趋势看,skills 这块还在快速演进。我观察到几个方向:
一是标准化。不同工具的 skill 格式可能会趋同,形成事实标准。这样写一次 skill,多个工具都能用。
二是市场化和分发机制。类似 App Store 的 skill 市场可能会出现,让 skill 的分享和获取更便捷。
三是与 CI/CD 深度集成。skills 不只是开发时的辅助,还可能进入构建、测试、部署流程,成为自动化的一部分。
四是智能化触发。未来的 agent 可能不需要显式触发词,而是根据上下文更精准地判断该用哪个 skill。
这些方向不一定都会实现,但值得关注。对于日常使用者来说,先把基础用法跑通,再逐步跟进新特性,是比较稳妥的策略。
7. 我个人的一些实操体会
写了这么多,最后分享几点我自己的体会,不是教程,就是踩坑之后的真实感受。
第一,skill 的质量比数量重要得多。我一开始兴致勃勃写了二十多个 skill,结果常用的就三四个。剩下的要么描述不清不触发,要么触发后输出不对,反而添乱。后来我砍到八个,每个都反复打磨,效率反而高了。
第二,描述值得花时间打磨。我写第一个 skill 时,描述只写了一句“生成 React 组件”,结果 agent 经常在该用的时候不用,不该用的时候乱用。后来我把描述改成“当用户要求创建新的 UI 组件、页面片段或可复用 React 组件时使用,不适用于 Vue、Angular”,触发准确率立刻上来了。描述是 skill 的灵魂,别在这上面偷懒。
第三,从简单开始,别一上来就搞复杂。我见过有人第一个 skill 就想调用外部 API、跑构建脚本、生成完整模块。结果调试了一周还没跑通,直接放弃了。我的建议是:第一个 skill 就写“生成一个符合规范的配置文件”这种最简单的,跑通流程、建立信心,再逐步加复杂度。
第四,团队共享要谨慎。个人觉得好用的 skill,别人不一定觉得好用。我推过一个“自动生成 commit message”的 skill 给团队,结果有人觉得生成的 message 太啰嗦,有人觉得太简略。后来改成可配置的,才勉强达成一致。团队 skill 要留出配置空间,别把个人偏好写死。
第五,定期清理。skill 跟代码一样,会腐化。项目变了、规范变了、工具版本变了,skill 可能就失效了。我每两周会花十分钟 review 一遍,把不用的删掉,把过时的更新。这个习惯帮我避免了很多“为什么 AI 输出不对”的困惑。
第六,别指望 skill 解决所有问题。skills 是工具,不是银弹。有些任务就是需要人工判断,有些场景就是不适合自动化。知道什么时候不用 skill,比知道怎么用 skill 更重要。
最后再分享一个小技巧:如果你不确定一个 skill 该怎么写,先手动做一遍任务,把步骤记下来,再把步骤翻译成提示词。这个方法我用了很多次,比凭空想要靠谱得多。手动做的时候你会自然发现哪些步骤是关键、哪些容易出错、哪些需要参数化。把这些观察写进 skill,质量不会差。