×−+
Skills 技能第 5 课 · Claude Code 教程
第 5 课 · SKILLS

Skills:给 Claude 一本
随用随取的操作手册

你是不是每次都要跟 Claude 重复一遍"周报要这么写""代码要那样审"?把这些套路写成一个 Skill,Claude 会在需要的时候自己翻开它;不需要的时候,它几乎不占地方。

约 60 分钟 13 节 · 8 个动手练习 章末测验 改编自 luongnv89/claude-howto(MIT)
记住这个画面。Claude 平时只看得见书脊,也就是每个 skill 的名字和一句简介。要用哪本,才把哪本抽出来读。整个 Skills 的设计都是围绕这一点展开的。 正在翻阅:—
入门先用起来 原理弄懂为什么 实战动手练 深入高级用法与避坑

时间紧就先看"入门"和"实战";"原理"和"深入"决定你能不能把 skill 写好。

01入门

什么是 Skill?

把 Claude 想成一位刚入职、能力很强但不了解你们规矩的新同事。

要让这位新同事干好活,你会给他准备几样东西。Claude Code 里正好各有对应:

员工守则,贴在工位上每天上班都会看一遍,所以得短。
CLAUDE.md
书架上的操作手册平时只看书脊,需要时才抽出来照着做。可以很厚,还能夹模板和工具。
Skill
门禁卡和系统账号让他能进入公司的 Jira、数据库等其他系统。
MCP
找个同事帮忙交出去一个任务,对方单独干完,回来只汇报结论。
Subagent
自动打卡机事件一发生就自动执行,不需要任何人记得。
Hook

一句话定义

一个 Skill 就是一个文件夹,里面至少有一个 SKILL.md。文件开头几行告诉 Claude"我是谁、什么时候该用我",后面写具体怎么做。文件夹里还可以放模板、参考资料和脚本。

整篇教程都用这个例子:周报助手
weekly-report/
├── SKILL.md            # 必需:说明书本体
├── templates/
│   └── report.md       # 可选:周报模板
└── scripts/
    └── stats.py        # 可选:统计改动量的脚本
为什么不直接写进 CLAUDE.md?

CLAUDE.md 的内容每次对话都会全部读一遍。把十几份操作手册都塞进去,Claude 每次开工都要先读完几万字,又慢又占地方,而且大部分时候根本用不上。Skill 解决的正是这个问题,第 5 节会用数字说明。

02入门

选对工具:什么时候该用 Skill

Skill 不是万能的。下面 6 个真实需求,你觉得各该用哪个?点一下你的答案。

对照表

什么时候进入上下文谁来触发最适合
CLAUDE.md每次对话开始时,全文自动简短、始终适用的规则
Skill平时只有名字和简介;用到时才加载全文Claude 按简介判断,或你输入 /名字可复用的流程、模板、专业知识
Subagent在自己独立的上下文里运行Claude 委派,或你指定会产生大量中间信息的大任务
MCP平时只有工具名字,用到时才取完整说明(第 7 课)Claude 调用工具时连接外部系统和数据
Hook平时不占上下文,只有钩子主动返回的内容才会进事件发生时自动执行必须 100% 执行的动作
它们可以组合

最常见的搭配是 MCP + Skill:MCP 负责让 Claude 连上 Jira,Skill 负责教它"我们团队怎么写工单"。前者给能力,后者给方法。

03入门

解剖一份 SKILL.md

点击带颜色标记的行,检查器会解释这一行的作用。一共 11 处,建议全部点一遍。

SKILL.md — weekly-report
配置区(frontmatter)正文动态内容
已查看 0 / 11

可以把它看成两部分:

  • 配置区(两条 --- 之间):告诉 Claude Code 什么时候用、怎么用这个 skill。
  • 正文:告诉 Claude 具体怎么做。就是普通的 Markdown,像写给同事的说明一样写就行。
04入门

放在哪里,决定了谁能用

同一份 SKILL.md,放在不同文件夹,作用范围完全不同。点不同的位置看看区别。

skills
位置

重名了听谁的?

企业托管› 个人~/.claude› 项目.claude› 内置

排在前面的优先。比如你的个人目录和项目目录里各有一个 weekly-report,生效的是个人目录里那个。你自己写的 skill 也会覆盖 Claude Code 内置的同名 skill。

插件里的 skill 不参与抢名字,调用时永远带插件名前缀,比如 /my-plugin:weekly-report,所以不会和别人的冲突。

小白最常踩的坑

文件名必须是 SKILL.md(全大写),并且放在以 skill 命名的子文件夹里:.claude/skills/weekly-report/SKILL.md ✅,.claude/skills/SKILL.md ❌。

05原理

渐进式加载:为什么装 100 个也不怕

这是 Skills 最核心的设计,官方叫 progressive disclosure。Skill 的内容分三层,按需逐层加载。

L1 · 元数据

书脊

name + description。启动时就加载,并且一直都在。

≈ 100 token / 个
L2 · 正文

翻开手册

SKILL.md 的正文。skill 被触发时才加载。

建议 < 5,000 token
L3 · 附属文件

翻到附录

模板、参考资料、脚本。执行到那一步才去读。脚本只有输出进上下文。

几乎不设上限

动手算一笔账

拖动滑块设置"装了多少个 skill",再依次点下面 4 个步骤,看上下文怎么增长。对照组是"把所有手册都写进 CLAUDE.md"。

用 Skills0
全写进 CLAUDE.md(每个手册按 4,000 token 估算;上限 200k)0
050k100k150k200k
L1 名字+简介 L2 正文 L3 附属文件 脚本输出 CLAUDE.md 全文

数字是为了说明量级的示意值,实际大小取决于你写了多少内容。

这对写 skill 意味着什么

① description 要写好,因为 L1 是 Claude 决定要不要加载的唯一依据(第 7 节)。② SKILL.md 保持精简(建议 500 行以内),大块资料拆到附属文件里。③ 能用脚本算的就交给脚本,脚本源码再长也不占上下文。

06原理

两种触发方式,以及怎么管住它

Skill 可以由 Claude 自己决定加载,也可以由你手动调用。两个开关控制谁有权触发。

方式怎么发生例子
自动你说的话和某个 skill 的 description 对上了,Claude 决定加载它"帮我写下这周的周报"
手动输入 / 加 skill 名字,后面可以跟参数/weekly-report 只写后端

试试这两个开关

disable-model-invocation: true禁止 Claude 自动调用,只能由你手动调用
user-invocable: false从 / 菜单里隐藏,只让 Claude 自动调用
你能用 / 调用
Claude 能自动加载
出现在 / 菜单
有副作用的 skill 一定要关掉自动触发

部署、提交代码、发消息这类操作,一旦 Claude "觉得你大概想要"就自己跑起来,后果可能很严重。给它们加上 disable-model-invocation: true,只有你亲手输入 /deploy 才会执行。

07原理

写好 description:决定 skill 用不用得上

很多人写的 skill "不灵",问题几乎都出在这一行。

先站在 Claude 的角度看看。启动后,它手里关于 skill 的信息大致就是下面这么一份清单:

Claude 的视角(示意)

用户说"帮我汇总一下这周干了啥"时,Claude 只能拿这句话去和每行简介比对。简介写得越具体、越贴近用户的原话,就越容易被选中。

二选一:哪个更好?

写法五要点

  1. 先写做什么,再写什么时候用。例如"根据 git 提交生成周报。当用户提到周报……时使用。"
  2. 放进用户真会说的词,中英文都放:周报、本周总结、weekly report。
  3. 具体胜过笼统。点名文件类型和场景:".xlsx 表格"比"文档"好。
  4. 一个 skill 只做一件事。"PDF 表单填写"比"文档处理"更容易被准确触发。
  5. 重要的放前面。description 和 when_to_use 合计超过 1,536 个字符的部分会被截掉。

给你的 description 做个体检

载入示例:

这个体检只是按上面五个要点做的简单规则比对,方便你自查,不代表 Claude 实际的判断方式。

装得太多也会"挤"

所有 skill 的简介加起来有一个总预算(约为上下文窗口的 1%)。超出后,每个 skill 的名字仍然可见,但最少用到的那些会先被去掉简介,触发就会变差。运行 /doctor 可以看到这份清单占了多少上下文、谁占得最多。

08实战

终端演练:看 Skill 从创建到生效

点"下一步"一步步回放。回放完可以在底部输入框自己打字试试。

my-app — claude — 90×28
>

终端画面为教学示意,与真实 Claude Code 的界面细节可能略有不同,但流程和原理一致。

09实战

参数与动态上下文

让同一个 skill 能适应不同的输入,并且每次都用上最新的数据。

参数替换游乐场

选一种写法,在命令行里改改参数,下方或旁边会实时显示 Claude 最终收到的内容。

/
SKILL.md 里写的
Claude 收到的
写法替换成
$ARGUMENTS命令后面的全部文字
$0 $1 …(或 $ARGUMENTS[0])按空格拆开后的第 1、2… 个参数(从 0 开始数;带空格的参数用引号包起来);没传到的序号占位符会原样留在正文里
$名字在 frontmatter 里用 arguments: [a, b] 声明过的具名参数
${CLAUDE_SKILL_DIR}这个 skill 所在文件夹的路径
${CLAUDE_SESSION_ID}当前会话 ID
\$1.00$ 后面紧跟数字、ARGUMENTS 或参数名时(比如价格 $1.00),前面加反斜杠才能保留字面的 $;其他地方的 $ 不用转义

动态上下文:!`命令`

在正文里写 !`命令`,Claude Code 会在把 skill 交给 Claude 之前先执行命令,再把输出原地替换进去。Claude 从头到尾看不到命令本身,只看到结果。

用哪个 shell默认 bash;在 frontmatter 写 shell: powershell 可改用 PowerShell
权限注入的命令不会弹窗问你。ls、git log 这类只读命令直接运行;其他命令要先被权限规则允许,或写进 allowed-tools,否则(auto 模式除外)整个调用会中止
命令失败非 0 退出码会让整个 skill 调用中止。预料之中的失败,末尾加 || true(grep、git diff 返回 1 不算失败)
超时每条命令 2 分钟
多行写法用 ```! 开头的代码块,里面每行一条命令
关掉在 settings.json 中设置 "disableSkillShellExecution": true。命令会被替换成一行"已被策略禁用"的提示(内置和企业托管的 skill 不受影响)
10实战

动手:生成你的第一个 Skill

填写表单,预览窗口会实时生成 SKILL.md。完成后可以拷贝或下载,放到指定文件夹就能用。

基本信息
调用方式
只允许我手动调用disable-model-invocation · 部署、提交这类有副作用的操作建议打开
在 / 菜单中显示user-invocable · 纯背景知识类 skill 可以关掉
在独立子代理中运行context: fork · 适合会产生大量中间内容的任务
权限与正文
保存位置
作用范围
操作系统
SKILL.md

安装:先建文件夹,再把下载的 SKILL.md 放进去。

终端

11深入

高级字段与生命周期

会用只需要 name 和 description。要把 skill 写得又稳又省,还得懂下面这些。

Skill 加载后会待多久?

很多人以为 skill 用完就"退出"了。其实它的内容会一直留在这次对话里,但它授予的权限只持续一轮:

第 1 轮
/weekly-report
第 2 轮
"再短一点"
第 3 轮
"加上数据"
自动压缩后
skill 正文
一直在上下文里
保留前 5,000 token
allowed-tools
本轮有效
  • 写成"长期守则",而不是"一次性步骤"。第 2 轮你说"再短一点"时,Claude 仍然会遵守 skill 里的规则。
  • 权限在你发下一条消息时清除。想再次免确认,就重新调用一次 skill。
  • 对话自动压缩时,每个 skill 只保留前 5,000 token,所有 skill 合计最多 25,000。调用过很多 skill 时,较早的可能整个被丢掉,需要时再调用一次。最重要的规则要写在前面。

在子代理里运行:context: fork

SKILL.md
---
name: deep-research
description: 深入调研代码库中的某个问题
context: fork
agent: Explore
---

调研 $ARGUMENTS:
1. 找到相关文件
2. 阅读并分析
3. 只汇报结论和关键文件路径

skill 会交给一个拥有独立上下文的子代理去执行。它翻了几百个文件,主对话里也只会多出最后那份结论。默认在后台运行,设置 background: false 则等它跑完再继续。注意:在后台跑的 fork 型 skill 改的文件不进检查点,/rewind 撤不回(第 3 课),要用 git 回退。

子代理看不到之前的对话

fork 出去的子代理不会带上主对话的历史,所以正文必须自成一体。不要写"按刚才说的做"这类依赖上文的话。

名字里虽然有 fork,但它和第 8 课讲的"fork 当前对话"不是一回事:那种会带上整段对话,context: fork 不会。

只在特定文件上生效:paths

---
name: react-conventions
description: 本项目 React/TypeScript 组件的写法约定
paths: "src/**/*.tsx"
---

加了 paths 后,只有在处理匹配的文件时,Claude 才会考虑自动加载这个 skill。这样可以减少误触发。

全部 frontmatter 字段

字段作用分类

如果要把 skill 上传到 claude.ai 或通过 API 使用,只支持 name、description、license、compatibility、metadata、allowed-tools 这几个字段。

12深入

安全与排错

Skill 能执行命令、能预批准工具。安装别人的 skill,等于在你的电脑上运行别人的代码。

安装前检查清单

通读文件夹里的所有文件,不只是 SKILL.md
重点看 !`…` 注入命令和 scripts/ 里的脚本,它们会在你的电脑上运行
留意 allowed-tools 预批准了什么。Bash(*) 这种全放开的要警惕。项目里 skill 的 allowed-tools 不受"信任此文件夹"对话框限制,拉下陌生仓库后先看看 .claude/skills/
会从网上下载内容再执行的 skill,风险最高

想关掉你自己、项目和插件里 skill 的命令注入,可以在 settings.json 里加上:

~/.claude/settings.json
{
  "disableSkillShellExecution": true
}

也可以用权限规则禁止某个 skill,例如 "deny": ["Skill(deploy *)"]。

常见问题

Claude 就是不用我的 skill
  1. 运行 /skills,确认它确实被加载了。
  2. 检查 frontmatter 格式:--- 必须在第一行,缩进用空格不用 Tab。YAML 写错时,skill 仍会加载,但所有字段都会失效。运行 claude plugin validate .claude/skills 能找出写错的 SKILL.md。
  3. description 里有没有用户真会说的词?回到第 7 节做个体检。
  4. 是不是设置了 disable-model-invocation: true,或者 paths 没有匹配到当前文件?
  5. 先用 /名字 手动调用,确认内容本身没问题。
skill 在不该出现的时候被触发
把 description 写得更具体,缩小适用范围;或者加上 paths 限定文件类型;有副作用的直接改成 disable-model-invocation: true。
调用时报错,skill 没执行
多半是某条 !`命令` 返回了非 0 退出码,或者它没被放行(不是只读命令,也不在 allowed-tools 里)。在终端里单独运行这条命令看看;预料之中的失败末尾加 || true;Windows 上检查是否需要 shell: powershell。
装了很多 skill,有些好像"消失"了
所有 skill 简介的总预算约为上下文窗口的 1%,超出后,最少用到的 skill 会先被去掉简介。运行 /doctor 看清单占了多少、谁最占地方;运行 /skill-doctor 找出从没用过的 skill 关掉;或者精简 description。
我改了 SKILL.md,要重启吗?
一般不用。Claude Code 会监视 ~/.claude/skills/ 和项目 .claude/skills/,修改会在当前会话里生效。两个例外:会话开始时 skills 文件夹还不存在的,新建后要重启一次;已经调用过的 skill,对话里留的是旧内容,要再调用一次才会用上新版。
以前写在 .claude/commands/ 里的命令还能用吗?
能用。.claude/commands/deploy.md 仍然会生成 /deploy。但它是单个文件,没法带附属文件,也不支持 paths,新写的建议直接用 skill。两者重名时 skill 优先。
13检验

小测验

8 道题,每题选完会立刻看到解析。全部答对就算掌握了这一章。