首页 › tutorials › 从零创建自定义Skill

Claude Code Skills 开发实战 —— 从零创建一个自定义 Skill

概览

Claude Code 的 Skills 系统是其最强大的扩展机制之一。一个 Skill 本质上是一个 Markdown 文件,它定义了一套可复用的指令集,让你无需每次都从零开始写 Prompt,只需输入 /skill-name 即可让 Claude 精确执行预设工作流。

本教程将带你从空白目录开始,逐步构建一个完整的、生产可用的自定义 Skill。你将深入理解 Skill 的文件结构、YAML Frontmatter 的每一个字段、参数传递机制、动态上下文注入、子代理执行模式,以及如何将 Skill 分享给团队。

Skill 在 Claude Code 扩展体系中的位置

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

前置条件

在开始之前,确保你具备以下条件:

  1. Claude Code 已安装并可用:在终端中运行 claude --version 确认安装正常
  2. 一个工作项目目录:任何有 Git 仓库的项目都可以,本教程使用一个 Next.js 项目作为示例
  3. 基本的 Markdown 知识:Skill 文件使用 Markdown 编写
  4. 对 YAML Frontmatter 的基本了解:虽然不是必须的,但有助于理解配置选项
  5. 终端操作能力:需要创建目录和文件

第一步:理解 Skill 的存储位置与作用域

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 都需要一个独立目录,其中必须包含 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 会按需读取。

第三步:编写 SKILL.md 的 YAML Frontmatter

Frontmatter 是 SKILL.md 文件顶部的 YAML 配置块,控制 Skill 的行为方式。虽然所有字段都是可选的,但 description 强烈建议填写。

最小可用的 Frontmatter

---
name: api-endpoint
description: "根据用户描述生成 RESTful API 端点,包含路由、控制器、验证和测试"
---

完整的 Frontmatter 参考

---
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 否 是

第四步:编写 Skill 的指令内容

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 数据的最终内容。

第六步:在子代理中运行 Skill

对于研究密集型或大量阅读的任务,使用 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. 提供带有具体文件引用的摘要

第七步:测试与调试 Skill

测试流程

  1. 直接调用测试:在 Claude Code 中输入 /api-endpoint POST /users 创建用户注册接口

  2. 自动发现测试:用自然语言描述你的需求,看 Claude 是否自动匹配到你的 Skill 帮我创建一个用户注册的 API 接口

  3. 边界情况测试: - 不传参数执行 /api-endpoint,检查 Skill 是否优雅地处理 - 传入不完整的参数,检查 Skill 是否主动询问 - 在不同类型的项目中测试(Express vs Fastify vs Next.js)

  4. 查看已加载的 Skill 列表:在 Claude Code 中输入 /help 可以看到所有可用的 Skill

常见问题排查

Skill 未自动触发 - 检查 description 是否包含与你的请求匹配的关键词 - 确认 disable-model-invocation 不是 true - 尝试在描述中前置核心用例

Skill 参数未正确传入 - 确认使用了正确的占位符语法($ARGUMENTS、$0、$1 等) - 检查参数之间是否用空格分隔

子代理 Skill 结果不完整 - 检查 allowed-tools 是否限制了必要的工具 - 确认 agent 类型是否匹配任务需求

第八步:实战案例 —— 构建完整的 Release Notes 生成器

让我们综合运用前面学到的所有知识,构建一个生产级的 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` 提供自动补全指引)

第九步:将 Skill 分享给团队

方式一:项目级共享(推荐)

将 .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 集合]

Monorepo 支持

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 工具。

安全最佳实践

  1. 有副作用的操作(部署、删除、发布)始终设置 disable-model-invocation: true
  2. 只读分析任务使用 allowed-tools: Read, Grep, Glob 限制工具范围
  3. 敏感操作通过 allowed-tools 精确指定允许的命令模式,如 Bash(npm test) 而非 Bash(*)
  4. 企业合规通过企业级 Skill 强制执行安全标准

完整 Skill 开发流程总结

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 的创建之后,以下方向值得进一步探索:

  1. Skill 与 Hooks 的协同:通过 hooks 字段为 Skill 绑定生命周期钩子,实现前置检查和后置处理
  2. Skill 与 MCP Server 的集成:在 Skill 中调用 MCP 工具,将外部服务能力融入工作流
  3. 多 Skill 编排:构建 Skill 之间的调用链,实现复杂的多步骤自动化
  4. 自定义 Subagent:在 .claude/agents/ 中定义专用子代理,与 Skill 的 agent 字段配合使用
  5. Skill 性能优化:通过精确的 description、合理的文件拆分和工具限制来优化 Token 消耗

训练营适用性评估

评估维度 说明
难度等级 中等偏上,需要理解 YAML 配置和 Markdown 指令编写
前置知识 Claude Code 基本操作、Markdown 语法、基本终端操作
实践性 极强,每一步都可以即时验证效果
适用人群 有一定 Claude Code 使用经验的开发者、DevOps 工程师、技术团队负责人
预计学习时间 2-3 小时(含实践)
核心收获 能够独立创建、测试、分发生产级自定义 Skill
延伸价值 理解 Skill 系统后,可以快速构建团队专属的 AI 辅助工具库

参考来源

  1. Extend Claude with skills - Claude Code 官方文档 — Skill 系统的权威参考,包含完整的 Frontmatter 字段说明和高级模式
  2. How to Build Claude Code Skills That Actually Work - DEV Community — 实战导向的 Skill 构建教程,包含多个实用示例和最佳实践
  3. Claude Code Skills Tutorial: Custom Slash Commands and Automations Guide - SupaLaunch — 从入门到高级的完整指南,涵盖动态上下文注入和子代理模式
  4. How to Build and Deploy a Custom Claude Code Plugin - LinuxBeast — 插件构建与分发流程的详细教程
  5. The Complete Guide to Building Skills for Claude - Anthropic 官方 PDF — Anthropic 发布的 Skill 构建完整指南

[!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 等场景全覆盖。

51学通信知识星球海报-扫码加入