Skills 技能:把重复任务封装成可复用技能

什么时候该写一个 Skill

判断标准一句话:当你发现自己第三次往对话框里粘贴同样的指令、清单或流程时,就该封装成 skill 了。还有一个信号来自 CLAUDE.md——当某个条目从"事实"长成了"多步骤流程",它就该搬出 CLAUDE.md(每会话都占上下文),搬进 skill(用到才加载)。

Skill 的本质是:一个带 YAML 前置元数据的 SKILL.md 文件,Claude 在相关时自动加载它,或者你用 /技能名 手动调它。旧版的 .claude/commands/*.md 自定义命令已和 skills 合并——两种文件都还支持、效果相同,新写法建议统一用 skills。顺带一提,Claude Code 内置的不少"命令"(/code-review、/debug、/batch)其实就是官方预装的 bundled skills——机制和你自己写的一样,只是内置。

五分钟写出第一个 Skill

目标:一个总结未提交改动并标出风险的技能。

mkdir -p ~/.claude/skills/summarize-changes

写 SKILL.md(放在刚建的目录里):

---
description: 总结未提交的改动并标记风险点。当用户问改了什么、
  要提交信息或想审阅 diff 时使用。
---

## 当前改动

!`git diff HEAD`

## 指令

用两三条要点总结上面的改动,然后列出你发现的风险:
缺失的错误处理、硬编码值、需要同步更新的测试。
如果 diff 为空,直接说明没有未提交改动。

两处细节决定了这个 skill 的质量。description 是给 Claude 的自动调度线索——写得越清楚"什么时候该用",Claude 自动触发的准确率越高。!git diff HEAD`` 是动态上下文注入:Claude Code 会先执行这条命令,把输出替换进内容再交给 Claude,于是指令到达时最新的 diff 已经内嵌——skill 从"让它去查"升级为"带着数据来"。

测试两条路都走一遍:问一句"我改了什么?"(应自动触发),或直接敲 /summarize-changes。

放哪儿决定谁能用

位置 生效范围
企业托管目录的 .claude/skills/ 组织下发的所有机器
~/.claude/skills/<名字>/SKILL.md 你的全部项目
项目 .claude/skills/<名字>/SKILL.md 本仓库(提交进 git 团队共享)
子目录的 .claude/skills/ 该子目录(按需懒加载)
插件的 skills/ 插件启用处,命令带插件前缀

monorepo 用户注意:从 packages/frontend/ 启动也能加载仓库根的 skills(向上扫描),而根目录和子目录有同名 skill 时两个都可用——/deploy 跑根上的,/apps/web:deploy 跑子目录那个。同名冲突的解析优先级是:企业 > 个人 > 项目,你的 skill 还能覆盖同名的内置命令和 bundled skill(但覆盖不了它们的别名)。

常用前置元数据

frontmatter 是 skill 的控制面板,最常用的几个字段:

---
description: 什么时候用(自动调度的依据)
argument-hint: "<PR号>"          # 输入提示
allowed-tools: Bash(git *), Read  # 该技能内放行的工具
model: haiku                      # 指定模型(省成本)
disable-model-invocation: true    # 禁止自动触发,只许手动调用
user-invocable: false             # 不出现在 / 菜单,纯自动触发
---

字段选择的心智:description 永远要写好;长流程、重成本的技能加 disable-model-invocation: true——自动触发一旦押错方向,浪费的是你的等待时间;简单查询类用 model: haiku 降本。完整字段清单见官方 Skills 文档。

目录不止一个文件

skill 目录里除了 SKILL.md 还能放支撑文件——参考文档、脚本、模板:

.claude/skills/release/
├── SKILL.md           # 主指令
├── checklist.md       # 发布检查单(SKILL.md 里指引 Claude 按需读)
└── changelog.sh       # 生成变更日志的脚本

这解决了"指令太长"的老问题:SKILL.md 保持精炼,重参考资料按需读取。技能之间还能串联——一条消息里最多连六个,/skill-a /skill-b 做某某事。

选型:skill、CLAUDE.md、hook、MCP 的边界

四种机制都能"给 Claude 加东西",选错的代价是浪费上下文或行为不稳定:

需求 正确载体 理由
每会话都要知道的规则/事实 CLAUDE.md(或无 paths 的 rules) 启动即载
只在特定文件上才适用的规范 带 paths 的 rules 按需加载省上下文
多步骤流程、可复用模板 skill 用到才加载正文
每次必须发生的事(格式化/拦截) hook 确定性执行
连接外部系统 MCP 标准化协议
打包分发以上多种 plugin 一个包全带走

记忆口诀:知识进文件,流程进 skill,规则进 hook,连接进 MCP。

从 CLAUDE.md 里"拆"技能的实操

最实际的迁移场景:CLAUDE.md 里的某段流程越写越长。以"发布流程"为例演示拆法:

迁移前(CLAUDE.md 里占 40 行,每会话都加载):
## 发布流程
1. 跑 npm run build 确认构建通过
2. 更新 CHANGELOG.md,格式参照上两个版本
3. 打 tag 并推送
4. 在内部频道公告(模板见 wiki)
……

迁移后:
- CLAUDE.md 只留一行:"发布流程用 /release 技能"
- 40 行流程全文 + 模板内容移进 .claude/skills/release/SKILL.md

效果对比:迁移前每会话固定消耗 40 行上下文(哪怕今天根本不发布);迁移后只在你说 /release 或 Claude 判断相关时才加载。上下文会计(见上下文管理那章)的角度,这是纯粹的只赚不赔。

热更新与在线管理

skills 支持会话中途热加载:往 .claude/skills/ 里新加或修改文件后跑 /reload-skills,不用重启会话。/skills 命令列出全部可用技能,支持按名字/描述过滤、按 token 数排序(按 t),还能用空格键逐个控制"是否让 Claude 看见"——对第三方技能不想删又嫌它占上下文的,关可见性即可。

一套团队级的技能库设计

给个真实团队在用的技能清单,感受这个东西能沉淀什么:

技能名 内容 谁用
/new-api 按团队模板生成 CRUD 接口 + 测试 + 文档骨架 全员
/db-review 检查迁移脚本:锁表风险、回滚语句、索引 后端
/daily-report 汇总当日提交和会话产出,生成日报 全员
/deploy-staging 执行预发部署的完整流程与验证 值班同学

这套库放项目 .claude/skills/ 里随仓库分发,新同事 clone 下来第一天就拥有全队沉淀。Skills 是团队知识的最低成本封装形式——不用写内部工具、不用搭平台,一个 md 文件就是一次知识入库。

维护也有讲究:定期跑 /skills 看列表(可按 token 数排序),跑 /skill-doctor 看每个技能的上下文成本和使用频率——长期没人用的技能果断删,每一条 description 都在每会话占位置。想了解别家 AI 编辑器的同类机制做对照,可看本站 Cursor 系列书 里 Rules 与自定义命令的章节。

本章由 WorkBuddy 原创整理,事实性内容参考 Claude Code 官方文档。