03 · Skill 什么时候该做、怎么做

03 · Skill 什么时候该做、怎么做

文字规则不够用时的升级。80% 的工夫在 description。

开场比喻

对前端开发者,Skill 最贴切的类比是 VS Code extension

  • 你不会打开 VS Code 就激活所有插件
  • 每个插件有 activationEvents("写 TypeScript 时激活")
  • 需要时才出来,平时安静在后台

Claude Code 里的 skill 同理——写了不代表每次会话都加载,它有 description 当"激活条件",只在匹配场景被 Claude 主动拉进来。

把前两篇串起来:三层升级路径

信息重复度存哪
说一次对话上下文
反复说(文字规则够用)CLAUDE.md / auto-memory
反复说 + 流程复杂 + 上下文重Skill(文字规则升级为可调用模块)

Skill 是文字规则不够用时的下一阶

三个触发条件(至少满足两个才做)

① 同类任务做过 3 次以上

第一次不做,第二次考虑,第三次必须做。一次性任务写 SKILL.md 的成本 > 重做一次。

② 流程稳定

能用有限步骤枚举清楚。每次做法都不一样 → 做成 skill 只会固化错误

③ 上下文重

规则展开超过 30 行塞 CLAUDE.md 不合适 → 抽成 skill,CLAUDE.md 保持清爽。

什么时候 该做

情况为什么
一次性任务成本 > 收益
流程不稳定会固化错误
一句 prompt 就能说清直接说
每次要自动触发hook,不是 skill

最关键的边界:自动触发 → hook;按需触发 → skill。混淆是新手高频错误(见 06)。

SKILL.md 解剖

标准结构:

---
name: add-region
description: 往项目添加新的 App Store 地区。
  当用户说"加个 X 地区"、"support <country>"、"新增 <地区代码>"时触发。
  输入:ISO 3166-1 alpha-2 大写代码。
---
 
# Add Region
 
## When to use
- 用户明确要给项目新增一个 App Store 地区
- 输入是地区代码(如 `BR``DE`
 
## Steps
1. 读 `src/constants/regions.ts`,确认目标地区不在
2. 查 Apple App Store 支持列表(`scripts/verify-apple-region.ts`
3. 追加到 `regions.ts`,按字母序维持
4. 所有 `messages/*.json` 补翻译 key
5. 更新 i18n 测试快照
6. 跑 `pnpm test -- regions``pnpm build`
7. 输出 commit 建议
 
## Inputs
- 地区代码(ISO 3166-1 alpha-2 大写)
 
## Output
- `regions.ts` 新增一行
- 所有语言 JSON 新增翻译
- Commit message 建议
 
## Do NOT
- 不往 `constants/` 以外的文件硬编码地区
- 不跳过 build 验证

三要素:frontmatter(身份证)+ When to use(门牌)+ Steps(剧本)

description 是生死线

Claude 决定"要不要加载这个 skill" 只看 description。写不好,skill 白做。

好 description 公式

[做什么] + [什么时候触发] + [输入形态]

❌ 太笼统

description: 添加地区到项目

Claude 不知道"什么项目"、"什么叫添加地区"。

✅ 精准

description: 往 XX 项目添加新的 App Store 地区。
  当用户说"加个 X 地区"、"support <country>"、"新增 <地区代码>"时触发。
  输入:ISO 3166-1 alpha-2 大写代码。

四个要点

  1. 项目 / 领域明示——避免别的项目误触发
  2. 触发短语列全(中英文都列)——用户表达不统一
  3. 输入格式——让 Claude 能识别"这不是我该干的活"
  4. 隐性"不做什么"——比如上例没写"删除地区",Claude 不会误用到删除场景

Skill 放哪

<repo>/.claude/skills/<name>/SKILL.md    ← 项目级,入 git(团队共享)
~/.claude/skills/<name>/SKILL.md          ← 个人全局,跨所有项目

判断:

  • 项目专属 → 项目级(入 git,团队都能用)
  • 跨项目通用(如"从剪贴板生成 kebab-case slug")→ 个人级

加载条件

项目级 skill 能被识别,需要三个条件:

① 目录结构必须精确

<repo>/.claude/skills/<skill-name>/SKILL.md

注意三层:

  • .claude/ 是项目配置根目录(必须这个名字)
  • skills/ 子目录(必须这个名字)
  • 每个 skill 各自一个子目录
  • 主文件必须叫 SKILL.md(大小写敏感;Linux / CI 环境需特别注意,macOS 默认不区分大小写,但 CI 通常跑在 Linux 上)

② 项目必须被"信任"

Claude Code 首次进入新仓库时会问:

This directory contains a .claude/ config. Do you trust it?

Yes,项目级 skills 才生效。

③ Frontmatter 合法

至少带 namedescription

---
name: add-region
description: <一句话,谁 / 什么时候 / 输入啥>
---

加载优先级

同名 skill 存在多处时:

项目级 (<repo>/.claude/skills/)  >  用户级 (~/.claude/skills/)  >  内置

项目级覆盖用户级——比如你用户级有个通用 deploy skill,项目里可以放一个同名的覆盖掉。

进阶:索引式 skill

当一个 skill 覆盖大量主题(如"Next.js 最佳实践")时,单文件会膨胀。此时用**"索引 + 分派"模式**:

next-best-practices/
├── SKILL.md              ← 4KB 索引(加载门面)
├── async-patterns.md     ← 1.7KB
├── bundling.md           ← 4.4KB
├── data-patterns.md      ← 6.7KB
├── ... 另外 16 个专题 md
└── self-hosting.md       ← 8.3KB

SKILL.md 本体不教具体知识,只做两件事:

  1. 声明覆盖哪些领域
  2. 告诉 Claude 想看 X 去读 X.md

两级触发机制

## Image Optimization
See [image.md](./image.md) for:
- Always use `next/image` over `<img>`
- Remote images configuration
- Responsive `sizes` attribute
- Blur placeholders
- Priority loading for LCP

不只给路径,还列了子文件里能找到什么。Claude 加载 SKILL.md 后看清单,不用真的打开 image.md 就能判断现在需不需要读它。

两级过滤:

  1. 外层 description → Claude 决定要不要拉 SKILL.md
  2. 内层 bullet list → Claude 决定要不要拉具体子文件

好处

问题单文件版索引分派版
触发一次加载多少85KB 全进仅 4KB 索引
Claude 聚焦度好(按需)
维护成本动巨文件改子文件即可

什么时候用

  • 主题超过 5 个且彼此独立
  • 总内容超过 20KB
  • 同一领域有"按场景"分派的自然结构

不适用:单一任务的线性流程(如 add-region)——没必要拆。

字段细节:user-invocable

看到这个字段你可能会愣一下:

user-invocable: false

含义:这个 skill 不能被用户直接调用(比如 /next-best-practices),只能由 Claude 自己判断要不要拉进来。

字段值含义典型 skill
默认(true用户可输 /xxx 触发/review/security-review
false只能 Claude 自动触发领域规则类(写 Next.js 时被动参考)

用法判断

  • Skill 是"命令" → 默认(user-invocable)
  • Skill 是"被动参考的规则集" → false

管理纪律

  1. 一个 skill 一件事——SKILL.md 超过 200 行多半该拆
  2. 脚本 / 模板放子目录,SKILL.md 保持纯指令
  3. 定期清理:三个月没触发过的 → 要么删,要么改 description
  4. 少而精 >>> 多而杂——skill 越多 Claude 选择负担越重
  5. 子文件 < 1.5KB 考虑合并——加载 overhead 不值

反模式三连

① SKILL.md 当说明书写

前半段"本 skill 介绍 / 设计理念 / 历史背景"——Claude 需要指令,不是背景故事。

② description 写成功能清单

description: 本 skill 可以:添加地区、删除地区、修改地区、查询地区...

万能 skill 是触发灾难。一个 skill 一个动作,要删除流程?单开 remove-region

③ 把 hook 的事做成 skill

"每次提交前跑 tests"——这是 hook。skill 需要主动拉取,不会自动激活。

一句话总结

Skill 是文字规则的升级版:当一条规则需要多步骤 + 脚本 + 验证时,升级成 skill。

写 skill 的 80% 工夫在 description——那是它唯一的生死线。

速查:两种典型形态

形态场景结构
单步流程add-regioncity-card单 SKILL.md + scripts/
索引分派next-best-practicesui-ux-pro-max顶层 SKILL.md + 多个主题 md
纯工作流/review/security-review单 SKILL.md,user-invocable 默认
被动参考领域规则集多文件,user-invocable: false

← 02 · 记忆的三层体系 | 目录 | 04 · Plan → Execute → Review 的协作节奏 →