Claude Code 的 Skills 系统是其最强大的扩展机制之一。一个 Skill 本质上是一个 Markdown 文件,它定义了一套可复用的指令集,让你无需每次都从零开始写 Prompt,只需输入 /skill-name 即可让 Claude 精确执行预设工作流。
本教程将带你从空白目录开始,逐步构建一个完整的、生产可用的自定义 Skill。你将深入理解 Skill 的文件结构、YAML Frontmatter 的每一个字段、参数传递机制、动态上下文注入、子代理执行模式,以及如何将 Skill 分享给团队。
Claude Code 提供了三种主要的扩展手段,各有适用场景:
| 扩展方式 | 何时使用 | 上下文影响 |
|---|---|---|
| CLAUDE.md | 适用于几乎每个任务的规则——构建命令、代码风格、架构决策 | 始终加载,始终消耗 Token |
| Skills | 有时才需要的工作流——部署步骤、审查清单、代码生成模式 | 按需加载,只在被调用或相关时生效 |
| Subagents | 不应污染主对话的隔离任务——研究、大规模代码探索 | 完全独立的上下文窗口 |
经验法则:如果一条规则适用于每个会话,放到 CLAUDE.md;如果是特定的工作流,做成 Skill;如果涉及大量阅读或探索,考虑子代理。
graph TD
A[用户输入] --> B{匹配类型}
B -->|/skill-name| C[直接调用 Skill]
B -->|自然语言描述| D[自动发现匹配 Skill]
B -->|全局规则| E[CLAUDE.md 始终加载]
C --> F[加载 SKILL.md 内容]
D --> F
F --> G{context 设置?}
G -->|默认| H[主会话中执行]
G -->|fork| I[子代理独立执行]
I --> J[结果摘要返回主会话]
H --> K[执行完毕]
J --> K
在开始之前,确保你具备以下条件:
claude --version 确认安装正常Skill 的存放路径决定了它的可见范围和优先级。
graph LR
subgraph 优先级从高到低
A[企业级<br/>托管设置] --> B[个人级<br/>~/.claude/skills/]
B --> C[项目级<br/>.claude/skills/]
C --> D[插件级<br/>plugin/skills/]
end
| 级别 | 路径 | 适用范围 |
|---|---|---|
| 企业级 | 托管设置(管理员配置) | 组织内所有用户 |
| 个人级 | ~/.claude/skills/<name>/SKILL.md |
你的所有项目 |
| 项目级 | .claude/skills/<name>/SKILL.md |
仅当前项目 |
| 插件级 | <plugin>/skills/<name>/SKILL.md |
启用该插件的项目 |
当不同级别的 Skill 同名时,高优先级覆盖低优先级。插件级 Skill 使用 plugin-name:skill-name 的命名空间,因此不会产生冲突。
实战建议:团队共享的工作流(如部署、代码审查)放在项目级,个人习惯(如代码生成偏好)放在个人级。
每个 Skill 都需要一个独立目录,其中必须包含 SKILL.md 文件。我们将创建一个实用的 API 端点生成器 Skill 作为贯穿全教程的案例。
# 创建项目级 Skill 目录
mkdir -p .claude/skills/api-endpoint
# 进入目录
cd .claude/skills/api-endpoint
一个成熟的 Skill 目录可以包含更多辅助文件:
api-endpoint/
├── SKILL.md # 主指令文件(必需)
├── template.md # 模板文件,供 Claude 填充
├── examples/
│ └── sample-output.md # 示例输出,展示期望格式
└── scripts/
└── validate.sh # Claude 可执行的验证脚本
最佳实践:SKILL.md 保持在 500 行以内。将详细的参考资料、API 文档或大型示例集移至单独文件,在 SKILL.md 中引用即可,Claude 会按需读取。
Frontmatter 是 SKILL.md 文件顶部的 YAML 配置块,控制 Skill 的行为方式。虽然所有字段都是可选的,但 description 强烈建议填写。
---
name: api-endpoint
description: "根据用户描述生成 RESTful API 端点,包含路由、控制器、验证和测试"
---
---
name: api-endpoint
description: "根据用户描述生成 RESTful API 端点。当用户要求创建 API 路由、新增接口或定义端点时使用。"
argument-hint: "[method] [path] [description]"
disable-model-invocation: false
user-invocable: true
allowed-tools: Read, Grep, Glob, Bash(npx *), Bash(npm *)
model: claude-sonnet-4-6
effort: high
context: default
---
name(名称)
- 显示名称和斜杠命令。默认取目录名。
- 只允许小写字母、数字和连字符。
- 例如:api-endpoint 对应 /api-endpoint 命令。
description(描述)
- Claude 根据此字段决定何时自动加载该 Skill。
- 将关键用例放在最前面——描述在 250 个字符后会被截断。
- 写得好是实现自动发现的关键。
argument-hint(参数提示)
- 在自动补全菜单中显示的参数格式提示。
- 例如:[method] [path] [description] 或 [issue-number]。
disable-model-invocation(禁止模型自动调用)
- 设为 true 后,只有用户可以通过 /name 手动调用,Claude 不会自动加载。
- 适用于有副作用的操作:部署、发送消息、发布版本。
user-invocable(用户可调用)
- 设为 false 后,该 Skill 不会出现在 / 菜单中。
- 适用于 Claude 应该知道但用户不需要直接调用的背景知识。
- 例如:遗留系统架构说明、编码规范上下文。
allowed-tools(允许的工具)
- 限制 Skill 激活时 Claude 可以使用的工具。
- 例如:Read, Grep, Glob 表示只读,Bash(npm *) 限制只能运行 npm 命令。
context(上下文模式)
- 设为 fork 时,Skill 在独立的子代理中运行。
- 适合研究密集型任务,避免中间结果淹没主对话。
agent(子代理类型)
- 配合 context: fork 使用。内置选项:
- Explore:优化的只读代码探索,使用快速模型。
- Plan:专注于架构设计策略。
- general-purpose:完整的工具访问权限。
model 和 effort
- model:为该 Skill 覆盖使用的模型。
- effort:覆盖努力级别,可选 low、medium、high 或 max。
| Frontmatter 设置 | 用户可调用 | Claude 可自动调用 |
|---|---|---|
| 默认 | 是 | 是 |
disable-model-invocation: true |
是 | 否 |
user-invocable: false |
否 | 是 |
Frontmatter 之后的 Markdown 内容就是 Claude 执行 Skill 时遵循的指令集。这是 Skill 的核心。好的指令应该像一份详细的工单——步骤清晰、标准明确、验证完整。
以下是我们 API 端点生成器的完整指令内容:
---
name: api-endpoint
description: "根据用户描述生成 RESTful API 端点。当用户要求创建 API 路由、新增接口或定义端点时使用。"
argument-hint: "[method] [path] [description]"
allowed-tools: Read, Grep, Glob, Bash(npx *), Bash(npm *)
---
根据用户的描述生成 RESTful API 端点:$ARGUMENTS
## 执行步骤
### 1. 分析项目结构
- 读取项目的路由配置,确定路由文件的位置和命名约定
- 确认使用的 Web 框架(Express、Fastify、Next.js App Router 等)
- 检查现有的中间件配置(认证、日志、错误处理)
### 2. 理解现有模式
- 读取 2-3 个现有的 API 端点文件,了解:
- 文件命名约定
- 导入风格和依赖注入模式
- 错误处理模式
- 响应格式约定
### 3. 在写代码之前提问
向用户确认以下信息:
- 是否需要身份验证?如果需要,使用什么策略?
- 请求体的验证规则是什么?
- 是否需要分页?如果需要,默认页面大小是多少?
### 4. 生成代码
基于以上分析,创建以下文件:
#### 路由文件
- 定义 HTTP 方法和路径
- 应用必要的中间件
- 连接到控制器
#### 控制器 / 处理函数
- 输入验证
- 业务逻辑调用
- 标准化响应格式
- 错误处理
#### 数据验证
- 使用项目中已有的验证库(如 Zod、Joi、class-validator)
- 定义请求体的 Schema
#### 测试文件
- 编写至少 3 个测试用例:成功路径、验证失败、权限检查
- 匹配项目中已有的测试风格
### 5. 验证
- 运行测试命令确认测试通过
- 检查 TypeScript 类型是否正确(如适用)
- 确认新文件被正确导出和注册
### 6. 总结
列出所有创建/修改的文件及其用途。
当用户执行 /api-endpoint POST /users 创建用户注册接口 时,参数通过占位符传入:
| 变量 | 说明 | 示例值 |
|---|---|---|
$ARGUMENTS |
完整参数字符串 | POST /users 创建用户注册接口 |
$ARGUMENTS[0] 或 $0 |
第一个参数 | POST |
$ARGUMENTS[1] 或 $1 |
第二个参数 | /users |
$ARGUMENTS[2] 或 $2 |
第三个参数 | 创建用户注册接口 |
${CLAUDE_SESSION_ID} |
当前会话 ID | abc123 |
${CLAUDE_SKILL_DIR} |
Skill 目录路径 | /project/.claude/skills/api-endpoint |
!command`` 语法在 Skill 内容发送给 Claude 之前执行 Shell 命令,将命令输出替换占位符。这意味着 Claude 看到的是实际的执行结果,而不是命令本身。
这在需要获取实时系统状态时极为强大。例如,创建一个代码审查 Skill:
---
name: smart-review
description: "基于团队标准的智能代码审查"
context: fork
agent: Explore
allowed-tools: Read, Grep, Glob
---
## 当前变更上下文
- 暂存区差异:!`git diff --staged --stat`
- 最近 10 条提交:!`git log --oneline -10`
- 变更文件列表:!`git diff --staged --name-only`
## 审查任务
基于以上变更执行代码审查:
1. 检查函数长度(超过 50 行标记警告)
2. 检查系统边界的错误处理是否完整
3. 检查命名约定是否一致
4. 检查是否引入了重复依赖
5. 检查新增代码路径的测试覆盖
6. 按严重程度分级:阻塞、警告、建议
当此 Skill 运行时,!command`` 中的每个命令立即执行,Claude 收到的是包含实际 Git 数据的最终内容。
对于研究密集型或大量阅读的任务,使用 context: fork 将 Skill 运行在独立的子代理中。这样可以避免中间结果淹没主对话,结果会被摘要后返回。
sequenceDiagram
participant U as 用户
participant M as 主会话
participant S as 子代理
U->>M: /deep-research 微服务架构
M->>S: 创建子代理(独立上下文)
S->>S: 使用 Glob 搜索文件
S->>S: 使用 Grep 搜索关键词
S->>S: 使用 Read 读取分析
S->>S: 整理发现
S->>M: 返回摘要结果
M->>U: 展示研究发现
以下是一个研究型 Skill 的示例:
---
name: deep-research
description: "在代码库中深入研究某个主题"
context: fork
agent: Explore
---
深入研究:$ARGUMENTS
1. 使用 Glob 和 Grep 查找相关文件
2. 阅读并分析代码
3. 识别模式、依赖关系和潜在问题
4. 提供带有具体文件引用的摘要
直接调用测试:在 Claude Code 中输入 /api-endpoint POST /users 创建用户注册接口
自动发现测试:用自然语言描述你的需求,看 Claude 是否自动匹配到你的 Skill
帮我创建一个用户注册的 API 接口
边界情况测试:
- 不传参数执行 /api-endpoint,检查 Skill 是否优雅地处理
- 传入不完整的参数,检查 Skill 是否主动询问
- 在不同类型的项目中测试(Express vs Fastify vs Next.js)
查看已加载的 Skill 列表:在 Claude Code 中输入 /help 可以看到所有可用的 Skill
Skill 未自动触发
- 检查 description 是否包含与你的请求匹配的关键词
- 确认 disable-model-invocation 不是 true
- 尝试在描述中前置核心用例
Skill 参数未正确传入
- 确认使用了正确的占位符语法($ARGUMENTS、$0、$1 等)
- 检查参数之间是否用空格分隔
子代理 Skill 结果不完整
- 检查 allowed-tools 是否限制了必要的工具
- 确认 agent 类型是否匹配任务需求
让我们综合运用前面学到的所有知识,构建一个生产级的 Release Notes 生成器 Skill。
---
name: release-notes
description: "从 Git 历史生成版本发布说明。当用户要求编写 release notes、发布说明或版本变更记录时使用。"
argument-hint: "[version]"
disable-model-invocation: true
---
## 上下文信息
- 最新标签:!`git describe --tags --abbrev=0 2>/dev/null || echo "no-tags"`
- 上次标签以来的提交:!`git log $(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~20")..HEAD --oneline`
- 贡献者:!`git log $(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~20")..HEAD --format='%an' | sort -u`
- 变更文件统计:!`git diff $(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~20")..HEAD --stat`
## 任务
为版本 $ARGUMENTS 编写发布说明。按以下分类组织变更:
### 分类规则
- feat: → 新功能
- fix: → 修复
- perf: → 性能优化
- breaking: → 破坏性变更
- docs: → 文档更新
- refactor: → 代码重构
- chore: → 维护事项
### 输出格式
## [版本号] - 日期
### 破坏性变更
- 具体描述变更内容和迁移方式
### 新功能
- 功能描述(PR #xxx)
### 修复
- 修复描述(PR #xxx)
### 其他
- 其他变更说明
### 贡献者
感谢 @贡献者列表
## 要求
- 面向最终用户撰写,而非开发者
- 每个条目控制在 1-2 句话
- 跳过纯 CI/CD 和依赖更新相关的提交
- 如果没有某个分类的变更,省略该分类
这个 Skill 综合运用了:
- 动态上下文注入(!command` 获取实时 Git 数据)
- **参数传递**($ARGUMENTS接收版本号)
- **禁止自动调用**(disable-model-invocation: true,因为发布是有副作用的操作)
- **参数提示**(argument-hint` 提供自动补全指引)
将 .claude/skills/ 目录提交到版本控制。每个克隆项目的开发者自动获得相同的 Skill 集:
.claude/
├── skills/
│ ├── api-endpoint/
│ │ └── SKILL.md
│ ├── smart-review/
│ │ └── SKILL.md
│ └── release-notes/
│ └── SKILL.md
这是最简单的分发方式,Skill 与它们支持的代码一起版本化。
对于跨项目复用的 Skill,将其打包为插件:
my-team-plugin/
├── skills/
│ ├── deploy/
│ │ └── SKILL.md
│ └── review/
│ └── SKILL.md
插件 Skill 使用 plugin-name:skill-name 命名空间,永远不会与项目或个人 Skill 冲突。
通过托管设置部署组织级 Skill。企业级 Skill 拥有最高优先级,可以强制执行全组织的标准。
graph TB
subgraph 分发渠道
A[项目级<br/>提交到 Git 仓库] --> D[团队成员自动获取]
B[插件级<br/>npm/Git 分发] --> E[跨项目复用]
C[企业级<br/>托管设置] --> F[全组织强制执行]
end
D --> G{优先级合并}
E --> G
F --> G
G --> H[最终生效的 Skill 集合]
Claude Code 自动发现嵌套的 .claude/skills/ 目录。如果你在编辑 packages/frontend/ 中的文件,Claude 也会检查 packages/frontend/.claude/skills/。这意味着 Monorepo 中的每个包都可以维护自己的 Skill 集。
可以通过权限规则精细控制 Claude 可以调用哪些 Skill:
# 仅允许特定 Skill
Skill(api-endpoint)
Skill(review *)
# 拒绝特定 Skill
Skill(deploy *)
要完全禁用所有 Skill,可以在 /permissions 中拒绝 Skill 工具。
disable-model-invocation: trueallowed-tools: Read, Grep, Glob 限制工具范围allowed-tools 精确指定允许的命令模式,如 Bash(npm test) 而非 Bash(*)flowchart TD
A[确定 Skill 需求] --> B[选择存储位置]
B --> C[创建目录结构]
C --> D[编写 Frontmatter 配置]
D --> E[编写指令内容]
E --> F{需要参数?}
F -->|是| G[添加 $ARGUMENTS 占位符]
F -->|否| H{需要动态数据?}
G --> H
H -->|是| I[添加 !`command` 注入]
H -->|否| J{需要隔离执行?}
I --> J
J -->|是| K[设置 context: fork]
J -->|否| L[测试 Skill]
K --> L
L --> M{测试通过?}
M -->|是| N[分享给团队]
M -->|否| O[调试修复]
O --> L
N --> P[纳入版本控制]
掌握了自定义 Skill 的创建之后,以下方向值得进一步探索:
hooks 字段为 Skill 绑定生命周期钩子,实现前置检查和后置处理.claude/agents/ 中定义专用子代理,与 Skill 的 agent 字段配合使用description、合理的文件拆分和工具限制来优化 Token 消耗| 评估维度 | 说明 |
|---|---|
| 难度等级 | 中等偏上,需要理解 YAML 配置和 Markdown 指令编写 |
| 前置知识 | Claude Code 基本操作、Markdown 语法、基本终端操作 |
| 实践性 | 极强,每一步都可以即时验证效果 |
| 适用人群 | 有一定 Claude Code 使用经验的开发者、DevOps 工程师、技术团队负责人 |
| 预计学习时间 | 2-3 小时(含实践) |
| 核心收获 | 能够独立创建、测试、分发生产级自定义 Skill |
| 延伸价值 | 理解 Skill 系统后,可以快速构建团队专属的 AI 辅助工具库 |
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
