Skill 是一份写给 Claude 看的 Markdown 说明书,告诉它"什么时候用、怎么用、参数怎么给"。Claude 判断当前对话匹配就把它读进来,在主对话里按步骤执行。

目录


Skill 是什么

用一句话说:Skill 是 Claude 的"技能包",一个技能包 = 一份说明书 + 一堆可选的辅助资源

举个通俗例子:

想象你雇了一个装修师傅。他人很聪明,但每次装修风格不同。你不能每次都从头教他"我家墙面要刷什么漆、地板要用什么胶",太啰嗦。于是你把这些标准写成一份《本项目装修规范》文档,师傅进场先翻这个文档,之后照着做。

  • 装修师傅 = Claude
  • 装修规范文档 = SKILL.md
  • 文档里附的样品图、材料清单 = skill 目录下的辅助文件

关键点:文档本身不"运行",它只是给师傅(Claude)看的。真正干活的是师傅本人,用的还是他自己带的工具(Claude 的 Read/Edit/Bash 等)。


Skill 的基本结构

一个 skill 就是一个目录,里面必须有 SKILL.md,其他都是可选的:

.claude/skills/gen-changelog/
├── SKILL.md              ← 必需,说明书本体
├── scripts/              ← 可选,脚本
│   └── append.sh
├── templates/            ← 可选,模板文件
│   └── entry.template
└── examples/             ← 可选,示例
    └── good-entry.md

放置位置有两种:

  • 项目级<项目根>/.claude/skills/xxx/ —— 跟仓库走,团队共享
  • 用户级~/.claude/skills/xxx/ —— 对当前用户所有项目生效

Claude Code 启动时自动扫描这两个目录,不需要注册或重启。


frontmatter 字段详解

SKILL.md 顶部有一段用 --- 包住的 YAML,叫 frontmatter,这是给 Claude 看的"元信息"。至少要有两个字段:

---
name: gen-changelog
description: 根据当前 git 改动生成 changelog 条目并追加到 CHANGELOG.md。当用户说"更新 changelog"、"记一下这次改动"、或提 PR 前需要补充变更记录时使用。
---

name:技能的唯一标识

  • 小写、连字符分隔(kebab-case)
  • 用户可以通过 /name 手动触发(/gen-changelog
  • 全局唯一,不要和别的 skill 重名

description:什么时候用它

这是整个 skill 里最重要的一句话。Claude 判断"要不要用这个 skill"完全靠这句话。

写好 description 有三个要点:

1. 说清楚"做什么"

❌ 差:处理 changelog
✅ 好:根据当前 git 改动生成 changelog 条目并追加到 CHANGELOG.md

2. 说清楚"什么时候用"

给 Claude 具体的触发场景关键词。

❌ 差:用于 changelog 管理
✅ 好:当用户说"更新 changelog"、"记一下这次改动"、或提 PR 前需要补充变更记录时使用

3. 说清楚"什么时候不用"(可选但强烈推荐)

典型的例子:

description: 仅当用户手动输入 /spec 斜杠命令、或其他 skill 明确点名调用本 skill 进入 OpenSpec 规格阶段时才使用……禁止模型仅因看到需求目录、meta.json 或上下文出现"规格""spec""OpenSpec"等模糊关键词就主动触发。

明确说了"不要因为看到 spec 这个词就自己调"。这是防止 Claude 过度联想触发。

通俗理解:description 就像招聘启事上的"任职要求"和"这份工作不合适哪些人"。写得越具体,来面试的人(Claude 的调用决策)越精准。

其他常见字段(可选)

---
name: xxx
description: xxx
allowed-tools:
  - Read
  - Bash
model: sonnet
---
  • allowed-tools:限制这个 skill 只能用哪些工具(很少用,一般 skill 保持全工具集)
  • model:指定运行时用哪个 Claude 模型(一般不指定,继承用户设置)

Skill 的触发方式

Skill 有两种被触发的方式:

方式一:用户显式触发(/skill-name

用户在对话里敲 /gen-changelog,Claude 立即加载并执行这个 skill。这是最可控的方式,用户明确表达了意图。

方式二:Claude 自主匹配

用户说自然语言,Claude 扫描所有 skill 的 description,找出最匹配的一个,主动去读。

举例:用户说"帮我记一下这次改动",Claude 想:“这匹配 gen-changelog 的 description 里的’记一下这次改动’” → 主动加载 → 按 skill 步骤执行。

方式二能否稳定触发,完全取决于 description 写得好不好。写不好的 description 会导致:

  • 漏触发:用户用同义说法(“总结改动”),Claude 匹配不到,自己写了个野路子
  • 误触发:description 太宽(“处理代码”),Claude 什么场景都想调它

Skill 里可以放什么

一个常见的疑问:“如果我要调一个脚本,脚本代码放哪?”

答案:放 skill 目录里,在 SKILL.md 里告诉 Claude 怎么调用它。

实际做法,一个 skill 目录可以包含:

1. 脚本(shell / node / python)

SKILL.md 里写:

## 步骤

1. 用 `bash` 工具执行:
   `bash ${CLAUDE_PLUGIN_ROOT}/skills/gen-changelog/scripts/append.sh`
2. 从 stdout 读取生成的条目
3. 交给用户确认

Claude 用它自带的 Bash 工具执行脚本。脚本本体不由 Claude Code 运行,是 Claude 通过 Bash 工具运行

2. 接口地址

如果你想调内部接口:

## 步骤

1. 组装请求 body(参考 templates/request.json)
2. 用 WebFetch 工具 POST 到 https://xxx.internal/api/foo
3. 解析响应

3. 模板文件

skills/gen-story/
├── SKILL.md
└── templates/
    ├── prd.template.md
    └── techspec.template.md

SKILL.md 里让 Claude 用 Read 工具把模板读进来,再基于模板填充。

4. 参考数据

比如常用规则清单、错误码字典等。

核心心智:skill 目录就是"这个技能需要的所有东西"的集合。SKILL.md 是入口,其他文件由 Claude 按 SKILL.md 的指引去读取和使用。


五个典型应用场景

场景 1:把一个反复做的检查流程标准化

举例:每次 PR 前你都要跑 npm run lint + npm run typecheck + npm run test:unit,然后看有没有失败的用例,失败的话按套路处理。

做成 skill:写个 pre-pr-check skill,把这套流程写在 SKILL.md 里。以后 /pre-pr-check 一键触发。

为什么用 skill:流程有明确套路,Claude 按步骤走就行;如果有失败可以在主对话里和你商量怎么修(skill 的优势之一)。

场景 2:根据上下文生成结构化产物

举例:需要根据当前 git diff 生成一份"变更说明"发到 PR 描述里。生成规则:先分类(feature / fix / refactor)、再列改动点、最后写测试建议。

做成 skillgen-pr-desc skill,SKILL.md 里定义生成规则和模板。

为什么用 skill:Claude 需要读 diff 的细节来生成(不能开新会话丢细节),且用户可能要边看边改(需要交互)。

场景 3:调用外部脚本,参数由 Claude 决定

举例:公司有一个内部 CLI xxcli deploy --env=xxx --service=yyy,参数需要根据当前分支、当前修改的服务名推断。

做成 skilldeploy skill,SKILL.md 里让 Claude 先用 git 命令推断服务名和环境,再拼装 xxcli 命令执行。

为什么用 skill:脚本执行是 Claude 用 Bash 工具做的,参数推断需要 LLM 智能。skill 就是把"推断 + 执行"的流程固化下来。

场景 4:从知识库拉资料到当前上下文

举例:开发前想把相关的需求文档、设计决策、历史 issue 一次性拉进上下文。

做成 skillreq-load skill,SKILL.md 里定义"根据用户提到的模块名去搜 docs/decision/、openspec/specs/ 里的相关文档"。

为什么用 skill:主对话需要看到文档全文才能好写代码(不能用 subagent 只拿摘要),且拉多少、拉哪些需要 Claude 智能判断。

场景 5:多步骤有依赖的复杂流程

举例:需求归档流程:先跑 tests → 通过后合并 openspec change → 更新 docs/decision/ 索引 → 生成归档报告。

做成 skillreq-archive skill,SKILL.md 里定义顺序、失败处理、每步的验收标准。

为什么用 skill:步骤多、有前置依赖,且中间失败要能让用户介入。


从零建一个 Skill

一个最小可用 skill 的完整例子,用来"根据当前改动生成 changelog 条目"。

步骤 1:建目录

mkdir -p .claude/skills/gen-changelog/scripts

步骤 2:写脚本

.claude/skills/gen-changelog/scripts/append.sh

#!/bin/bash
# 从 stdin 读一行文本,追加到 CHANGELOG.md 顶部
CHANGELOG="CHANGELOG.md"
[ -f "$CHANGELOG" ] || echo "# Changelog" > "$CHANGELOG"

TMP=$(mktemp)
head -1 "$CHANGELOG" > "$TMP"
echo "" >> "$TMP"
cat >> "$TMP"
echo "" >> "$TMP"
tail -n +2 "$CHANGELOG" >> "$TMP"
mv "$TMP" "$CHANGELOG"
echo "已追加到 $CHANGELOG"

步骤 3:写 SKILL.md

.claude/skills/gen-changelog/SKILL.md

---
name: gen-changelog
description: 根据当前 git 改动生成 changelog 条目并追加到 CHANGELOG.md 顶部。当用户说"更新 changelog"、"记一下这次改动"、"补一下变更记录",或在提 PR 前需要生成变更说明时使用。
---

# 生成 Changelog 条目

## 使用时机

- 用户显式触发 `/gen-changelog`
- 用户提到"更新 changelog"、"记一下这次改动"等相似意图

## 执行步骤

1. **获取改动**:跑 `git diff --staged`,如果没有暂存内容则跑 `git diff HEAD~1`
2. **判断类型**:根据改动内容判断是以下哪一类:
   - `feat`:新功能
   - `fix`:bug 修复
   - `refactor`:重构
   - `docs`:文档
   - `chore`:杂项
3. **生成条目**:格式为 `- [{type}] {简短描述}(涉及文件: xxx)`
4. **让用户确认**:把生成的条目展示给用户,问是否需要调整
5. **写入文件**:确认后用 Bash 执行:
   `echo "生成的条目" | bash .claude/skills/gen-changelog/scripts/append.sh`

## 边界

- 不要覆盖已有的 changelog 内容,只追加
- 生成的描述控制在 30 字以内
- 遇到多类型混合改动,拆成多条

步骤 4:验证

在 Claude Code 里打 /gen-changelog,看能不能触发;或者说"帮我记一下这次改动",看 Claude 会不会主动匹配到。


常见问题

Q1:Skill 和普通的 CLAUDE.md 有什么区别?

  • CLAUDE.md每次会话都自动加载的项目说明,写全局约定(用什么框架、代码风格)
  • Skill按需加载的,只有 Claude 判断这次要用才读,适合写具体流程

放在 CLAUDE.md 里的东西每次都占 token,只有 skill 才能做到"用时才加载"。

Q2:Skill 里的脚本会自动执行吗?

不会。skill 只是"说明书",Claude 读完说明书后用它自己的工具(Bash / Read 等)去执行脚本。这意味着执行前用户能看到 Claude 要跑什么命令,可以拦下来。

Q3:Skill 可以调用其他 Skill 吗?

可以。在 SKILL.md 里让 Claude 用 Skill 工具调用另一个 skill 就行。

Q4:description 到底该写多长?

看情况:

  • 纯手动触发(只靠 /name):写清"做什么"就行,短点无所谓
  • 需要 Claude 自主匹配:写详细一点,包含"什么时候用 + 什么时候不用 + 关键词"
  • 重型操作(跑测试、跑构建、影响面大):一定要写清"禁止条件",防止误触发

一般 1-3 行就够,超过 5 行说明可能想在 description 里放操作步骤,那些应该放正文里。

Q5:Skill 触发不稳定,Claude 有时匹配不到怎么办?

三个方向排查:

  1. description 关键词覆盖不全:把用户可能的说法都列上("更新/生成/写/记录 changelog"都写进去)
  2. 和别的 skill 描述冲突:两个 skill description 太像,Claude 选不定或选错
  3. 改用手动触发:如果稳定性要求高,直接绑 /name,别指望 Claude 猜

Q6:Skill 会不会读了没用(token 浪费)?

Claude 只有在判断"这次要用"时才加载 SKILL.md 内容。加载后 Claude 会尽量按 skill 走,不会读了不用。所以关键是 description 匹配准确 —— description 写得越差,误加载越多。


快速参考卡

┌────────────────────────────────────────────────────────┐
│  Skill = 说明书                                        │
│                                                        │
│  最小结构:                                            │
│    .claude/skills/xxx/                                 │
│      └── SKILL.md(前面 --- 包 frontmatter)           │
│                                                        │
│  frontmatter 两必需字段:                              │
│    name: 唯一 ID,用户用 /name 触发                    │
│    description: 什么时候用 + 什么时候不用              │
│                                                        │
│  触发方式:                                            │
│    1. 用户敲 /name 显式触发                            │
│    2. Claude 匹配 description 自主触发                 │
│                                                        │
│  Skill 里可以放:                                      │
│    - 脚本(Claude 用 Bash 工具跑)                     │
│    - 模板(Claude 用 Read 工具读)                     │
│    - 接口地址(Claude 用 WebFetch 调)                 │
│    - 参考数据                                          │
└────────────────────────────────────────────────────────┘
Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐