首页 / Claude Code 入门教程 / Skills 技能系统

Claude Code 入门教程

Skills 技能系统

本教程共 34 篇 · 第 21 篇 · 更新于 2026-07-26 · 约 11 分钟阅读

Claude CodeClaude Code 入门教程技能SkillSKILL.mdskill-creator渐进式披露

21. Skills 技能系统

本节目标:搞懂技能(Skill)是什么、和 CLAUDE.md 有啥不一样。学会写 SKILL.md、填 frontmatter、用渐进式披露省上下文,了解动态上下文注入、子代理运行和 skill-creator。学完你能把团队规范、固定流程打包成可复用的技能包,Claude 该用时自动用,不用时不占地方。

技能到底解决什么问题

用 Claude Code 时间长了,你会发现有些事反复做:每次提交代码都要按团队规范写 commit message,每次改 React 组件都要提醒它用你们的设计系统,每次部署都要走一遍固定流程。

这些说明你以前可能是这么处理的:把规范写进 CLAUDE.md,让 Claude 每次都读。问题来了——CLAUDE.md 是常驻上下文,里面的内容每轮对话都占 token。你写进去一份 2000 字的部署流程,哪怕这次只是改个错别字,那 2000 字也一直在那烧钱。

技能(Skill)就是解决这个的。它是一个独立的 Markdown 文件,平时只把名字和一句话描述放在上下文里(几乎不花成本),等你真正需要时才把完整内容加载进来。

打个比方:CLAUDE.md 像你桌上常摊开的笔记本,随时翻得到,但占桌面。技能像书架上的一本手册,你记得它讲什么(描述),要用时才取下来翻开(加载正文)。

技能遵循 Agent Skills 开放标准,同一份技能在 Claude.ai、Claude Code、VS Code Copilot、Cursor 等工具里都能用。Claude Code 在这基础上加了几个增强功能:控制谁来调用、子代理执行、动态上下文注入。

技能的最小结构

一个技能就是一个文件夹,里面必须有一个 SKILL.md

my-skill/
└── SKILL.md   # 唯一必需的文件

SKILL.md 分两部分:开头的 YAML frontmatter(夹在两个 --- 之间)告诉 Claude 这个技能是干嘛的、什么时候用;后面的 Markdown 正文是 Claude 调用时要遵循的具体说明。

最小的一个 SKILL.md 长这样:

---
name: python-naming
description: 团队 Python 命名规范。用户要求重构、审查或编写 Python 代码时使用。
---

## 指令
1. 所有内部辅助函数必须以 `_internal_` 前缀命名。
2. 发现不符合此规则的代码,主动提出修改建议。

## 示例
- 正确:`def _internal_calculate_risk():`
- 错误:`def _calculate_risk():`

目录名变成你输入的命令名。这个技能放在 .claude/skills/python-naming/ 下,你就能用 /python-naming 直接调用它。Claude 也会在你说「帮我写个 Python 函数」时自动加载它。

Note

.claude/commands/ 下的旧命令文件依然有效,行为和技能一样。但技能支持更多功能(支持文件、调用控制、自动加载),新项目建议直接用 .claude/skills/

技能放在哪里

存放位置决定谁能用到它:

位置路径谁能用
企业托管设置分发组织内所有用户
个人~/.claude/skills/<技能名>/SKILL.md你的所有项目
项目.claude/skills/<技能名>/SKILL.md仅此项目
插件<插件>/skills/<技能名>/SKILL.md启用该插件的地方

同名技能的优先级:企业 > 个人 > 项目。任何一级的技能也会覆盖同名的捆绑技能。比如你在项目的 .claude/skills/ 里放一个 code-review,就会替掉内置的 /code-review

插件技能用 插件名:技能名 命名,不会和其他级别冲突。

Tip

项目技能适合提交到 Git,团队共享。个人技能放 ~/.claude/skills/,跨项目复用,不进版本控制。

嵌套目录的技能

Monorepo 里每个包可以有自己的技能。Claude Code 会从当前目录往上找到仓库根,沿途的 .claude/skills/ 都加载。当你编辑 packages/frontend/ 里的文件时,packages/frontend/.claude/skills/ 里的技能也会按需出现。

如果嵌套技能和根目录的同名,两个都保留:根目录的用 /deploy,嵌套的用 /apps/web:deploy 这种限定名。Claude 会根据正在处理的文件自动选合适的那个。

实时变更检测

Claude Code 监视技能目录的文件变化。在 ~/.claude/skills/、项目 .claude/skills/ 里增删改技能,当前会话立即生效,不用重启。只有会话启动时不存在的顶级 skills 目录才需要重启才能识别。

frontmatter 字段参考

除了正文,SKILL.md 顶部的 YAML frontmatter 可以配置技能行为。所有字段都可选,但强烈建议写 description

---
name: my-skill
description: 这个技能做什么、什么时候用
disable-model-invocation: true
allowed-tools: Read Grep
---

常用字段:

字段作用
name显示名称,默认用目录名。仅小写字母、数字、短横线,最长 64 字符
description技能功能和使用时机,Claude 靠它判断是否自动加载。把关键用例放前面,组合文本上限 1536 字符
when_to_use额外的触发上下文,比如触发短语或示例请求,追加到 description 后
argument-hint自动补全时显示的参数提示,如 [issue-number]
arguments命名位置参数,用于 $name 替换
disable-model-invocationtrue 禁止 Claude 自动调用,只能你手动 /name 触发
user-invocablefalse/ 菜单隐藏,只让 Claude 用
allowed-tools技能激活时 Claude 可免授权使用的工具
disallowed-tools技能激活时从工具池移除的工具
model技能激活时使用的模型,覆盖当前轮,下个提示恢复
effort工作量级别:low/medium/high/xhigh/max
contextfork 在子代理上下文中运行
agent配合 context: fork 使用的子代理类型
hooks限定于此技能生命周期的钩子
pathsglob 模式,限制只处理匹配文件时才激活
shell内联 shell 命令用的 shell,bash(默认)或 powershell
Warning

name 字段只影响显示标签,不改变你 / 后输入的命令名。命令名来自目录名(普通技能)或文件名(旧命令)。唯一例外是插件根 SKILL.md,它没有目录名可用,这时 name 才决定命令名。

控制谁来调用技能

默认情况下,你和 Claude 都能调用任何技能。你可以 /技能名 直接调,Claude 也会在对话相关时自动加载。两个 frontmatter 字段帮你收紧控制:

disable-model-invocation: true:只有你能调。用于有副作用的工作流,比如 /deploy/commit/send-slack。你不想让 Claude 因为代码看起来准备好了就自己决定部署。

user-invocable: false:只有 Claude 能调。用于不能当命令操作的背景知识。比如一个 legacy-system-context 技能解释旧系统怎么运作,Claude 相关时该知道,但 /legacy-system-context 对你来说没意义。

frontmatter你能调Claude 能调何时加载
默认描述常在上下文,调用时加载完整内容
disable-model-invocation: true描述不在上下文,你调用时才加载
user-invocable: false描述常在,调用时加载完整内容

渐进式披露:省上下文的关键

技能最聪明的地方是渐进式披露(Progressive Disclosure),分三层加载:

  1. 第一层:元数据。启动时只把每个技能的 namedescription 放进系统提示,让 Claude 知道有啥可用。这部分始终在上下文里,但很短。
  2. 第二层:核心指令。Claude 判断任务相关后,才读取 SKILL.md 正文,加载完整说明。
  3. 第三层:资源文件。只在真正需要时才读取技能目录里的参考文档、示例,或执行脚本。

对比一下 CLAUDE.md:它所有内容都在第一层常驻。技能把大部分内容推到第二、三层,按需加载,所以长参考资料在你需要它之前几乎零成本。

多文件技能

复杂技能可以拆成多个文件,让 SKILL.md 聚焦要点:

my-skill/
├── SKILL.md          # 主说明(必需)+ 导航
├── reference.md      # 详细 API 文档,按需加载
├── examples.md       # 使用示例,按需加载
└── scripts/
    └── helper.py     # 工具脚本,执行不加载

SKILL.md 里引用它们,让 Claude 知道每个文件装了什么、什么时候读:

## 额外资源
- 完整 API 细节见 [reference.md](reference.md)
- 使用示例见 [examples.md](examples.md)
Tip

SKILL.md 控制在 500 行以内。详细参考资料挪到单独文件,按需加载。

给技能传参数

调用技能时可以传参数,用 $ARGUMENTS 占位符接收:

---
name: fix-issue
description: 修复 GitHub issue
disable-model-invocation: true
---

修复 GitHub issue $ARGUMENTS,遵循我们的编码规范。

1. 读取 issue 描述
2. 理解需求
3. 实现修复
4. 写测试
5. 创建 commit

运行 /fix-issue 123,Claude 收到的就是「修复 GitHub issue 123,遵循我们的编码规范…」。

按位置访问单个参数用 $ARGUMENTS[0] 或简写 $0

---
name: migrate-component
description: 把组件从一个框架迁移到另一个
---

把 $0 组件从 $1 迁移到 $2。
保留所有现有行为和测试。

运行 /migrate-component SearchBar React Vue$0 变成 SearchBar$1 变成 React$2 变成 Vue

有用的内置变量

变量含义
$ARGUMENTS所有参数
$ARGUMENTS[N] / $N第 N 个参数(0 基索引)
$namearguments 里声明的命名参数
${CLAUDE_SESSION_ID}当前会话 ID,适合日志、临时文件
${CLAUDE_EFFORT}当前工作量级别
${CLAUDE_SKILL_DIR}技能所在目录,引用捆绑脚本
${CLAUDE_PROJECT_DIR}项目根目录

${CLAUDE_SKILL_DIR} 特别有用,无论技能装在个人、项目还是插件级别,它都正确解析到技能自己的目录,方便引用捆绑的脚本。

动态上下文注入

有时候你想让技能基于实时数据工作,比如总结当前 git diff。!`命令` 语法在技能内容发给 Claude 之前先执行 shell 命令,把输出插进去:

---
description: 总结未提交的更改并标记风险。
---

## 当前更改

!`git diff HEAD`

## 指令

用两三个要点总结上面的更改,然后列出你注意到的风险,比如缺少错误处理、硬编码值、需要更新的测试。如果 diff 为空,说明没有未提交的更改。

Claude 看到的不是 !git diff HEAD“ 这个命令,而是它的实际输出。这是预处理,不是 Claude 执行的。

多行命令用 ! 围栏代码块:

## 环境
```bash
node --version
npm --version
git status --short
```
Warning

内联形式只在 ! 出现在行首或紧跟空白后才识别。KEY=!cmd“ 这种写法会被当成字面文本,命令不会跑。

在子代理里运行技能

context: fork,技能就在隔离的子代理上下文里跑,看不到你的对话历史:

---
name: deep-research
description: 彻底研究某个主题
context: fork
agent: Explore
---

彻底研究 $ARGUMENTS:

1. 用 Glob 和 Grep 找相关文件
2. 读取并分析代码
3. 带具体文件引用总结发现

运行时:创建新的隔离上下文 → 子代理收到技能内容作为提示 → agent 字段决定执行环境(ExplorePlangeneral-purpose 或自定义子代理)→ 结果摘要返回主对话。

Warning

context: fork 只适合有明确任务的技能。如果你的技能只是「使用这些 API 约定」之类的指南,子代理收到指南但没有可执行任务,会空手而归。

内置捆绑技能

Claude Code 自带一组捆绑技能,每个会话都可用(除非禁用),包括:

  • /doctor:诊断配置问题
  • /code-review:代码审查
  • /batch:批量处理
  • /debug:调试
  • /loop:循环任务
  • /claude-api:Claude API 相关

还有三个协同工作来运行和验证你的应用:

技能作用
/run启动并驱动应用,看改动是否生效
/verify构建并运行应用,确认代码改动按预期工作
/run-skill-generator/run/verify 怎么构建启动你的项目

捆绑技能是基于提示的:它们给 Claude 详细说明,让 Claude 用自己的工具去编排工作,而不是直接执行固定逻辑。需要 v2.1.145 或更高版本。

技能内容生命周期

调用技能时,SKILL.md 渲染后的内容作为一条消息进入对话,并在会话剩余部分保持在那里。Claude Code 不会后续轮次重新读技能文件,所以要把应该贯穿整个任务的指导写成常设说明。

当 Claude 重新调用一个技能且内容没变,Claude Code 只加一句「该技能已加载」的说明,不会塞第二份副本。如果内容变了(参数变了或动态上下文产生了新输出),才会再附加完整内容。

自动压缩时,Claude Code 在总结后重新附加每个技能的最近一次调用,保留前 5000 token,所有重新附加的技能共享 25000 token 预算。从最近调用的开始填,所以一次会话调了太多技能,旧的可能会被压缩掉。

Tip

如果某个技能在第一个响应后好像不再影响行为,内容其实还在,只是模型选了别的路子。强化 description 和说明,或用钩子(Hook)强制行为。压缩后想恢复,重新调用一次就行。

用 skill-creator 造技能

写技能和写代码一样,需要迭代。Anthropic 官方提供了 skill-creator 插件,在 Claude Code 里自动化整个创建-测试-优化循环。

从官方市场安装:

/plugin install skill-creator@claude-plugins-official

装完运行 /reload-plugins 让当前会话能用,然后让 Claude 评估或创建技能,比如 evaluate my summarize-changes skill with skill-creator

skill-creator 帮你做这些:

  • 需求梳理:通过对话问清楚技能做什么、何时触发、输出格式
  • 起草 SKILL.md:根据你的回答生成初稿和参考文件
  • 测试用例:在技能目录的 evals/evals.json 存提示、输入文件、预期行为
  • 隔离运行:每个测试用例起一个子代理,从干净上下文跑,记录 token 和耗时
  • 评分:检查每个断言,把通过/失败写进 grading.json
  • 基准对比:聚合通过率、时间、token,有技能 vs 无技能对比,放进 benchmark.json
  • 版本比较:两个版本的技能盲测 A/B,确认改动是真改进才提交
  • 描述调整:生成应触发和不应触发的提示,测命中率,描述不准时提议修改

整个流程是个循环:想清楚需求 → 起草 SKILL.md → 设计测试 → 跑测试 → 看报告 → 改 SKILL.md → 重复。

Note

如果 Claude Code 报告找不到该插件,运行 /plugin marketplace update claude-plugins-official 刷新,或 /plugin marketplace add anthropics/claude-plugins-official 添加后重试。

技能 vs CLAUDE.md vs 子代理

这三个容易混,这里我踩过坑,帮你们理清楚:

维度CLAUDE.md技能(Skill)子代理(Subagent)
加载时机会话开始就全量加载描述常在,正文按需加载委托时才创建独立上下文
上下文成本每轮都占几乎零,调用时才占主对话只收摘要
适合放什么项目事实、约定、常驻规则可复用流程、专项知识、有副作用的操作探索、审查、调试等脏活
触发方式自动自动或手动 /nameClaude 自动委托
隔离性无(内联)或有(context: fork有,独立上下文

简单记:CLAUDE.md 写「这个项目是啥、有啥约定」,技能写「怎么做某件具体事」,子代理是「让另一个 AI 去干这件事,只把结论给我」。

技能不触发怎么办

如果 Claude 该用技能却没用:

  1. 检查 description 是否包含用户会自然说的关键词
  2. 问 Claude「What skills are available?」确认技能被识别
  3. 把请求改得更贴近描述
  4. 如果技能是用户可调用的,直接 /技能名 手动触发

frontmatter YAML 格式不对的话,Claude Code 会加载技能正文但元数据为空,/技能名 还能用,但 Claude 没有 description 去匹配自动触发。用 --debug 运行能看到解析错误。

技能触发太频繁

反过来,如果 Claude 老在不该用的时候用:

  1. 把 description 写得更具体,加上限定条件
  2. 只想手动触发就加 disable-model-invocation: true

描述被截断

技能列表有字符预算(按模型上下文窗口的 1% 扩展)。技能太多时,Claude Code 会从你最不常调用的开始砍描述。运行 /doctor 看列表的上下文成本和最大贡献者。

要释放预算:在 skillOverrides 设置里把低优先级技能设成 "name-only"(只列名字不显示描述)。或者在源处精简 descriptionwhen_to_use,把关键用例放前面。

共享技能

技能按受众分几种分发方式:

  • 项目技能:把 .claude/skills/ 提交到版本控制,团队拉代码就有
  • 插件:在插件里建 skills/ 目录,通过插件市场分发
  • 托管:通过托管设置在企业内部署

技能遵循开放标准,你写的技能不只能给自己用。社区也有现成的技能集合,比如 anthropics/skills 仓库里有 PDF、PPT、Excel 等文档处理技能。

把那个仓库注册成插件市场:

/plugin marketplace add anthropics/skills

然后装文档技能集:

/plugin install document-skills@anthropic-agent-skills

装完重启 Claude Code,跟 Claude 说「用 PDF 技能提取这个文件的表单字段」就能调用 /document-skills:pdf 了。