本文根据 Anthropic 的 Claude Code 官方文档编译整理,非逐字翻译;功能、字段和版本行为可能继续变化,请以官方原文为准。
Skills 是 Claude Code 的可复用能力单元。你可以把一套经常重复使用的说明、检查清单或多步骤流程写进 SKILL.md,让 Claude 在合适的时候自动加载,也可以通过 /skill-name 主动调用。
它最适合解决这样的场景:同一段要求已经在对话里粘贴了很多次,或者 CLAUDE.md 中的某一节逐渐从“项目事实”变成了一套完整操作流程。
Skills 与 CLAUDE.md 的区别
CLAUDE.md 会作为项目上下文持续存在,更适合记录长期有效的事实、约束和约定;Skill 的正文只有在真正调用时才进入上下文,因此可以容纳更长的参考资料或更具体的流程,而不会让每次对话都承担同样的上下文成本。
旧版自定义命令已经合并到 Skills 体系中。.claude/commands/deploy.md 仍然可以继续使用,并会创建 /deploy 命令;不过 .claude/skills/deploy/SKILL.md 还能携带脚本、模板、示例和更丰富的调用配置,因此更适合新项目。
Claude Code 也自带 /doctor、/code-review、/debug 等 Skills。它们与自定义 Skill 的调用方式相同,但是否允许自动触发取决于各自的配置。
创建第一个 Skill
下面创建一个用于检查当前工作区改动的个人 Skill。个人 Skill 可以在所有项目中使用:
mkdir -p ~/.claude/skills/review-working-tree
然后创建 ~/.claude/skills/review-working-tree/SKILL.md:
---
description: 检查当前 Git 工作区的改动并指出风险。适用于提交前检查、生成改动摘要或确认遗漏测试。
allowed-tools: Bash(git status *) Bash(git diff *)
---
先查看当前状态与 diff,再完成以下工作:
1. 用三条以内的要点总结改动。
2. 标出潜在的兼容性、错误处理和安全风险。
3. 列出缺少的测试或验证步骤。
4. 如果没有改动,直接说明工作区是干净的。
目录名决定命令名,因此可以输入:
/review-working-tree
也可以直接问“帮我检查一下当前改动”。当请求与 description 足够匹配时,Claude 可以自动加载它。
Skills 存放在哪里
存放位置决定了 Skill 的可用范围:
| 范围 | 路径 | 适用对象 |
|---|---|---|
| 企业级 | 由托管设置指定 | 组织内所有用户 |
| 个人 | ~/.claude/skills/<skill-name>/SKILL.md |
当前用户的所有项目 |
| 项目 | .claude/skills/<skill-name>/SKILL.md |
当前仓库 |
| 插件 | <plugin>/skills/<skill-name>/SKILL.md |
启用该插件的环境 |
同名 Skill 的覆盖顺序是:企业级高于个人级,个人级高于项目级。插件 Skill 使用 plugin-name:skill-name 命名空间,因此不会与其他层级直接冲突。
Claude Code 会从启动目录一路向上查找 .claude/skills/,直到仓库根目录;当它开始处理更深层目录中的文件时,也会按需发现嵌套的 Skills。这对 monorepo 很实用:仓库根目录可以放通用规范,每个 package 再提供自己的构建或发布流程。
Skill 文件的修改通常会在当前会话中自动生效。如果会话启动时顶层 Skills 目录还不存在,新建该目录后可能需要重启 Claude Code,文件监听才会覆盖它。
SKILL.md 的组成
一个 Skill 由两部分组成:
- YAML frontmatter:说明它是什么、何时调用以及可以使用哪些能力。
- Markdown 正文:Claude 真正执行的说明。
最小配置只需要正文,但强烈建议提供 description。Claude 会依靠它判断是否应该自动触发 Skill。
常用 frontmatter 字段如下:
| 字段 | 作用 |
|---|---|
name |
在 Skill 列表中显示的名称;个人和项目 Skill 的命令名仍由目录名决定 |
description |
说明用途和触发时机,应把最重要的使用场景放在开头 |
when_to_use |
补充触发条件、常见请求或关键词 |
argument-hint |
在自动补全中提示参数格式 |
arguments |
声明具名的位置参数 |
disable-model-invocation |
设为 true 后只允许用户手动调用 |
user-invocable |
设为 false 后不在 / 菜单中显示,只供 Claude 使用 |
allowed-tools |
在本次调用中预先允许指定工具 |
disallowed-tools |
在 Skill 激活期间移除指定工具 |
model、effort |
为这一次调用指定模型或推理强度 |
context、agent、background |
让 Skill 在独立子代理中运行,并控制代理类型与是否后台执行 |
paths |
只在处理匹配路径时允许自动激活 |
hooks |
配置仅在该 Skill 生命周期内生效的钩子 |
description 不只是说明文字,它直接影响发现效果。写成“帮助处理代码”过于宽泛;写成“审查当前 Git diff,生成提交摘要并指出缺少的测试”更容易在正确的请求上触发。
把正文保持精简
Skill 可以包含参考知识,也可以描述一个明确任务。
参考型 Skill 适合记录 API 约定、代码风格和领域规则,通常与当前对话一起运行。任务型 Skill 则适合部署、提交、迁移或代码生成等有明确步骤的工作,这类操作往往应配合 disable-model-invocation: true,避免在错误时机被自动执行。
复杂 Skill 不需要把所有内容都塞进一个文件,可以使用如下结构:
my-skill/
├── SKILL.md
├── reference.md
├── examples/
│ └── expected-output.md
└── scripts/
└── validate.sh
在 SKILL.md 中说明每个辅助文件的用途以及何时读取。这样 Claude 只在需要时加载详细文档,而脚本可以直接执行,不必把源码全部送入上下文。官方建议让 SKILL.md 保持在 500 行以内。
控制谁来调用
默认情况下,用户和 Claude 都可以调用 Skill:
| 配置 | 用户可调用 | Claude 可自动调用 |
|---|---|---|
| 默认 | 是 | 是 |
disable-model-invocation: true |
是 | 否 |
user-invocable: false |
否 | 是 |
涉及提交、部署、发送消息等有副作用的操作,适合禁止模型自动调用;仅用于补充旧系统背景或内部规范的 Skill,则可以从用户命令菜单中隐藏。
普通会话只会预先加载 Skill 的名称和描述,完整正文会在调用时进入上下文,并在后续对话中继续保留。allowed-tools 等临时授权不同:它们只在调用发生的那一轮有效,下一条用户消息到来时就会清除。
参数与字符串替换
调用 Skill 时可以附带参数。最常用的是 $ARGUMENTS:
---
description: 修复指定的问题并补充测试
disable-model-invocation: true
---
处理问题:$ARGUMENTS
调用 /fix-issue 123 后,123 会替换 $ARGUMENTS。如果需要访问单个位置参数,可以使用 $ARGUMENTS[0]、$ARGUMENTS[1],也可以简写为 $0、$1。在 frontmatter 中声明 arguments 后,还可以使用 $issue 这类具名参数。
Claude Code 还提供一些运行时变量:
${CLAUDE_SESSION_ID}:当前会话 ID。${CLAUDE_EFFORT}:当前推理强度。${CLAUDE_SKILL_DIR}:当前 Skill 所在目录。${CLAUDE_PROJECT_DIR}:当前项目根目录。
其中 ${CLAUDE_SKILL_DIR} 很适合引用随 Skill 一起分发的脚本,避免依赖调用时的工作目录。
注入实时上下文
Skill 可以在正文交给 Claude 之前执行命令,并把输出插入最终提示词。单行命令使用 ! 加反引号:
## 当前仓库
- 状态:!`git status --short`
- 最近提交:!`git log -5 --oneline`
多行命令则可以使用以 ! 标记的代码块。这里发生的是预处理:命令先执行,Claude 看到的是替换后的结果,而不是待执行的命令文本。
动态上下文很强大,也意味着必须认真审查 Skill。对于不希望执行 Skill 内 shell 注入的环境,可以通过 disableSkillShellExecution 设置统一关闭这项能力。
在子代理中运行
把 context 设为 fork,可以让 Skill 在隔离的子代理上下文中执行:
---
description: 深入研究指定模块并返回文件级结论
context: fork
agent: Explore
background: false
---
此时 SKILL.md 正文就是子代理收到的任务。它不会继承主对话历史,因此正文必须包含完整、可执行的目标。参考型规范如果没有具体任务,通常不适合直接放进 forked context。
agent 可以选择内置代理或自定义代理;background 决定当前回合是否等待结果。后台子代理的工具范围会更窄,而且它在主会话检查点之外产生的修改不能依赖 /rewind 撤销,最好继续用 Git 管理可恢复性。
权限与可见性
allowed-tools 是一次调用范围内的预授权,不等同于永久权限。没有列出的工具仍然遵循 Claude Code 的常规权限设置。
还可以在权限规则中控制 Skill:
Skill(review-pr *)
Skill(deploy *)
规则既可以允许也可以拒绝,Skill(name) 表示精确匹配,Skill(name *) 表示允许带参数的前缀匹配。
如果不想修改仓库内共享的 SKILL.md,可以使用 skillOverrides 调整本地可见性。常用状态包括完全启用、只保留名称、仅允许用户调用以及完全关闭。插件提供的 Skills 需要通过插件管理界面单独控制。
如何验证一个 Skill 是否真的有效
“成功触发”不等于“输出正确”。评估时应该把两个问题分开:
- 它是否在应该触发的请求上被调用,并在无关请求上保持安静?
- 调用以后,结果是否稳定符合预期?
准备几条真实请求,在全新会话中分别测试启用和禁用 Skill 的结果。新会话很重要,因为编写 Skill 时留下的上下文可能掩盖说明中的缺口。
团队还可以把项目 Skill 提交进 .claude/skills/,通过插件分发一组 Skills,或用托管设置部署到整个组织。对于复杂 Skill,建议维护固定测试用例,对比通过率、耗时和 token 成本,而不是只凭一次运行的感觉判断质量。
常见问题
Skill 没有触发
- 确认
description包含用户平时真正会说的关键词。 - 检查 Skill 是否出现在可用列表中。
- 尝试让请求更贴近描述,或直接输入
/skill-name。 - 检查 YAML frontmatter。格式错误时,正文可能仍能手动运行,但 Claude 拿不到有效的描述,自然无法正确匹配。
- 使用
--debug查看解析和发现过程。
Skill 触发得太频繁
把 description 写得更具体,明确任务边界和适用对象。如果这个流程只应该手动运行,直接设置 disable-model-invocation: true。
Skill 太多,描述被截断
Claude Code 会把 Skill 名称和描述列表放进上下文,但列表有字符预算。Skill 数量很多时,低频项目的描述可能被缩短。可以用 /doctor 和 /context 查看占用情况,缩短低价值描述,或通过 skillOverrides 把次要项目设为仅保留名称。
实践建议
- 把事实放在
CLAUDE.md,把可执行流程放进 Skill。 - 让一个 Skill 聚焦一个清晰目标,不要把所有项目知识做成一个巨型入口。
- 把关键触发词放在
description开头。 - 对部署、提交和外部消息等操作禁用自动调用。
- 用辅助文件保存长参考资料,用脚本处理确定性工作。
- 在干净会话中做正向和反向测试。
- 始终审查来自不可信仓库的项目 Skills,特别是动态命令和工具授权。