1. 从零认识 Claude Skills:它到底解决了什么问题
第一次听到 Claude Skills 这个词,很多人会下意识地把它和 MCP 混为一谈。我刚开始接触的时候也是这个反应,毕竟那段时间 MCP 协议的热度实在太高,几乎所有的讨论都围绕着“怎么把外部工具接进模型”展开。但真正上手用了一段时间之后才发现,Skills 和 MCP 解决的是两个完全不同层面的问题,理解这一点,是决定你要不要投入时间折腾它的关键。
先说结论:MCP 解决的是“模型能碰到什么”的问题,Skills 解决的是“模型知道怎么做”的问题。打个比方,MCP 像是给你的助手配了一把万能钥匙,让它能打开各种房间的门;而 Skills 更像是一本操作手册,告诉它进了房间之后该按什么顺序、用什么手法去完成具体任务。两者不是替代关系,而是互补关系。你可以只用 MCP 不用 Skills,也可以只用 Skills 不接 MCP,但如果两个都用上,整个工作流的顺畅程度会有明显提升。
那 Claude Skills 具体是什么形态的东西?说白了,它就是一个结构化的文件夹,里面包含一个SKILL.md文件作为入口,再加上若干辅助脚本、参考资料、模板文件。模型在需要的时候会读取这个文件,按照里面定义的流程去执行任务。它不依赖任何特殊的运行时环境,不需要编译,不需要部署服务,本质上就是“把一套做事的方法写成模型能看懂的文档”。
这个设计思路其实非常朴素,但威力在于它把“领域知识”和“模型能力”解耦了。以前你想让模型按照公司内部的代码规范写代码,得在每次对话里把规范贴一遍,或者写一个很长的系统提示词。现在你只需要把规范整理成一个 Skill,模型在合适的时机自动加载,既省 token 又不容易遗漏。对于经常重复同类任务的人来说,这个效率提升是实打实的。
适合读这篇内容的人大概分三类:一是已经在用 Claude Code 做日常开发,想进一步提升自动化程度的;二是团队里需要统一工作流程、降低协作摩擦的技术负责人;三是对 Agent 架构感兴趣,想通过一个具体案例理解“技能系统”设计思路的开发者。不管你是哪一类,接下来的内容都会从实际操作的层面展开,尽量把每个环节讲透。
2. Skills 的核心机制与设计逻辑拆解
2.1 为什么是“文件夹 + Markdown”而不是插件系统
很多人第一次看到 Skills 的目录结构时会觉得过于简单,甚至有点“不正式”。一个文件夹,一个 Markdown 文件,几个可选的脚本,这就完了?没有注册机制,没有依赖声明,没有版本管理,看起来像是临时拼凑的方案。但恰恰是这种极简设计,让它的上手门槛降到了几乎为零。
我试过对比几种不同的扩展方案。传统的插件系统通常需要你遵循特定的接口规范,写一堆样板代码,还要处理生命周期钩子、依赖注入这些概念。对于专业开发者来说不算什么,但对于只想“让模型按我的方式做事”的人来说,这些额外负担完全是浪费精力。Skills 的做法是把复杂度转移到模型侧——模型本身足够聪明,能读懂自然语言描述的流程,那就不需要你用代码去定义每一步。
另一个关键考量是可移植性。一个 Skill 文件夹可以放在项目仓库里跟着代码走,也可以放在用户目录下作为个人工具箱,还可以打包分享给同事。它不绑定任何特定的 IDE 或平台,只要运行环境支持读取文件系统,就能用。这种“文件即配置”的思路,和当年 Docker 用 Dockerfile 定义环境、GitHub Actions 用 YAML 定义流水线是一个道理,降低认知负担的同时提高了传播效率。
当然,简单也有简单的代价。没有强制的 schema 校验意味着 Skill 的质量完全取决于写作者的水平,一个逻辑混乱的SKILL.md会让模型执行得一塌糊涂。没有版本管理意味着多人协作时容易出现覆盖冲突。这些问题在实际使用中确实会遇到,后面我会专门讲怎么规避。
2.2 SKILL.md 的加载时机与触发逻辑
理解 Skills 最关键的一点是搞清楚模型什么时候会去读这个文件。它不是每次对话都加载,也不是永远不加载,而是根据当前任务和 Skill 的描述信息做匹配。具体来说,模型首先看到的是所有可用 Skill 的名称和简短描述,当它判断当前任务和某个 Skill 相关时,才会去读取完整的SKILL.md内容。
这个机制带来的直接好处是上下文窗口的节省。假设你有二十个 Skill,每个完整内容平均两千字,如果全部加载就是四万字,直接吃掉一大块上下文。但实际运行时,模型可能只需要其中一两个,其余的只占用一行描述的空间。这种“按需加载”的设计,让 Skill 数量可以持续增长而不会导致性能线性下降。
那描述信息怎么写才能让模型准确匹配?我的经验是用任务导向的语言,而不是功能导向的语言。比如“当用户需要生成符合团队规范的 React 组件时使用”就比“React 组件生成器”要好,因为前者描述了触发场景,后者只是标签。模型在判断相关性时,更擅长匹配场景描述而不是抽象名词。
还有一个容易被忽略的细节:Skill 的优先级和冲突处理。如果你同时装了两个功能重叠的 Skill,模型可能会随机选一个,也可能两个都读然后混淆。目前没有官方的优先级机制,所以实际使用中要尽量避免功能重叠。如果确实需要多个相似 Skill,建议在描述里明确区分适用场景,比如一个用于“新项目初始化”,另一个用于“存量项目重构”。
2.3 与 MCP 协议的协作边界在哪里
MCP 和 Skills 经常被放在一起讨论,但它们的职责边界其实很清晰。MCP 负责连接外部资源——数据库、API、文件系统、第三方服务,它定义的是“模型能调用哪些工具”。Skills 负责编排工作流程——先做什么、后做什么、遇到分支怎么处理,它定义的是“模型该怎么组合这些工具”。
举个具体的例子。假设你要做一个“自动生成周报”的功能。MCP 层面,你需要接入日历服务获取本周会议记录,接入项目管理工具获取任务完成情况,接入文档系统用于写入结果。这些是 MCP 的活儿。而 Skills 层面,你需要定义:先拉取哪些数据,怎么过滤无关信息,按什么结构组织内容,遇到数据缺失时怎么处理,最终输出成什么格式。这些是 Skills 的活儿。
实际使用中,两者配合的方式通常是:Skill 的SKILL.md里写明“第一步调用 XX 工具获取数据,第二步调用 YY 工具处理”,模型读到这个流程后,通过 MCP 去实际执行工具调用。所以 Skill 更像是导演,MCP 像是演员和道具。没有导演,演员不知道该演什么;没有演员,导演的想法落不了地。
注意:不要试图用 Skill 去实现 MCP 该做的事。我见过有人在
SKILL.md里写一堆 HTTP 请求的细节,试图绕过 MCP 直接调 API。这样做短期能跑通,但长期维护成本极高,而且失去了 MCP 带来的统一鉴权、错误处理、重试机制等好处。
3. 手把手搭建你的第一个 Skill
3.1 目录结构规划与文件组织
动手写之前,先把目录结构想清楚。一个标准的 Skill 文件夹大概长这样:
my-skill/ ├── SKILL.md # 入口文件,必须存在 ├── scripts/ # 可执行脚本,可选 │ ├── process.py │ └── validate.sh ├── references/ # 参考资料,可选 │ ├── style-guide.md │ └── api-schema.json └── assets/ # 模板、静态资源,可选 └── template.docxSKILL.md是唯一必须存在的文件,其他都是按需添加。我建议一开始只建SKILL.md,等确实需要脚本或参考资料时再逐步补充。过早拆分目录会让结构复杂化,反而不利于维护。
关于存放位置,通常有两个选择:项目级和用户级。项目级放在项目根目录的.claude/skills/下,跟着代码仓库走,适合团队共享的规范类 Skill。用户级放在用户主目录的.claude/skills/下,只对当前用户生效,适合个人习惯类 Skill。如果同名 Skill 同时存在于两个位置,项目级通常优先,但具体行为建议实际测试确认。
3.2 SKILL.md 的编写模板与要点
SKILL.md的写法没有强制格式,但根据我的实践,以下结构效果最好:
--- name: react-component-generator description: 当需要创建符合团队规范的 React 函数组件时使用,包括组件文件、样式文件和测试文件 --- # React 组件生成规范 ## 触发条件 当用户要求创建新的 React 组件,或提到"生成组件""新建页面"等关键词时使用本技能。 ## 执行步骤 1. 确认组件名称,转换为 PascalCase 格式 2. 在 src/components/ 下创建组件目录 3. 生成 index.tsx,使用函数式组件 + TypeScript 4. 生成 styles.module.css,使用 CSS Modules 5. 生成 index.test.tsx,包含基础渲染测试 6. 更新 src/components/index.ts 导出新组件 ## 代码规范 - 组件必须使用 named export,不用 default export - Props 接口命名格式为 `XxxProps` - 样式类名使用 camelCase - 测试文件覆盖率要求达到 80% 以上 ## 注意事项 - 如果组件目录已存在,先询问用户是否覆盖 - 如果项目使用 JavaScript 而非 TypeScript,跳过类型定义部分 - 生成后运行一次 lint 检查,有错误则修复后再交付这个模板里有几个关键点值得展开说。frontmatter 里的 description 极其重要,它是模型判断是否加载这个 Skill 的唯一依据,必须写清楚“什么时候用”而不是“这是什么”。执行步骤要具体到可操作,不要写“生成合适的代码”这种模糊表述,要写清楚文件路径、命名规则、具体内容要求。注意事项要覆盖边界情况,比如文件已存在怎么办、环境不匹配怎么办,这些是实际运行中最容易出问题的地方。
3.3 参数传递与动态内容处理
Skill 执行过程中经常需要根据用户输入动态调整行为。比如用户说“创建一个叫 UserProfile 的组件”,Skill 需要提取出UserProfile这个名称并应用到各个步骤中。这个提取过程不需要特殊语法,模型会自然地从对话中理解并填充到流程里。
但如果需要更精确的控制,可以在SKILL.md里定义变量占位符:
## 输入参数 - `componentName`: 组件名称,PascalCase 格式 - `targetDir`: 目标目录,默认为 src/components/ - `withTest`: 是否生成测试文件,默认为 true模型读到这些定义后,会主动从用户输入中提取对应信息,缺失的则使用默认值。这种方式比让模型自由发挥要稳定得多,尤其是在团队协作场景下,能保证不同人使用同一个 Skill 得到一致的结果。
对于需要复杂计算的场景,可以配合scripts/下的脚本。比如一个处理数据的 Skill,可以在SKILL.md里写“运行python scripts/process.py --input {file}处理数据”,模型会调用相应命令并读取输出。脚本的好处是逻辑确定性强,不受模型理解偏差影响,适合对准确性要求高的环节。
4. 实战:用 Skills 重构一个真实工作流
4.1 场景选择与痛点分析
拿一个我实际改造过的场景来说:前端项目的新页面创建。在没上 Skills 之前,每次新建一个页面,我需要手动做这些事:创建页面目录、写页面组件、写路由配置、写菜单项、写权限配置、写基础测试。步骤多且容易遗漏,尤其是路由和权限这两块,经常写完页面忘了注册,调试半天才发现问题。
这个场景适合用 Skill 来规范化的原因有三个:步骤固定,每次新建页面都是同样的流程;容易出错,人工操作总有遗漏;频率高,一个中型项目开发期可能每周要建十几个页面。三个条件都满足,投入时间写 Skill 的回报就很明显。
我统计过改造前后的数据:改造前平均每个页面创建耗时约 8 分钟,其中约 2 分钟花在排查遗漏上;改造后平均耗时降到 2 分钟以内,且基本不会出现遗漏。按每周创建 10 个页面算,一周能省下一个多小时,一个月就是四五个小时。这还没算上因为遗漏导致的调试时间。
4.2 Skill 内容设计与步骤拆解
这个 Skill 的SKILL.md核心部分大概是这样组织的:
--- name: create-page description: 当需要在前端项目中创建新页面时使用,自动完成页面组件、路由、菜单、权限和测试文件的创建 --- # 前端页面创建流程 ## 前置检查 1. 确认当前目录是项目根目录(存在 package.json) 2. 读取 src/router/routes.ts 了解路由配置格式 3. 读取 src/config/menu.ts 了解菜单配置格式 4. 确认用户提供的页面名称和路径 ## 创建步骤 ### 第一步:创建页面组件 - 路径:src/pages/{PageName}/index.tsx - 使用函数式组件,包含基础布局结构 - 导出方式:named export ### 第二步:注册路由 - 在 src/router/routes.ts 中添加路由项 - path 使用 kebab-case 格式 - 懒加载方式引入组件 ### 第三步:添加菜单项 - 在 src/config/menu.ts 中添加对应菜单 - 菜单标题从页面名称转换而来 - 图标使用默认值,后续手动调整 ### 第四步:配置权限 - 在 src/config/permissions.ts 中注册页面权限码 - 权限码格式:{module}:{page}:view ### 第五步:生成测试文件 - 路径:src/pages/{PageName}/index.test.tsx - 包含基础渲染测试和路由匹配测试 ## 验证步骤 1. 运行 npm run lint 检查代码规范 2. 运行 npm run test 确认测试通过 3. 运行 npm run build 确认无编译错误 4. 如有错误,修复后重新验证 ## 注意事项 - 如果页面名称已存在,终止流程并提示用户 - 如果路由文件格式与预期不符,先询问用户再操作 - 所有文件创建完成后,输出变更文件列表供用户确认这个设计里有几个我踩过坑之后总结的要点。前置检查不能省,早期版本没有这一步,结果在非项目目录下执行导致创建了一堆垃圾文件。验证步骤要写进流程,让模型自己跑 lint 和 test,有问题当场修复,而不是等用户发现。注意事项要覆盖冲突场景,同名页面、格式不匹配这些情况在实际使用中经常遇到,提前定义好处理方式能避免很多混乱。
4.3 效果验证与迭代优化
第一版 Skill 上线后,我用了两周时间收集问题。实际运行中暴露出来的问题主要有三类:
第一类是路径判断错误。有些项目页面放在src/pages/下,有些放在src/views/下,Skill 硬编码了路径导致后者失败。修复方式是在前置检查里增加路径探测逻辑,读取项目配置文件判断实际使用的目录结构。
第二类是格式假设过强。不同项目的路由配置格式差异很大,有的用数组,有的用对象,有的用装饰器。Skill 最初假设了一种格式,遇到其他格式就生成错误的代码。修复方式是把“读取现有配置并模仿其格式”作为明确步骤写进流程,而不是预设格式。
第三类是验证环节被跳过。模型有时候会“偷懒”,觉得代码写完了就结束了,不去跑验证命令。修复方式是在SKILL.md里把验证步骤标记为“必须执行”,并说明“未经验证的输出视为未完成”。
经过三轮迭代,这个 Skill 的首次成功率从最初的六成左右提升到了九成以上。剩下的失败案例基本都是项目结构过于特殊导致的,这种就属于正常范围,手动处理即可。
5. 常见问题排查与避坑指南
5.1 Skill 不生效的排查思路
Skill 写了但模型不加载,这是最常见的问题。排查顺序建议如下:
| 排查项 | 检查方法 | 常见原因 |
|---|---|---|
| 文件位置 | 确认 SKILL.md 在正确的 skills 目录下 | 放错目录,如放到了项目根目录而非 .claude/skills/ |
| 文件命名 | 确认文件名严格为 SKILL.md | 大小写错误,如 skill.md、Skill.md |
| frontmatter 格式 | 确认开头是 --- 包裹的 YAML | 缺少分隔符或格式错误导致解析失败 |
| description 质量 | 检查是否描述了触发场景 | 只写了功能名称,模型无法判断何时使用 |
| 权限问题 | 确认运行环境有读取权限 | 文件权限设置过严 |
我遇到最多的情况是 description 写得太抽象。比如写“代码审查工具”,模型不知道什么时候该用;改成“当用户提交代码需要审查或提到代码检查时使用”,命中率立刻上去了。这个细节看起来小,但实际影响很大。
5.2 执行结果不稳定的应对策略
同一个 Skill 有时候执行得好,有时候执行得差,这种波动性主要来自三个源头。
流程描述有歧义。比如写“生成合适的样式”,什么叫合适?模型每次理解可能不同。改成“生成 CSS Modules 文件,类名使用 camelCase,包含容器和内容两个基础类”,确定性就强很多。步骤顺序不明确。如果步骤之间有依赖关系但没写清楚,模型可能乱序执行。建议用有序列表并标注依赖,比如“在完成第二步之后再执行第三步”。缺少异常处理。正常路径写得很清楚,但遇到文件已存在、目录不存在这些情况没有定义行为,模型就会自由发挥。把常见异常的处理方式写进注意事项,能显著降低波动。
5.3 多 Skill 协作时的冲突处理
当项目里 Skill 数量增多,冲突就不可避免。我遇到过两个 Skill 都试图修改同一个配置文件,结果互相覆盖。也遇到过两个 Skill 的触发条件重叠,模型随机选一个导致行为不一致。
处理这类问题的原则是职责单一、边界清晰。每个 Skill 只负责一件事,修改配置文件的 Skill 和生成代码的 Skill 分开。如果确实需要协作,在SKILL.md里明确写出“本 Skill 完成后,建议调用 XX Skill 进行后续处理”,让模型知道衔接关系。
对于触发条件重叠的情况,可以在 description 里加入排除条件。比如“当需要创建新页面时使用,不适用于修改现有页面”,这样模型在修改场景下就不会误加载。
提示:定期审查项目里的 Skill 列表,合并功能重叠的,删除不再使用的。我一般每个月清理一次,保持活跃 Skill 在十个以内,太多会导致模型选择困难。
5.4 团队共享时的版本管理
Skill 跟着项目仓库走的时候,版本管理就很重要。我的做法是在SKILL.md的 frontmatter 里加一个 version 字段,每次修改都递增。同时在项目文档里维护一个变更记录,说明每个版本改了什么、为什么改。
多人同时修改同一个 Skill 时,建议走代码审查流程,和改代码一样对待。我见过因为两个人同时改SKILL.md导致流程逻辑冲突,最后生成的文件一半新一半旧,排查了半天才发现是合并问题。把 Skill 当代码管理,能避免很多这类低级问题。
6. 进阶玩法:让 Skills 真正融入日常开发
6.1 从个人工具到团队规范
一个人用 Skill 和一群人用 Skill,考虑的问题完全不同。个人用的时候怎么方便怎么来,团队用的时候必须考虑一致性和可维护性。我推动团队使用 Skills 的过程中,总结了几个关键动作。
建立 Skill 评审机制。新 Skill 提交后,由两到三个人实际跑一遍,确认流程合理、边界清晰、结果稳定,才能合并到主分支。统一命名规范。所有 Skill 名称使用 kebab-case,description 统一以“当...时使用”开头,方便模型匹配也方便人查找。定期同步会。每两周花半小时过一遍最近新增和修改的 Skill,讨论遇到的问题和改进方向。
这些机制看起来有点重,但实际运行下来,团队整体的开发效率提升明显。尤其是新人入职时,以前需要口口相传的规范现在都固化在 Skill 里,上手速度快了很多。
6.2 结合 MCP 打造完整自动化链路
单独用 Skills 已经能解决不少问题,但结合 MCP 之后能做的事情更多。举个例子,一个“代码审查”Skill 可以这样设计:通过 MCP 接入代码仓库获取变更内容,按照 Skill 里定义的审查规则逐项检查,再通过 MCP 把审查结果写入 PR 评论。整个过程从拉取代码到输出结果全自动,人只需要最后确认。
这种组合的关键在于明确哪些环节用 MCP、哪些用 Skill。我的划分原则是:需要和外部系统交互的用 MCP,需要做判断和编排的用 Skill。比如“获取 PR 变更”是 MCP 的活儿,“判断变更是否符合规范”是 Skill 的活儿,“写入评论”又是 MCP 的活儿。按这个原则拆分,两边各司其职,维护起来也清晰。
6.3 持续迭代:从能用 to 好用
Skill 写完只是开始,真正让它变得好用需要持续迭代。我的习惯是每次使用后花一分钟记录:这次哪里卡住了、哪里结果不对、哪里可以更快。攒够三五个问题就更新一版SKILL.md。
迭代的方向通常有三个:减少人工确认环节,把更多判断逻辑写进流程,让模型自己决策;增加异常覆盖,把实际遇到的新情况补充到注意事项里;优化输出格式,让结果更符合下游使用需求。经过几个月迭代,一个 Skill 会越来越贴合实际工作,最终变成离不开的工具。
我个人的体会是,Skills 的价值不在于技术有多复杂,而在于它把“隐性知识显性化”这件事变得极其简单。以前那些只存在于老员工脑子里的操作流程,现在花半小时就能整理成一个 Skill,然后被所有人使用。这种知识沉淀的效率,是它最吸引我的地方。