Skill:把重复流程变成一条命令
每次发版都要粘贴同一段检查清单?这一课讲清 SKILL.md 的结构、存放位置、前置信息字段和按需加载原理,分清 Skill、CLAUDE.md 与斜杠命令各管什么,并手把手写一个生成中文发版说明的 Skill。
学完这一课,你能
- 能说出 SKILL.md 的结构,以及个人级、项目级 Skill 放在哪里
- 能解释 Skill 按需加载的原理,并用前置信息控制谁能调用它
- 能判断一条内容该放进 CLAUDE.md、路径规则、Skill 还是 hook
- 能独立写出一个带参数和动态上下文的 Skill 并调试触发
小周每次发版前都要在 Claude Code 里粘贴同一段话:「看一下上个 tag 以来的提交,按新功能、修复分类,用中文写成面向用户的更新说明,追加到 CHANGELOG.md 顶部,别把 CI 配置的改动写进去……」这段话已经粘了十几次,每次还会漏掉一两条要求。
把它写进 CLAUDE.md?可这段内容一个月只用两次,却要在每个会话里占着上下文。这正是 Skill 要解决的问题:把反复使用的流程或资料打包起来,需要时用一条 /命令 调出来,不需要时几乎不占空间。
Skill 是什么
一个 Skill 就是一个目录,里面至少有一个 SKILL.md 文件。文件分两部分:开头 --- 之间的 YAML 前置信息(frontmatter),告诉 Claude 这个 Skill 叫什么、什么时候用;后面是 Markdown 正文,写 Claude 执行时要遵循的指令。
调用方式有两种:你在消息开头输入 /skill-name 直接调用,或者 Claude 发现你的请求和 Skill 的描述匹配时自动加载。Claude Code 的 Skill 遵循 Agent Skills 开放标准,同一份 Skill 在其他支持该标准的工具里也能用(部分字段是 Claude Code 独有的扩展)。
放在哪里
| 位置 | 路径 | 在哪些会话里加载 |
|---|---|---|
| 个人 | ~/.claude/skills/<名字>/SKILL.md |
你本机的所有项目 |
| 项目 | .claude/skills/<名字>/SKILL.md |
这个仓库里的会话,提交到 git 后团队共享 |
| 嵌套 | <子目录>/.claude/skills/<名字>/SKILL.md |
在该子目录启动,或 Claude 处理到那里的文件时 |
| 插件 | <插件>/skills/<名字>/SKILL.md |
启用该插件的地方,命令形如 /插件名:skill名 |
| 企业 | 托管设置目录下的 .claude/skills/ |
组织部署到的机器 |
同名时,企业级优先于个人级,个人级优先于项目级;插件 Skill 带命名空间,不会冲突。命令名默认取目录名,也可以用前置信息里的 name 指定。
Claude Code 会监听这些目录,会话中新增或修改 SKILL.md 立即生效,不用重启。只有当你新建了一个会话启动时还不存在的顶层 skills 目录,才需要运行 /reload-skills。输入 /skills 可以列出当前所有 Skill,按 t 还能按 token 数排序。
前置信息:常用字段
所有字段都是可选的,但官方强烈建议写 description。字段名必须完全一致,写错了不会报错,只会被悄悄忽略。
| 字段 | 作用 |
|---|---|
name |
显示在 / 菜单里的命令名,默认用目录名 |
description |
做什么、什么时候用。Claude 靠它决定是否自动加载,关键用途要放在最前面 |
when_to_use |
补充触发场景或示例说法,和 description 合计超过 1536 字符会被截断 |
argument-hint |
输入命令时的参数提示,如 [版本号] |
disable-model-invocation |
设为 true 后只能由你手动调用,Claude 不会自己触发 |
user-invocable |
设为 false 后从 / 菜单隐藏,只让 Claude 在需要时加载 |
allowed-tools |
调用这个 Skill 的那一轮里,列出的工具无需逐次批准 |
model、effort |
这个 Skill 运行时临时换用的模型和推理强度 |
context、agent |
context: fork 让 Skill 在独立的子智能体里运行,agent 指定子智能体类型 |
paths |
只在处理匹配这些路径的文件时才自动加载 |
正文里还能用几种替换:$ARGUMENTS 是调用时跟在命令后面的全部参数,$0、$1 按位置取单个参数,${CLAUDE_SKILL_DIR} 是 Skill 所在目录,方便引用附带的脚本。以 !`命令` 开头的写法叫动态上下文注入:Claude Code 会先在本机执行这条命令,把输出替换进正文,Claude 看到的就是真实数据而不是命令本身。
按需加载:为什么 Skill 几乎不占地方
这是 Skill 和 CLAUDE.md 最大的区别:
| 前置信息 | 你能调用 | Claude 能自己调用 | 进入上下文的方式 |
|---|---|---|---|
| 默认 | 能 | 能 | 描述始终在上下文里,调用时才加载全文 |
disable-model-invocation: true |
能 | 不能 | 描述也不进上下文,调用时才加载全文 |
user-invocable: false |
不能 | 能 | 描述始终在上下文里,调用时才加载全文 |
会话开始时,Claude 只看到每个 Skill 的名字和简短描述;正文、参考资料、脚本都留在磁盘上,用到才读。所以一份上千行的 API 规范做成 Skill,平时几乎不花成本。
调用之后,渲染好的 SKILL.md 正文会作为一条消息留在对话里,后续轮次不会重新读文件。上下文被压缩时,每个 Skill 只保留开头的 5000 token,所以最重要的指令要写在 SKILL.md 前面。有副作用的流程,比如部署、发消息、打 tag,务必加 disable-model-invocation: true,你不会希望 Claude 觉得「代码看起来差不多了」就自己去部署。
Skill、CLAUDE.md、斜杠命令各管什么
| 机制 | 什么时候生效 | 适合放 |
|---|---|---|
| CLAUDE.md | 每个会话自动加载 | 每次都要遵守的事实和规则:构建命令、代码约定 |
.claude/rules/ 路径规则 |
每次会话,或处理匹配文件时 | 只和某类文件、某个目录相关的约定 |
| Skill | 你输入 /名字,或 Claude 判断相关时 |
偶尔用的参考资料、多步骤流程 |
| 内置命令 | 你输入 /clear、/compact 等 |
Claude Code 自身的固定功能,不是给模型的指令 |
| Hook | 到了特定生命周期事件必定执行 | 必须每次都发生、不需要模型判断的动作 |
判断起来很简单:每次都需要知道的写 CLAUDE.md;偶尔需要、或者是一套操作步骤的做成 Skill;必须保证执行、不能靠模型自觉的写成 hook(见第 7 课Hooks 自动化)。官方给的信号也很实用:同一段流程第三次粘贴进聊天,或者 CLAUDE.md 里某一节已经从「事实」长成了「操作步骤」,就该把它挪成 Skill。
你写了一个 /deploy-staging Skill,会执行构建并推送到测试服务器。你希望它只在你明确输入命令时才运行。应该怎么配置?
手把手:写一个中文发版说明 Skill
目标:输入 /changelog-zh v1.4.0,Claude 读取上一个 tag 之后的提交,按模板生成中文发版说明,追加到 CHANGELOG.md 顶部。
第 1 步:建目录。 这是项目相关的流程,放在项目里,团队都能用:
mkdir -p .claude/skills/changelog-zh
第 2 步:写 SKILL.md。 保存为 .claude/skills/changelog-zh/SKILL.md:
---
name: changelog-zh
description: 根据上一个 tag 之后的 git 提交,生成面向用户的中文发版说明并写入 CHANGELOG.md。用于发版、写更新日志时。
argument-hint: "[版本号,如 v1.4.0]"
disable-model-invocation: true
allowed-tools: Bash(git log *) Bash(git describe *)
---
为版本 $ARGUMENTS 生成中文发版说明。
## 仓库现状
- 最近的 tag:!`git describe --tags --abbrev=0 || echo "(还没有 tag)"`
## 步骤
1. 运行 `git log <最近的 tag>..HEAD --no-merges --pretty=format:"%h %s"` 获取提交;没有 tag 时取最近 50 条。
2. 按 feat → 新功能、fix → 问题修复、perf → 性能优化分类,其余归入「其他改动」。
3. 去掉对用户没有影响的提交:ci、chore、仅改文档或测试的提交。
4. 每条用用户能看懂的话重写,不出现函数名,末尾保留短 hash。
5. 按 [template.md](template.md) 的格式输出,先给我看,确认后再插入 CHANGELOG.md 顶部。
## 规则
- 没有给出版本号时,先问我,不要自己编。
- 不要修改 CHANGELOG.md 里已有的历史内容。
第 3 步:加一个支持文件。 在同一目录新建 template.md:
## 版本号(发布日期 YYYY-MM-DD)
### 新功能
- 一句话说明用户能做什么新事情(abc1234)
### 问题修复
- 一句话说明修好了什么现象(def5678)
### 其他改动
- 性能、依赖升级等(9a8b7c6)
SKILL.md 里用链接指向它,Claude 需要时才去读。官方建议 SKILL.md 控制在 500 行以内,更长的参考资料、示例都拆成支持文件。
这份 Skill 里有几个刻意的设计:
disable-model-invocation: true:写文件、发版这类有副作用的事,只在你说要做的时候做;- 动态注入:
!`git describe ...`在 Claude 看到正文之前就执行,它拿到的是真实的 tag。注意注入的命令一旦以非零码退出,整个 Skill 调用会失败,所以加了|| echo兜底,覆盖仓库还没有 tag 的情况; allowed-tools:只在这一轮免确认git log和git describe,你发下一条消息后就失效,不会长期放宽权限;- 先展示、后写入:生成的说明先给你审,再落盘。
第 4 步:测试。
> /skills# 列表里应能看到 changelog-zh,没有的话检查目录名和 SKILL.md 第一行是否是 ---> /changelog-zh v1.4.0 Bash git log v1.3.2..HEAD --no-merges --pretty=format:"%h %s"⏺ 共 23 条提交,过滤掉 7 条 ci / chore 提交后,整理如下: ## v1.4.0(2026-10-25) ### 新功能 - 订单列表支持按退款状态筛选(a1c93e2) ...⏺ 确认无误的话,我把它插入 CHANGELOG.md 顶部。 第 5 步:迭代。 不满意就直接改 SKILL.md,保存后在同一会话里再调用一次就能看到效果。如果 Skill 本该被自动调用却没触发(没设 disable-model-invocation 的那类),先检查 description 里有没有用户自然会说的关键词;反过来触发太频繁,就把描述写得更具体。
你的 SKILL.md 有 800 行,前 600 行是接口字段说明,最后 200 行才是「生成代码时必须遵守的五条规则」。会话很长、发生过几次自动压缩后,Claude 开始不遵守这五条规则。最合理的改法是?
动手:把你自己的重复流程做成 Skill
我想把一个经常重复的流程做成 Claude Code 的 Skill。流程是:(在这里用几句话描述,例如「每次新增后端接口:建 DTO、写 Service、注册路由、补单元测试、更新接口文档」)。
请你:
- 先读项目里一个现有的同类实现,总结出这个流程在本项目里的真实步骤和约定;
- 判断它更适合做成 Skill 还是写进 CLAUDE.md,说明理由;
- 如果适合做 Skill,起草 .claude/skills/对应名字/SKILL.md:写好 description(关键用途放最前)、argument-hint;判断是否有副作用,决定要不要 disable-model-invocation;正文控制在 60 行以内,长的参考内容拆到支持文件;
- 列出我该用哪两三句话测试它能否被正确触发。
先给我看草稿,确认后再创建文件。
动手清单
0/5参考来源
- Extend Claude with skills(Claude Code 官方文档)
- Extend Claude Code(Claude Code 官方文档)
- Commands(Claude Code 官方文档)
- Best practices for Claude Code(Claude Code 官方文档)
工具更新很快,若与官方文档不一致,以官方为准。
学完了吗?
标记完成会记录在本机浏览器,计入你的学习进度和连续天数。