怎么写出自己的第一个 Claude Code Skill
把一段你反复对 AI 口述的流程,写成一个文件夹、一个 /命令——以及它为什么有时候死活不触发
📅 更新于 2026-09-13
本文校对于 Claude Code 技能文档 @ v2.1.269 · 官方源:code.claude.com/docs/en/skills
0030 秒速览:三句话 + 你的处境 → 直接看哪节
读完这一篇,你能亲手写出一个真能跑起来的 Skill:它认识你敲的 /命令,能在你说人话时自己认领任务,能带上当前的真实数据(比如未提交的改动),也能被同事拉下仓库直接用。同时你会知道它的两种失败长什么样、分别该改哪一行。
① 一个 Skill 就是一个文件夹里放一份 SKILL.md——上半段是被两条 --- 夹住的「字段区」,下半段是给 AI 看的操作说明;文件夹的名字就是你要敲的命令名。② 字段区里的 description(描述)决定它会不会被自动叫起来,而正文只在真被叫起来时才占用 AI 的"记忆空间"。③ 它不是代码工程:没有编译、没有依赖,你写的是"让助手照着做的说明",所以第一版十分钟就能出来。
按你现在的处境,直接跳到这一节
| 你现在的状态 | 直接看 | 为什么先看这个 |
|---|---|---|
| 完全没概念,不知道 Skill 长什么样 | 01 → 06 | 先破除四个错误印象,再直接做一个最小的 |
| 做过一次,但它从来不会自动触发 | 07 | 九成问题在 description 那一行 |
| 它总是乱触发,我不想让它自作主张 | 05 / 14 | 一个开关字段 + 一条权限规则就能锁住 |
| 技能放了但列表里找不到 | 04 / 16 | 位置、层级、文件名三处最容易放错 |
| 想让技能看到"我此刻改了哪些文件" | 09 | 动态注入会在加载前先把命令跑掉 |
| 某个步骤必须精确一致,怕 AI 临场发挥 | 09 | 把它写成脚本,正文里写死调用命令 |
| 想装别人写好的,不想从零写 | 12 | 官方技能仓库可以直接当插件市场装 |
| 想给团队用 / 想在别的工具里也用 | 11 | 跨工具只认规范里的六个字段 |
| 已经有一堆技能了,想知道谁在用 | 14 | /skill-doctor 会告诉你每个技能占多少 |
一条最短路径(今天就能走完)
- 建一个文件夹,写一份 SKILL.md(约 5 分钟)——照 06 的
summarize-changes抄,只需要两行字段和一个正文标题。 - 两条触发路径各测一次(约 3 分钟)——主动敲
/summarize-changes,再用大白话问一次"我这次改了什么"。两条都通,才算真的装上。 - 拿一个你重复讲过三遍的流程换掉它(约 10 分钟)——用 03 的三问筛一遍,再用 18 的 10 问过一遍才算交付。
本文第一次出现的每个非日常词,都会在同一屏内用日常语言解释一遍;不解释的说法一律不写。文末术语对照表的第三列回答的是「为什么重要 / 什么时候用 · 别当什么用」,可以直接当索引查。
01一个 Skill 到底是什么东西(先破四个错想)
Skill(技能)是 Claude Code 里一个"打包好的做事方法":它不装软件、不写代码,实体就是你磁盘上的一个文件夹,里面至少躺着一份叫 SKILL.md 的纯文本文件。Claude Code 是 Anthropic 出的 AI 编程助手,你在终端里跟它对话,它能替你读写文件、跑命令——本文讲的就是怎么给它加一个你自己的技能。官方的定义很朴素:Skill 是文件夹形式的指令、脚本和资源,Claude 按需加载它来提高在专门任务上的表现[4]。翻成人话:你把一段反复要讲的流程写成文档放进工位,下次它自己去翻。
先看它最小的样子
命令名来自文件夹名——想要 /daily-summary,文件夹就得叫 daily-summary:
# 你的项目目录结构
my-project/
└── .claude/
└── skills/
└── daily-summary/ # 文件夹名 = 命令名
└── SKILL.md # 唯一必需的"说明书"
SKILL.md 里只有两块:最顶上用两条 --- 夹住的 frontmatter(前置字段区,一种写在一对横线之间、用"键: 值"表示配置的文本格式,叫 YAML),和下面的正文说明。一个最短可用版长这样:
---
description: 汇总当前工作区未提交的改动,指出风险点。用户问"改了什么""帮我写 commit 信息"或"review 一下我的改动"时使用。
---
## Instructions(步骤)
把上面的 git 改动用两三点概括,再列出你注意到的风险(缺错误处理、硬编码、需要补测试等)。
就这么简单——没有编译、没有配置、没有依赖。它能成立,是因为 Claude 本身就会读写文件;你给的不是程序,而是让助手照着执行的说明。
破错想一:它不是插件,也不是后台常驻的程序
很多人第一次听"技能"会以为是个装上去就常驻运行的小软件。不是。它的主体是纯文本,磁盘上只是一个文件夹:没有进程、没有守护、没有开机自启。官方说法是:技能被用到时以「一段消息」的形式进入对话,从此留在上下文里,Claude 不会在后续回合重新读那个文件[1]。
破错想二:装上了不等于会自动生效
"装好了就该自动想起来用"是最常见的误解。触发只有两条路:你主动敲 /技能名,或者 Claude 在对话里发现任务和某个技能的 description 对得上,自己加载它[1]。第二条完全依赖你那一行描述写得好不好——描述看不出来,这个技能对 AI 就等于不存在。
破错想三:它不能替代 CLAUDE.md
CLAUDE.md 是 Claude Code 每次会话都会自动读进上下文的项目记忆文件。官方给的判据是:当你反复粘贴同一段指令、检查清单或多步流程时,或者 CLAUDE.md 里某一节已经从「事实」长成了「流程」,就该做成技能[1]。一句话规则进记忆,多步流程进技能(02)。
破错想四:它不是代码工程,但仍能跑代码
技能本身是文档,可它可以带脚本、也可以让 Claude 在你的机器上执行命令——这是它真正的威力,也是唯一需要警惕的地方[1][4]。自己写的自己清楚,别人给的要先通读(09)。
02它解决什么问题(以及它和"记忆"怎么分工)
你大概已经让 AI 写过代码、改过东西了。有没有过这种体验:同一套"先检查、再按这个格式、最后跑那个测试"的流程,隔几天就得重新打一遍?有时讲得细,有时讲得粗,AI 的发挥也跟着忽好忽坏。Skill 就是来终结这种重复的。
同一件事的两种做法
> 帮我 review 下这次改动。按老规矩来:
> 1. 看有没有把密钥写进代码
> 2. 看有没有处理空值和报错
> 3. 命名要符合项目规范
> 4. 最后跑一遍相关测试
> 记住了吗?上次你漏了第 4 步…
打字累、容易漏,每次都占掉一截上下文,还常常"这轮讲歪了"。团队里其他人更得各自发明一套。
> /review-pr
同一套流程,一次写进 .claude/skills/review-pr/SKILL.md,之后永远只有一句话。换谁来用都一样稳。
"为什么不写进 CLAUDE.md"
官方把分工写得很直白:CLAUDE.md 的内容每次会话都在,而技能正文用到时才加载,所以长参考资料在没被用上之前几乎不花成本[1]。
| 载体 | 适合装什么 | 加载方式 | 一句话记忆法 |
|---|---|---|---|
CLAUDE.md(记忆) | 一句话能说清的常驻规则:代码风格、禁止事项、"提交信息用中文" | 每次会话都进上下文,一直生效 | "你永远都要遵守的规矩" |
| Skill(技能) | 多步骤流程,或只有特定任务才用得上的知识:PR 检查、周报生成、导出某种格式 | 描述常驻,正文按需加载 | "只有干这活时才翻的操作手册" |
同一段流程你已经对着 AI 重复讲了 2~3 次,或者你希望别人也能稳定跑出同样结果——就是把它做成 Skill 的时候了。技能的四笔收益也在这里:经验固化、输出稳定、省上下文、可带可分享(随 Git 入库,换电脑不丢)。别一上来为了"酷"去定制;痛点会替你选出第一批该固化的流程。
03什么值得做成 Skill、什么不值得
技能不是越多越好。攒一堆用不上的技能,会让每次会话的技能清单变长(清单也占上下文,见 14)。先筛,再写。
三个问题过筛
- 它还会再发生吗?只做一次的事不用固化。
- 我不在场时,别人能验收吗?验收标准说不清,说明流程本身还没定型。
- 它有固定形状吗?有步骤或固定格式;如果每次都要你实时拍板,那它更该留在对话里。
适合 / 不适合
- ✅ 适合:同一流程已重复 2~3 次;希望"别人 / 未来的我"也能稳定复现;有明确步骤或固定格式、边界描述得出来;只在特定任务上用得上(正好适合按需加载)。
- ❌ 该用别的方式:只有一句话的常驻规则 → 写进
CLAUDE.md。 - ❌ 干脆别做:只做一次、下次多半不一样的事;中间需要你不断实时拍板的交互流程;完全依赖当天口味、每次都要重新聊的创作;你还没想清楚"什么时候算做完了"的流程。
12 个"新手半小时能落地"的起点
下表第二列是"直接抄进 description 就该八九不离十"的触发话术。
| 场景 | 你实际会说的话(写进 description) | 做成什么 & 放哪 |
|---|---|---|
| 规范写 commit 信息 | "帮我写条 commit 信息""这次改了什么" | git 改动汇总 + 格式生成(个人级) |
| 按团队标准审改动 | "review 一下我的改动 / 这个 PR" | 项目级检查清单(项目级) |
| 给新项目"认路" | "这个项目是干嘛的?从哪开始看?" | 读 README → 跑起来 → 输出"代码地图"(项目级) |
| 某类报错急救 | "又报 xxx 了,帮我查" | 一类报错的排查步骤(个人级) |
| 每周汇总开发进展 | "写周报""这周做了什么" | 注入 git log 生成周报(个人级,见 10) |
| 检验自己是否真懂 | "考考我""帮我检查我理解对没" | 五步校验法(个人级,见 10) |
| 笔记转复习卡 | "把这篇笔记变成几个问题" | 输入 Markdown → 输出问答卡(个人级) |
| 精读一篇技术文 | "用老办法拆解这篇文章" | 固定拆解框架(背景 / 论点 / 例子 / 可复用处) |
| 统一风格的翻译 / 改写 | "把这封邮件改得像上封那样正式" | 把"你的文风"固化成说明(个人级) |
| CSV / 表格整理成报告 | "整理一下这个表,出个报告" | 说明 + 轻脚本,规定列与输出(个人级) |
| 下载文件夹体检 | "看看下载文件夹乱不乱" | 扫大文件脚本(个人级,见 09) |
| 用官方文档技能做 Office 文件 | "用文档技能做个 PPT / PDF" | 直接装官方技能包(见 12) |
04它住在哪、你敲的命令从哪来
写之前先把这两件事搞清楚——新手失败的一大半原因不是正文写得差,而是放错位置,或以为 name 字段能改命令名。
技能可以被放在七个位置(校对时官方列了七行)
"放在哪"决定"对谁生效"。这是官方位置表的完整形态[1]:
| 层级 | 路径 | 在这些地方加载 |
|---|---|---|
| 企业级(Enterprise) | 受管设置目录里的 .claude/skills/<技能名>/SKILL.md | 组织部署到的机器上所有用户 |
| 个人级(Personal) | ~/.claude/skills/<技能名>/SKILL.md | 你这台机器上的所有项目(Cowork——Anthropic 的桌面协作产品——和跑在云端的会话不读它) |
| 项目级(Project) | .claude/skills/<技能名>/SKILL.md | 这个仓库里的会话。提交进 Git 全组都有 |
| 嵌套级(Nested) | <子目录>/.claude/skills/<技能名>/SKILL.md | 在子目录里或之下启动的会话;父级会话在 Claude 动到该目录文件时才加载 |
| 附加目录(Additional) | 你用 --add-dir 传进去的目录里的 .claude/skills/ | 那一次会话 |
| 插件级(Plugin) | <插件>/skills/<技能名>/SKILL.md | 启用该插件的所有地方,命令名前带插件前缀 |
| claude.ai 账号同步 | 你在 claude.ai 设置里启用的技能 | Cowork 与云端会话(见 14) |
① 别把技能文件夹叫 synced(任何大小写都不行):那是 Claude Code 放"从 claude.ai 同步下来的技能"的保留名字,你写的同名技能会被跳过[1]。② --add-dir 只加载被加目录下的 .claude/skills/、.claude/commands/ 和 .claude/agents/;设置里的 permissions.additionalDirectories 只给文件访问权,一个技能都不加载[1]。
你敲的命令从哪来:目录名,不是 name
这是旧版教程最容易讲错的一处。在个人级与项目级技能里,name 字段只改列表里显示的标签,命令名仍然来自文件夹名;只有插件技能里,name 才会覆盖命令的最后一段[1]。
| 技能放在哪 | 命令名从哪来 | 例子 |
|---|---|---|
~/.claude/skills/ 或 .claude/skills/ 下的技能目录 | 目录名 | .claude/skills/deploy-staging/SKILL.md → /deploy-staging |
嵌套 .claude/skills/,且名字和其他技能撞车 | 相对工作目录的子路径 + 技能目录名 | apps/web/.claude/skills/deploy/SKILL.md → /apps/web:deploy |
.claude/commands/ 下的文件 | 去掉扩展名的文件名 | .claude/commands/deploy.md → /deploy |
.claude/commands/ 子目录里的文件 | 子路径把 / 换成 :,再接文件名 | .claude/commands/frontend/component.md → /frontend:component |
插件的 skills/ 子目录 | 字段区的 name,否则目录名;都带插件前缀 | my-plugin/skills/review/SKILL.md → /my-plugin:review;写了 name: fancy 则是 /my-plugin:fancy |
插件根目录的 SKILL.md | 字段区的 name,退回插件目录名 | my-plugin/SKILL.md(name: review)→ /my-plugin:review |
同名了谁赢
- 企业级 / 个人级 / 项目级里的两个:企业 > 个人 > 项目。两处都有
deploy时跑个人的那个。 - 上面任一层 vs 内置技能(bundled skill):你的技能替换掉内置那个,但不替换它的别名——项目里的
code-review会顶掉/code-review,可内置别名/review永远不会跑到你的技能。 - 技能 vs
.claude/commands/里的文件:技能赢。 - 项目根技能 vs 嵌套技能:两个都加载,靠
/apps/web:deploy这种带路径的名字区分。 - 插件技能 vs 上面任何一层:两个都加载——插件技能带命名空间
/插件名:技能名。
老式自定义命令还在,但已并入技能;"保存即生效"有一个例外
以前大家把 /deploy 写在 .claude/commands/deploy.md。官方现在明确说:它和 .claude/skills/deploy/SKILL.md 都会生成 /deploy、行为一样,你已有的命令文件继续能用;区别是技能多了辅助文件目录、控制"谁来触发"的字段、以及被自动加载的能力,命令文件还少支持 name 和 paths 两个字段[1]。新写就用技能。热更新方面:Claude Code 会监视技能目录,新增、修改、删除都当前会话内即时生效[1];两个例外是——会话启动时那个顶层 skills 目录还不存在(得重启一次),以及监视只覆盖 SKILL.md 文本(插件型技能改 hooks/、.mcp.json、agents/ 要另跑 /reload-plugins)[1]。
05frontmatter 逐字段:哪些必须有、哪些只在 Claude Code 里有效
frontmatter 不是写给读者看的,是写给"调度器"看的:告诉它这个技能叫什么、什么时候能用、能不能自动用、用的时候要不要免询问放行某些工具[1]。官方口径是:所有字段都可选,只有 description 是"推荐写"的,省略它时会拿正文第一行非空内容当描述[1]。但实操上,不写 description 等于放弃自动触发,所以把它当必填。
字段表(校对时的完整清单)
| 字段 | 干什么用 | 新手怎么填 |
|---|---|---|
description | Claude 判断何时自动调用(最重要) | 推荐必写。写"做什么 + 何时用 + 用户会说的原话"(07) |
name | 技能在列表里的显示名;省略时用目录名 | 个人级 / 项目级里它不改命令名(04);插件技能里才覆盖命令最后一段 |
when_to_use | 额外触发语境(触发短语、例句),会拼在 description 后面一起进列表 | 触发词太多就放这,别把 description 挤爆。它一起算进 1536 字符上限 |
argument-hint | 自动补全时提示这个命令期望什么参数,如 [issue-number] | 要带参数就写;用户敲 /技能名 时会看到该填什么 |
arguments | 给位置参数起名,供正文里的 $名字 引用 | 进阶:写成空格分隔的字符串或 YAML 列表,按顺序对应第 1、2、3 个参数(09) |
disable-model-invocation | 设为 true 时禁止 Claude 自动加载,只能你敲 /名字 | 副作用大的流程(部署、提交、发消息)加它。加了以后描述也不再进上下文 |
user-invocable | 设为 false 时从 / 菜单隐藏,只允许 Claude 自动加载 | 纯背景知识型技能用(比如"这套老系统怎么运作") |
allowed-tools | 调用这个技能的那一回合里免询问放行列出的工具 | 进阶。下一条消息发出时授权就清空;新手先让它弹一次权限框,亲眼看它跑什么 |
disallowed-tools | 技能生效期间把某些工具从可用池里拿掉(allowed-tools 的反面) | 极端场景才用,比如让后台循环技能不可能调用"问你问题"这个工具 |
context / agent / background | 把技能丢进独立子代理里跑,并指定用哪种子代理、要不要在后台跑 | 进阶,见 11。写 background: false 让它在调用它的那一回合里等结果(需要 v2.1.218+) |
model / effort / hooks / paths / shell | 换模型、调"努力档位";注册钩子(在特定事件点自动替你执行的命令);限定只在动到匹配文件时才自动加载;指定动态注入用哪个 shell(命令行解释器) | 进阶玩法,先不管。effort 可选 low / medium / high / xhigh / max;shell 默认 bash,也可写 powershell |
metadata / license / compatibility | 你自己工具读的自由键值对;许可证;环境要求(如"需要 git、docker、jq") | 来自跨工具规范。Claude Code 接受这三个字段但不据此做任何事 |
只有六个字段能跟着技能"跨工具走"
这点新手最容易忽略:Claude Code 的字段是超集。当你把技能上传到 claude.ai、走 Skills API,或用官方仓库的打包脚本时,只认六个字段;带了别的字段不是被忽略,而是直接硬报错[1]:
Unexpected key(s) in SKILL.md frontmatter: argument-hint. Allowed properties are: allowed-tools, compatibility, description, license, metadata, name
| 分发路径 | 能用的字段 |
|---|---|
| Claude Code 里任何层级的技能(含插件技能) | 上面那张表的全部字段 |
claude.ai 技能上传、Skills API、用 anthropics/skills 的打包脚本 | 只有 name、description、license、compatibility、metadata、allowed-tools |
两个来源在这里对不上(读懂才写得出的分歧)
跨工具的 Agent Skills 规范说:name 和 description 都是必填,而且 name 有硬性格式——最多 64 个字符、只能用小写字母数字和连字符、不能以连字符开头或结尾、不能出现连续两个连字符,并且必须和父目录同名[3]。Claude Code 的文档说:字段全部可选,只有 description 是推荐字段,name 省略就用目录名,在个人级 / 项目级技能里它甚至只影响显示标签[1]。
怎么理解这个分歧:这不是谁错了,而是两个不同的关口——Claude Code 读你本地文件时很宽容;打包上传 / 跨工具分发时才按规范严格校验。所以实操建议只有一句:即使 Claude Code 不要求,也把 name 写成小写连字符、并且和文件夹同名。这样以后要上 claude.ai、或给别的 AI 工具用,不用返工。
YAML 写法上三个真会把人绊倒的点
- 第一个
---必须是文件第 1 行。否则 Claude Code 会把整个文件(连---一起)当成正文——结果是:正文照用、/名字照样能敲,但描述读不到,自动触发全线失效[1]。 - 布尔值写法很宽松。除了
true/false,还接受yes/no/on/off/1/0,不区分大小写(v2.1.218 起;之前只认true和false)[1]。 - 列表既能写成一行也能写成 YAML 列表。
allowed-tools、disallowed-tools、arguments、paths都接受"空格或逗号分隔的一行",也接受真正的 YAML 列表[1]。
06最小例子:十分钟做出第一个能用的技能
现在从头做一个真正能用的:「看懂我改了什么 + 生成规范的 commit 信息」。它够小、能立刻验证,还正对你天天遇到的场景。目标是:以后只要说"我这次改了什么",Claude 就会自动带上当前真实的 git 改动,按固定格式汇报并给 commit 建议。commit 是 Git 里"把一批改动记成一个存档点"的动作,commit 信息就是那次存档的说明文字。
Step 1|决定放个人级还是项目级
个人级(~/.claude/skills/):所有项目通用,适合"你自己的习惯"类技能。
# 在终端(Mac 按 Command+空格 输入"终端")执行:
mkdir -p ~/.claude/skills/summarize-changes
项目级(.claude/skills/):跟着项目走,团队共享,适合"这个项目的规矩"类技能。
# 先 cd 进你的项目目录,再执行:
mkdir -p .claude/skills/summarize-changes
Step 2|写入 SKILL.md
在刚建好的文件夹里新建 SKILL.md,内容如下。注意第一行就是 ---,前面不能有空行,否则字段区读不到:
---
description: Summarizes uncommitted changes and flags anything risky. Use when the user asks what changed, wants a commit message, or asks to review their diff.
---
## Current changes
!`git diff HEAD`
## Instructions
Summarize the changes above in two or three bullet points, then list any risks
you notice such as missing error handling, hardcoded values, or tests that need
updating. If the diff is empty, say there are no uncommitted changes.
Finally suggest one commit message in the form `type(scope): summary`, where
`type` is one of fix, feat, docs, refactor, or test.
这段里有唯一一个"魔法"值得先记住:正文里的 !`git diff HEAD` 是动态上下文注入——技能被加载前,Claude Code 会先执行这条命令,把输出替换掉这一行,所以给到 Claude 的说明里已经内联了当前改动,而不是它自己猜的[1]。git diff HEAD 是 Git 的"显示我改了哪些行"命令(HEAD 指最新那次提交)。这段抄的是官方文档的英文原版;描述写中文没有副作用,见 07。
Step 3|两条触发路径都要测(必做)
- 主动调用路径:随便改一个文件,然后在会话里敲
/summarize-changes。它应该读取当前改动并按格式汇报。 - 自动触发路径:用一句大白话问"我这次改了什么?帮我写条 commit 信息"。描述写得够具体的话,Claude 应该自己认领这个技能。
- 确认它真被加载了:敲
/skills看列表里有没有它(也可以直接问"你现在有哪些技能可用?")。如果列表里有、但描述像是空的,用claude --debug启动会话看字段区解析报错[1]。
① 文件夹确实在 ~/.claude/skills/ 或 .claude/skills/ 下、且叫 summarize-changes?② SKILL.md 第一行就是 ---,前面没有空行、没有 BOM(文件开头那种看不见的编码标记)?③ description 里有没有用户真会说的那句话?三样都对了还不行,就跑 claude plugin validate 检查语法(需要 v2.1.233 或更高版本)[1]:
claude plugin validate ~/.claude/skills
claude plugin validate .claude/skills
不想敲命令?直接把需求说给 Claude,让它建
你完全不用背路径。下面这段对话是"可以照抄"的脚本——真实输出会有差异,但节奏一模一样:
# ── 你在 Claude Code 里输入 ──
> 我的电脑是 Mac。请帮我做一个个人技能 weekly-report:
> 它读最近 7 天的 git 提交,生成一份简洁的中文周报。
> 帮我在 ~/.claude/skills/weekly-report/ 下建好 SKILL.md。
# ── Claude 的回复(示意,实际可能不同)──
> 好的。我会创建 ~/.claude/skills/weekly-report/SKILL.md:
> 用动态注入读取 git log,按"归类+动词开头"的结构输出周报。
> 已创建完毕,你可以输入 /weekly-report 试试。
# ── 你继续提需求(迭代,别一次提完)──
> 加个触发词:当我说"写周报"或"这周干了啥"时,希望它会自动用这个技能。
# ── 然后分别测两条触发路径 ──
> /weekly-report # 路径一:主动调用。应输出本周周报
> 这周我干了啥? # 路径二:自然语言。自动调用了=成功;
# 没调用=把 description 改得更接近这句人话
连对话都不想打,这是最短路线——把下面这段直接发给它:
> 把这段流程做成个人技能 review-my-diff,放到 ~/.claude/skills/ 下。
> description 写成:按我的项目标准审查未提交改动并给 commit 建议,
> 我说"review 我的改动"时自动用。
> 流程:1) 用 git diff 看改动 2) 查密钥/空值/命名
> 3) 按 fix/feat/docs/refactor/test 给 commit 建议。
建好后立刻 /review-my-diff 试一次。不满意就接着说"把第 2 条改成先查错误处理"——它会改文件,你再测。技能文件就是普通文本,打开 ~/.claude/skills/weekly-report/SKILL.md(在访达按 Command+Shift+G 粘贴路径直达)随时手改,保存即生效。
07写出会被自动触发的 description
description 是新手定制技能时最值得花功夫的一行。它是 Claude 判断"要不要用这个技能"的主要窗口:写得模糊,技能永远不被想起;写得太宽,它又会到处乱触发。配方是【它做什么】+【什么时候用】+【触发关键词 / 用户原话】[2]。
一条好描述长什么样
description: 处理文档,帮助用户。
任何任务都"沾边",所以任何任务都轮不到它——Claude 判断不出它比别的技能更合适。官方给的反面例子更短:Helps with documents[2]。
description: 汇总未提交的 git 改动并生成规范的 commit
信息;指出风险。用户说"我改了什么""写条 commit"
或"review 我的改动"时使用。
三样都齐了:做什么(汇总 + 生成 commit)、何时用(有未提交改动时)、触发词(用户原话)。
六条可以照抄的规则
- 用第三人称客观口吻,别写"我帮你……"——描述会被塞进系统语境。官方明确警告:一律用第三人称,视角不一致会导致发现失败[2]。不会开头就以动词起:
Summarizes/汇总。 - 把最重要的用途放在最前面——技能列表对描述做截断:
description和when_to_use合起来上限 1536 字符[1]。核心用途不写进前一两句,被截掉就亏了;总长控制在一两百字内。 - 埋入"用户会真的说出的话"——"我改了什么""写周报""帮我 review"。官方排查"技能不触发"的第一条建议就是:确认描述里含用户会自然说出的关键词[1]。
- 含文件类型 / 领域词——技能针对特定格式就直接点名:
.csv、.xlsx、.pdf、React、Obsidian。官方示范里就点明了 PDFs, forms, or document extraction、.xlsx files[2]。 - 触发太频繁就把范围收窄——官方办法就是让描述更具体;实在想全手动,再加
disable-model-invocation: true[1]。比如把"处理文件"改成"把 CSV 整理成透视表报告"。 - 别在描述里写会过期的信息——版本号、最新价格、截止日期放进正文或参考文件都比写进
description好;描述常驻,过期一次污染所有会话。
描述被截断时,究竟发生了什么(这一步多数教程不讲)
除了单个技能 1536 字符的上限,还有一层总预算:Claude Code 把所有技能的"名字 + 描述"当成一份清单塞进上下文,清单的字符预算是模型上下文窗口的 1%(上下文窗口=模型一次能"看到"的全部信息量)。清单溢出时,它从你最少调用的技能开始丢描述,让你常用的那几个保留完整文字[1]。
- 描述被削短:清单超出预算,按"调用次数从少到多"丢描述(名字永远保留)。解法是把低频技能在
skillOverrides里设成name-only,腾出预算(14)。 - 想知道清单占了多少:
/doctor给估算值和最大的几个贡献者,/context里的 Skills 行给的是应用预算之后的实际大小。 - 想加大预算 / 改单条上限:设置项
skillListingBudgetFraction(如0.02表示 2%)、环境变量SLASH_COMMAND_TOOL_CHAR_BUDGET、单条上限skillListingMaxDescChars;不过优先减技能,其次才加预算。
自测一法:把 description 读给一个没用过你技能的人,问他"听完你能不能在 3 秒内想到,什么时候该喊这句话出场?"能,就对了;要解释半天,说明还太抽象。
08正文怎么写:五百行、辅助文件与渐进披露
正文没有固定格式,但官方规范和一些共同经验指向同一套骨架,照它写最不容易漏[1][2]。先记住一句话:技能加载后,正文会作为一条消息留在上下文里,后续回合不会重新读文件[1]——所以每一行都是持续的成本,写"该做什么"而不是"这是怎么回事"。官方作者指南把上下文窗口叫"公共资源",并给出一句默认假设:Claude 已经足够聪明,只补它不知道的东西[2]。
正文骨架三件套
| 块 | 写什么 | 为什么必须有 |
|---|---|---|
| Instructions(步骤) | 编号、具体、可执行。别写"处理好数据",写"运行 python3 scripts/collect_logs.py --week 本周 收集日志" | 这是 AI 实际照着走的路径,含糊=结果随机 |
| Examples(例子) | 给 1~2 个"输入长这样 → 输出长这样"的对照 | AI 模仿具体例子比读抽象描述快得多[2] |
| 适用边界 | 写清它不负责什么、什么时候别用它 | 这是一道"第二道过滤",能显著减少误用 |
一个稍完整的技能长这样——注意它同时给了字段区、适用边界和编号步骤:
# SKILL.md —— 顶部两条 --- 之间叫 frontmatter(元信息)
---
name: weekly-report
description: 汇总本周学习/工作进展,生成一份简洁的中文周报。用户说"写周报""本周总结"时使用。
argument-hint: [本周起止日期]
---
## 适用边界
只处理本周的进展汇报,不做下周规划、不算数据指标。
## 怎么做
1. 打开 reference.md,按里面的模板结构生成周报。
2. 逐项回顾本周改动与产出,每条一句话、以动词开头。
3. 结尾列出 1~2 条"卡住待解决"的问题。
4. 输出成 Markdown;若给了日期参数,在标题写明起止日期。
正文别超 500 行:超了拆文件
官方给的硬建议是 SKILL.md 保持在 500 行以内,接近这个量就把细节挪到旁边的文件[1][3]。跨工具的规范把"渐进披露"(progressive disclosure:先只给摘要,用到才展开细节)拆成三层成本[3]:
| 层 | 什么时候加载 | 官方给的量级 |
|---|---|---|
| 元信息(名字 + 描述) | 启动时,所有技能都加载 | 约 100 个 token(token=模型计费与容量的小块文字单位) |
| 正文 | 技能被激活时 | 建议 5000 个 token 以内 |
| 资源文件 | 按需 | 脚本、参考文档、模板,不用就不加载 |
社区通行的目录约定是这样分工的[1][3]。要让 Claude 知道每个文件装了什么、什么时候读它,正文里就直接列出来(- For complete API details, see [reference.md](reference.md)):
weekly-report/
├── SKILL.md # 说明书(唯一必需):总览 + 导航
├── reference.md # 参考书:模板 / 术语对照,正文太长时挪到这里
├── examples.md # 用法示例,需要时才读
├── references/ # 规范里的推荐目录名,放 REFERENCE.md、FORMS.md 等
├── assets/ # 模板、图片、查表数据等静态资源
└── scripts/
└── collect_logs.py # 工具:能被执行的脚本(执行,不加载进上下文)
引用辅助文件的三条铁律
- 只用相对路径,且文件就在
SKILL.md旁边:scripts/helper.py、references/REFERENCE.md,不要引用别处的绝对路径。 - 引用层级只保持一层:
SKILL.md → reference.md可以;SKILL.md → a.md → b.md这种链条,规范明确要求避免[3]。 - 路径分隔符一律用正斜杠
/,别用 Windows 的反斜杠——这是跨工具通行的写法。
技能内容其实分两类,写法不一样
| 类型 | 装什么 | 该怎么写 | 典型开关 |
|---|---|---|---|
| 参考型(Reference content) | 规矩、模式、风格指南、领域知识——Claude 应用到当前工作上的知识 | 内容内联生效,写成条目式规则即可 | 一般用默认(人和 Claude 都能调) |
| 任务型(Task content) | 部署、提交、代码生成这类具体动作的分步指令 | 通常希望你自己敲 /名字,而不是让 Claude 自己决定何时跑 | 加 disable-model-invocation: true |
给多少自由取决于任务的脆弱程度[2]:高自由度——纯文字说明,适合有多种正确做法、要看上下文决定的任务(如代码审查);中自由度——给伪代码或带参数的模板,适合有偏好模式但允许变化的任务;低自由度——直接给脚本、且明确"就照这个跑,不要改命令",适合必须精确一致的重复操作。官方给的类比是"两边都是悬崖的窄桥"和"没有障碍的开阔地":出错代价越高,越该写死。
09让它带上真数据:参数、动态注入、脚本
前面几节都是"纯说明书",这已经能解决大量问题,但有三类需求会让技能更值钱:同一套流程服务不同输入(参数)、要看当前真实状态(动态注入)、某一步必须精确一致(脚本)。
参数:同一个技能吃不同输入
你敲 /技能名 后面这段字 时,后面那段可以用占位符取到[1]:
| 写法 | 含义 | 注意 |
|---|---|---|
$ARGUMENTS | 你敲进来的整句参数 | 正文里没有任何占位符接住参数时,Claude Code 会把 ARGUMENTS: <你输入的内容> 追加到正文末尾,保证 Claude 仍看得到[1] |
$0 / $1 / $2 | 按空格拆开后的第 1、2、3 个参数 | $0 才是第一个参数,$1 是第二个。多词的值要用引号包成一个参数 |
$ARGUMENTS[0] | 和 $0 等价的全写形式 | 看着啰嗦,但意图更清楚 |
$名字 | 引用字段区里 arguments 声明过的具名参数 | 如 arguments: [issue, branch] 时 $issue 是第一个、$branch 是第二个 |
$0 是第一个,不是 $1
很多人(包括旧版教程)会顺手写成"$1、$2 取第 1、2 个参数"。这在官方文档里是反的:$N 是 $ARGUMENTS[N] 的简写,$0 是第一个参数,$1 是第二个[1]。写成分位置取参时务必照官方核对。
两个完整的带参技能
---
name: migrate-component
description: Migrate a component from one language to another
---
Migrate the $0 component from $1 to $2.
Preserve all existing behavior and tests.
跑 /migrate-component SearchBar JavaScript TypeScript 时,$0 换成 SearchBar、$1 换成 JavaScript、$2 换成 TypeScript[1]。把参数和动态注入合起来,就是周报那种"给几天就查几天"的写法——注意 argument-hint 让用户知道该填什么:
# frontmatter 声明参数提示(可选)
---
description: 按最近 N 天的 git 提交生成中文周报。用户说"写周报"时使用。
argument-hint: [最近几天,默认 7]
---
## Instructions
1. 用户给了 N 就用 N,没给就用 7:
!`git log --since="$ARGUMENTS days ago" --pretty=format:"%ad %s" --date=format:%m-%d`
2. 把注入的提交记录归类后输出中文周报。
- 取位置参数用的是 shell 风格的引号规则:
/my-skill "hello world" second会让$0变成hello world、$1变成second;而$ARGUMENTS永远是原样整句[1]。 - 索引占位符没有对应参数时(比如只传了一个参数却写了
$2),它原样留在正文里;具名占位符没有对应参数时展开成空字符串[1]。 - 想在正文里写真正的钱数
$1.00,用反斜杠转义\$1.00;参数里若本身含$1,会被当纯文本插入、不再展开[1]。 - 一条消息里可以叠着调多个技能:敲
/write-tests /fix-issue 123会同时加载两个技能,并把尾部文字123作为各自的参数。最多展开"第一个 + 后面五个"[1]。
动态上下文注入:让技能看到"此刻真的发生了什么"
!`<命令>` 会在技能内容送给 Claude 之前先跑命令,并用输出替换掉这一行[1]。三个要点:只在行首或空白之后才被识别(写成 KEY=!`cmd` 会原样留着、命令不跑);命令输出不会再被扫描一遍(不能"吐出"另一个占位符让下一轮展开);多行命令用 ```! 开头的围栏代码块:
## Environment
```!
node --version
git status --short
```
这不是"那一行空了",而是整个技能这次都不生效——Claude 看不到任何技能内容,界面上显示 Shell command failed for pattern "...",错误里带 [stderr] 段[1]。三条实操结论:默认 bash 下任何非零退出码都算失败(唯一例外是官方列出的"搜索与比较类"命令退出码为 1;≥2 仍失败);你预料会非零退出的命令(比如"发现问题就退出 1"的检查脚本)在命令后加 || true;注入的命令永不弹权限框,权限检查只要不是"允许"就整次中止,要么用 allowed-tools 预先放行,要么改成不触发权限的写法[1]。
另外三个默认行为:命令在会话当前的工作目录下跑(Claude 执行过 cd 就会跟着变);默认 bash 下 stderr 会被合并进输出;每条命令受 Bash 工具默认的 2 分钟超时限制[1]。
脚本:把"必须精确一致"的那一步锁死
有些事必须精确、可复现(统计数量、压缩图片、解析固定格式的日志),让 Claude 现场凭感觉做容易出错。这时就把这一步写成脚本,Claude 只负责运行它、再解读结果——这就是官方说的低自由度写法[2]。一个能直接用的例子,个人级技能 folder-scan 体检 ~/Downloads:
~/.claude/skills/folder-scan/
├── SKILL.md
└── scripts/
└── scan_dir.py # 一个能跑的脚本
# scripts/scan_dir.py —— 脚本务必自带错误处理,别一崩就退出
import os, sys
def main():
try:
root = sys.argv[1] if len(sys.argv) > 1 else os.path.expanduser("~/Downloads")
big = []
for dirpath, _, files in os.walk(root):
for name in files:
fp = os.path.join(dirpath, name)
try:
size = os.path.getsize(fp)
if size > 100 * 1024 * 1024: # 只看 >100MB 的
big.append((size, fp))
except OSError:
continue # 单个文件读不了就跳过,不中断
big.sort(reverse=True)
for size, fp in big[:15]:
print(f"{size/1024/1024:.0f} MB\t{fp}")
if not big:
print("目录下没有超过 100MB 的文件。")
except Exception as e:
print("扫描失败:", e, file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
---
name: folder-scan
description: 体检一个文件夹:找出超大文件并排序。用户说"看下我的下载文件夹乱不乱""有哪些大文件"时使用。
argument-hint: [目录路径]
---
## Instructions
1. 用户未指定目录时,直接运行:`python3 scripts/scan_dir.py`(默认扫 ~/Downloads)。
2. 用户给了路径就运行:`python3 scripts/scan_dir.py 路径`。
3. 脚本输出到 stderr 的报错信息要原样告诉用户,不要自己编一个。
4. 把前几行最大的文件用易懂的话总结给用户,并给出"要不要删 / 移到外置盘"的建议。
把 python3 scripts/scan_dir.py 这条命令原样写进正文,Claude 就会真去跑脚本,而不是"假装"帮你数——这就是低自由度把不确定性锁死的意义。四条脚本纪律:命令写全(写 python3 scripts/scan_dir.py --dir 路径,而不是"用脚本扫一下目录");脚本自带错误处理(兜底、把失败原因打到 stderr——错误信息专用的输出通道——并 sys.exit(1),Claude 才好把真实报错转述给你);写清分工("脚本负责抓数据,你负责解读和排版");只装信得过的来源[2][4]。
让脚本路径"装在哪都对":用 ${CLAUDE_SKILL_DIR}
直接写 scripts/xx.py 时,命令是在会话的当前工作目录下跑的,不一定在技能目录里。官方提供了变量 ${CLAUDE_SKILL_DIR}(技能自己的目录),它在正文和 allowed-tools 里都会被替换[1]——两处写同一个变量,是为了让放行规则精确匹配正文让 Claude 跑的那条命令,于是脚本免询问直接跑。同类变量还有 ${CLAUDE_PROJECT_DIR}(项目根目录,需要 v2.1.196+)、${CLAUDE_SESSION_ID}(当前会话号)、${CLAUDE_PLUGIN_ROOT} / ${CLAUDE_PLUGIN_DATA}(只在插件技能里)[1]。
allowed-tools
有人为了"少弹权限框"一上来就写 allowed-tools。它确实能在调用那一回合免询问放行,但官方也点明了风险:工作区信任不会拦住这个字段——被提交进仓库的技能,在你从没信任过的目录里跑 -p(非交互模式,一次性跑完就退出)时,它的 allowed-tools 照样生效[1]。所以:用之前先看一眼仓库里别人写的技能的 allowed-tools;新手阶段宁可让它弹一次权限框、你亲眼确认它真在跑你要的命令。另外还有一个管理员级开关 disableSkillShellExecution,打开后用户 / 项目 / 插件来源技能里的 !`命令` 会被替换成 [shell command execution disabled by policy] 而不执行[1]。
10四个可以照抄的技能
把前面学到的合起来。四个技能难度递进、都能立刻用上:纯规则、带权限声明、带动态数据、纯教学法。每个都给完整文件,照着建就行。
案例 A|只许你敲的提交助手:commit
这是官方文档里"任务型技能"的示范:动作有副作用,所以用 disable-model-invocation 把自动触发关掉,再用 allowed-tools 精确放行三条 git 命令[1]:
---
name: commit
description: Stage and commit the current changes
disable-model-invocation: true
allowed-tools: Bash(git add *) Bash(git commit *) Bash(git status *)
---
它帮你省下:每次提交前逐条放行 git 命令的点击,以及"怕 AI 自作主张提交"的心慌。注意:加了 disable-model-invocation: true 后,它的描述也不再进上下文——这是"拿省心换省上下文"的取舍[1]。
案例 B|项目级:代码审查清单 review-pr
放进你项目的 .claude/skills/review-pr/SKILL.md,把"这个项目该按什么标准 review"固化成团队共识:
---
name: review-pr
description: 按本仓库标准审查当前分支改动(找 bug、对规格),输出问题清单。用户说"review 我的改动/这个 PR"时使用。
---
## 适用范围
只审查未合并进 main 的分支改动,不重构、不写测试代码。
## 怎么做
1. 先运行 `git diff origin/main...HEAD --stat` 了解改了哪些文件。
2. 逐个改动文件检查:有没有密钥/绝对路径写死?有没有把 null 当对象用(空值崩溃)?报错是被吞掉还是真的处理了?命名是否符合项目习惯?
3. 把发现按「必须改 / 建议改」两档列出,每一条写清文件与行号级的位置。
4. 收尾时给出结论:可以合并 / 修完再合 / 不建议合。
它帮你省下:每次 review 重新口述标准,以及"AI 这次有没有记得看错误处理"的抽奖感。换新同事、换项目,直接用同一套。
案例 C|个人级:周报生成器 weekly-report
放进 ~/.claude/skills/weekly-report/SKILL.md(个人级,所有项目都能喊)。它靠动态注入"最近一周的 git 提交",你只需要说一句"写周报":
---
name: weekly-report
description: 根据最近一周的 git 提交生成简洁中文周报。用户说"写周报""这周做了什么"时使用。
argument-hint: [天数,默认 7]
---
## 数据源:先把本周提交注入进来
!`git log --since="7 days ago" --pretty=format:"%ad %s" --date=format:%m-%d`
## 怎么做
1. 若上面的注入结果为空,告诉用户"这一周没有提交记录",并建议检查是否在正确的仓库目录。
2. 有记录时:把提交信息归类成「功能 / 修复 / 学习 / 杂务」几组,每组一句、以动词开头。
3. 想了解更多文件级改动,自己再跑 `git log --since="7 days ago" --stat --oneline`。
4. 结尾列出「下周打算」2~3 条(用户没提就空着,别瞎编)。
5. 输出 Markdown;若用户给了天数参数 N,把 `--since="N days ago"` 替换进去。
它帮你省下:回想"这周到底干了啥"的脑内考古,和每次翻 git log 的手工活。动态注入意味着它拿到的永远是真实数据,不是编的。
案例 D|纯教学法:五步校验 teach-check
这是最"零代码"、也最能体现 Skill 本质的一个:不含脚本、不含 git,只是把你认可的一套方法写成文档。放进 ~/.claude/skills/teach-check/SKILL.md:
---
name: teach-check
description: 用固定五步帮用户校验是否真懂了一个概念。用户说"考考我""帮我检查理解""讲透这个概念"时使用。
---
## 它是什么
把"检验是否真懂一个概念"的方法论,做成一问一答的现场小考。不直接灌输,而是先让用户自己答。
## 怎么做
1. 请用户说出或挑出一个想检验的概念(如"事件循环")。
2. 依次抛出下面五个问题,每问等用户答完、给一句纠正后再进下一问:
a) 它不是什么?(最容易被误解成什么?)
b) 它是什么?(给一句准确的定义)
c) 它怎么运作?(底层机制或执行流,别说"就是那样")
d) 为什么重要?没有它会怎样?
e) 新手最容易踩什么坑?边界在哪里?
3. 五问结束,用一张小表总结,并指出用户刚才哪一问最含糊。
4. 用户答错时,只纠正并给一句话类比,不展开长篇大论。
它帮你省下:每次想"检验自己理解"时重新设计提问框架的脑力。它示范了技能的另一半价值——把方法论本身变成可以反复执行的东西,哪怕一行代码都没有。
四个案例的骨架完全一样:description 圈定触发 → 正文写死流程 →(需要时)声明权限、注入真实数据或调用脚本。区别只在于"流程"是什么——是检查清单、是周报模板,还是你的教学方法。你会写一个,就会写一百个。
11进阶:让它跑在子代理里,以及同一份技能跨工具用
什么时候该让技能独立跑:context: fork
加上 context: fork 后,技能会在一个独立的子代理上下文里执行:Claude Code 新开一个由 agent 字段指定类型的子代理,把技能内容当它的任务[1]。好处是它看不到你的对话历史——跑研究、跑长任务时不会把主对话撑爆。
---
name: deep-research
description: Research a topic thoroughly
context: fork
agent: Explore
---
Research $ARGUMENTS thoroughly:
1. Find relevant files using Glob and Grep
2. Read and analyze the code
3. Summarize findings with specific file references
- 它不是"分叉当前对话"。尽管名字里有 fork,它并不会把你们聊过的内容交给子代理;任务依赖对话历史时,该分叉的是对话本身[1]。
- 纯规范型技能用它没意义。像"请遵守这套 API 约定"这种没有动作的知识型技能,子代理收到一段没有任务可执行的文字,会空手而归[1]。
- 默认在后台跑。写
background: false才会在调用它的那一回合里等结果;后台跑的 forked 技能,改动不在会话检查点里,/rewind撤不掉,要撤得用 git[1]。
agent 可以填内置的 Explore、Plan、general-purpose,也可以是 .claude/agents/ 里的自定义子代理;不写就是 general-purpose[1]。
技能之间可以叠加
一条消息里可以叠着调多个技能(09 的 /write-tests /fix-issue 123),正文里也可以指示 Claude"先按某个底层技能的流程做完,再回来继续"。官方把"先执行基础技能、再回到本技能"这种做法当作组合方式之一[1]。不过新手先别急着做组合:等手上攒到三个以上技能,你会自然地想把公共步骤抽出来。
跨工具:Agent Skills 是一份公开规范
Claude Code 的技能遵循 Agent Skills 开放标准(agentskills.io),这份标准也被别的 AI 工具实现[1][3],所以同一份技能有机会"写一次、处处用"。代价就是 05 讲的那条限制:出了 Claude Code 只认六个字段,多写一个直接硬报错。想让技能既能本地用、又能上传 / 分发,就把字段限制在这六个里,把 Claude Code 专属的便利(动态注入、argument-hint、context: fork)留在本地版本。官方还明确了两条跨工具边界:动态注入这类"Claude Code 专属正文功能"在 claude.ai 聊天和 API 调用时不会生效;Claude Code 在你机器上绝不会为"从 claude.ai 账号同步下来的技能"执行 !`命令`,同步技能里的 @ 文件引用和 ${CLAUDE_PROJECT_DIR} 也会以纯文本到达 Claude(v2.1.228+)[1]。
12复用现成的:官方技能包与空白模板
定制自己的技能,最快的起点不是从空白开始,而是先改一个现成的。官方仓库 anthropics/skills 收集了大量演示级技能,从文档处理(docx / pdf / pptx / xlsx)到开发测试都有;每个都是独立文件夹 + 一份 SKILL.md[4]。
方式一:整包安装官方的(当插件用)
在 Claude Code 会话里把这个仓库注册成插件市场,再安装你想要的包[4]:
# 在 Claude Code 会话里输入:
/plugin marketplace add anthropics/skills
# 然后挑一个包安装,例如文档技能:
/plugin install document-skills@anthropic-agent-skills
# 或用:
/plugin install example-skills@anthropic-agent-skills
装完直接说人话就能用:"用 PDF 技能把这个 PDF 的表单字段提取出来"[4]。两条使用前必须知道的口径:这些技能仅作演示与教学用途,你实际得到的行为可能和示范不同,用在关键任务前请自己在环境里充分测试;仓库里多数技能是 Apache 2.0(一种宽松的开源许可证,允许自由使用与修改)开源,但支撑 Claude 文档能力的 docx / pdf / pptx / xlsx 是 source-available(源码可读,但不是完全开源),拿来学结构没问题[4]。
方式二:拷贝 + 改造 = 学定制最快的一课
- 找到想学的技能文件夹——从
anthropics/skills仓库挑一个,或从你装好的插件目录里挑一个;也可以直接让 Claude 展示它某个内置技能的结构。 - 整包复制到你的技能目录,改名——拷到
~/.claude/skills/或项目.claude/skills/下,文件夹名改成你要的命令名,此时它已经出现在技能列表里。 - 改字段区:
name+description换成你的场景——这是"变成你自己的技能"的关键一步,把描述里的领域词换成你的触发词(07)。 - 通读正文再留改——删掉不适用步骤、加上你的检查项,然后照 06 测一遍。改之前先通读全文,尤其是带脚本的技能,别在没看懂前就让它跑。
官方也给了空白模板
仓库里的 template/ 就是一个空技能模板,校对于 2026-09-13 时它的全文只有五行[4]:
---
name: template-skill
description: Replace with description of the skill and when Claude should use it.
---
# Insert instructions below
复制它、把两个字段填成你的场景、在 Markdown 正文里写 Instructions / Examples / 适用边界,一个合格技能就成型了[4]。分享与带走也是这样:全组都能用就把项目级技能提交进 Git(官方推荐做法[1]);换电脑不丢就备份 ~/.claude/skills/,建议把这个目录本身也纳入一个 git 仓库;按组织统一部署就走受管设置目录(企业级,普通用户改不了);跨 AI 工具就遵循 Agent Skills 规范、只用那六个字段(11)。
技能可以包含并执行脚本[1][4]。因此:只从可信来源安装(官方仓库、你信任的人)、改造前先通读正文和脚本、别因为"是别人给的技能"就跳过这一步。你亲手写的技能由你负责——这才是定制真正带给你的掌控感。
13怎么知道它真的在工作:两条触发路径 + 一个对照实验
官方把这件事说得很清楚:看到技能被触发,只说明 Claude 找到了它,不代表它做了你想做的事[1]。要判定"它在工作",得把两件事分开测——该触发时有没有触发,和触发后输出对不对。
第一层:两条路径各测一遍
先照 06 的 Step 3 那样各走一次手工测试。判断标准要分清:主动调用不通就改正文步骤和参数占位符;自动触发不通就改 description / when_to_use 里的触发词;如果连 /skills 里都看不到它,那问题在位置、层级或文件名(04)。
第二层:做一个"有它 / 没它"的对照实验
官方推荐的判定法是基线对比:攒几个真实场景的提示词,每个都在全新会话里跑两次——一次技能可用,一次技能被关掉——然后比较结果[1]。为什么必须是新会话?因为你写技能时积累的上下文会掩盖文件里没写清的地方[1]。两个工具能把这个比较自动化:claude plugin eval 在隔离会话里对每个提示词各跑一遍"有插件 / 没插件",用你定义或它生成的评分器打分,低于阈值就返回非零退出码、可以卡在 CI(持续集成,每次提交自动跑检查的那套流水线)上(适合随插件分发的技能);skill-creator 插件在对话里跑同一套循环、用自己的 evals/evals.json 格式(适合迭代单个技能)[1]:
/plugin install skill-creator@claude-plugins-official
# 如果提示找不到市场:
/plugin marketplace add anthropics/claude-plugins-official
# 装完让 Claude 评估一个已有技能:
evaluate my summarize-changes skill with skill-creator
它会做的事包括:把测试用例存进技能目录下的 evals/evals.json;每个用例起一个子代理保证干净上下文,并记录 token 数与耗时;把每条断言的结果写进 grading.json;把"有技能 / 没技能"的通过率、时间和 token 汇总进 benchmark.json;在两个版本之间做盲测 A/B;生成"该触发 / 不该触发"的提示词来调描述;最后开一个 HTML 报告让你逐条记反馈[1]。注意:官方明确说这两个评估(eval,就是"拿一批真实提示词跑一遍看结果")格式不能互换[1]。
技能"跑着跑着就不管用了"是怎么回事
新手常见抱怨是"第一条回复还听我的,后面就不听了"。官方给的解释是:内容通常还在上下文里,是模型选择了别的做法[1]。两条应对路径:把 description 和正文写得更有说服力,让模型持续偏好它;或者需要确定性的行为就用钩子(hooks)强制,而不是指望提示词[1]。还有一种情况是上下文被压缩了:自动压缩(auto-compaction)时,Claude Code 会把每个技能最近一次调用的前 5000 个 token 重新挂回摘要之后,所有被重新挂回的技能共享 25000 个 token 的总预算,从最近调用的开始填[1]。所以一次会话里调了太多技能,旧的会被整个丢掉——压缩之后再调一次就能恢复完整内容[1]。
14开关、权限、用量:技能变多以后
技能攒到五六个之后,会开始出现新问题:谁在占上下文?怎么临时关掉一个?怎么让某个技能永远不许自动跑?这一节全是可操作的。
目录卫生:让三个月后的自己还看得懂
- 一个技能一个文件夹,命令名一眼看懂用途(动词开头更佳:
summarize-changes而不是gitstuff)。 - 把个人技能目录也纳入一个 Git 仓库:换电脑一克隆就全回来,改坏了能回滚——技能也是资产。
- 辅助文件固定后缀:每个技能根部只留
SKILL.md,长资料用reference.md、工具放scripts/、模板放assets/。 - 定期清点:用
/skill-doctor看哪个技能从没被用过,超过一个月没动的考虑关掉或归档。
一个整洁到一眼能看懂的技能目录长这样:
~/.claude/skills/
├── summarize-changes/
│ └── SKILL.md
├── weekly-report/
│ └── SKILL.md
├── folder-scan/
│ ├── SKILL.md
│ └── scripts/
│ └── scan_dir.py
└── teach-check/
└── SKILL.md
不改文件也能关技能:skillOverrides
有些技能是别人提交进共享仓库的,你不想动它的文件。skillOverrides 设置让你从设置里控制可见性;/skills 菜单会替你写它——高亮一个技能、按空格循环状态、按 Esc 保存到 .claude/settings.local.json[1]。四个状态:"on"(名字和描述都给 Claude、菜单里有)、"name-only"(只给名字,省描述预算)、"user-invocable-only"(对 Claude 隐藏但菜单里有,标成 user-only)、"off"(两边都隐藏)[1]。
{
"skillOverrides": {
"legacy-context": "name-only",
"deploy": "off"
}
}
三条边界要注意:没出现在 skillOverrides 里的技能按 "on" 处理;"off" 不影响插件技能,插件的用 /plugin 管;"user-invocable-only" 和 "off" 之后用全名硬敲也不会跑,而是返回 skillOverrides 错误[1]。
用权限规则控制"哪些技能能被 AI 调用"
比逐个改字段更统一的做法,是在权限设置里写规则[1]。语法是 Skill(名字) 精确匹配,Skill(名字 *) 前缀匹配、后面可以带任意参数:
# 全部禁用(在 deny 规则里加一行)
Skill
# 只允许特定技能
Skill(commit)
Skill(review-pr *)
# 禁止特定技能
Skill(deploy *)
另一种等价的"从上下文里彻底移除"的办法,是在那个技能的字段区写 disable-model-invocation: true[1]。
看用量与删除:谁在花你的上下文
想知道谁在花上下文,跑 /skill-doctor(每个技能占多少、被调用过几次、哪些从没被用过;需要 v2.1.252+)和 /doctor(清单总成本);/context 里的 Skills 行给的是应用预算之后的实际大小。
删除按来源分五种做法:个人级 / 项目级直接删掉那个目录(~/.claude/skills/<名字>/ 或 .claude/skills/<名字>/),当前会话内即从 /skills 消失;企业级由管理员从受管设置目录里删(如 Linux 上的 /etc/claude-code/.claude/skills/);插件技能在 /plugin 菜单里停用或卸载,或 /plugin uninstall <插件名>@<市场名>;claude.ai 同步来的要在 claude.ai 上关掉(手动删目录没用,下次同步还会回来);内置技能把 disableBundledSkills 设为 true 全关,或用 skillOverrides 把某一个设成 "off"[1]。
把 claude.ai 上启用的技能同步到本地
如果你在 claude.ai 的账号设置里启用了技能,本地会话不会自动拿;需要跑一次带环境变量的非交互会话把它下载下来[1]:
CLAUDE_CODE_SYNC_SKILLS=1 claude -p "List the skills you have available"
它会下载到 ~/.claude/skills/synced/,回答完提示词就退出,文件留在磁盘上。之后启动交互会话、跑 /skills,会在 claude.ai sync 分组下看到它们[1]。同步技能有一条重要规则:它的名字若和任何内置命令、内置技能、本地技能、插件技能或 MCP 提示词撞车,就会被跳过,另一个跑[1]。
15易混对照:它和五个邻居各差在哪
这是新手最容易长期搞混的一片区域。先把六个东西摆在一张表里,再逐个说差别。
| 它是什么 | 本质 | 加载方式 | 什么时候用它 |
|---|---|---|---|
| Skill(技能) | 文件夹 + SKILL.md(可带脚本 / 资料) | 描述常驻;正文被调用时才进上下文,且此后留在上下文里 | 多步流程、特定任务才用得上的知识 |
CLAUDE.md(记忆) | 项目或个人的常驻规则文件 | 每次会话都读 | 一句话就能说清、且永远要遵守的规矩 |
.claude/commands/*.md(旧式自定义命令) | Markdown 文件,已并入技能体系 | 和技能一样,也会生成 /名字 | 老项目里已有的可以留;新写就用技能 |
| 子代理(Subagent) | 一套独立的执行者配置(模型、工具、权限) | 单独上下文,靠任务简报启动 | 要隔离上下文、要专用工具集时 |
| 插件(Plugin) | 技能 + 子代理 + 钩子 + MCP 服务器的打包分发单位 | 装了插件,它带的技能以 /插件名:技能名 出现 | 要分享给一群人、或按组织部署时 |
| MCP | Model Context Protocol:让 AI 连上外部工具 / 数据源的开放协议 | 由 MCP 服务器提供工具和提示词 | 需要连数据库、第三方服务等外部能力时 |
「技能」和「记忆」:一句话规则 vs 多步流程
官方判据已经在 02 讲过:CLAUDE.md 的内容 每次会话都在;技能正文用到才加载[1]。所以"提交信息一律用中文"进记忆,"生成周报要走这四步"进技能。别用技能替换永远要遵守的规则——那种规则进了技能反而不会每次都生效。
「技能」和「旧式自定义命令」:现在是同一件事
两者会生成同一个 /名字、行为一样,所以新写时直接用技能即可,别在"这算不算技能"上纠结;完整的边界(命令文件少支持哪两个字段)见 04 那一节。
「技能」和「子代理」:可以互相借力,但方向不同
带 context: fork 的技能是"你写任务、挑一个子代理类型来执行":系统提示来自子代理类型,任务来自 SKILL.md 内容,还会加载 CLAUDE.md(用 Explore / Plan 时除外)。反过来,用 skills 字段预载技能的子代理,系统提示来自它自己的 Markdown 正文,任务来自 Claude 的委派消息[1]。
「技能」和「插件」:零件与集装箱
插件是分发单位。给一个技能文件夹加一个 .claude-plugin/plugin.json,它就会以 <名字>@skills-dir 的形式作为一个插件加载,从而能顺带打包子代理、钩子和 MCP 服务器[1]。反过来:插件里的技能带命名空间前缀,所以它和你本地的同名技能不会互相覆盖,而是两个都在[1]。
「技能」和「MCP」:一个管"怎么做",一个管"能碰到什么"
MCP 让 AI 接上外部世界(能查数据库、能调第三方接口),技能告诉 AI 按什么流程做。两者不冲突:一个技能完全可以规定"先用某个 MCP 工具拉数据,再按这个格式输出"。所以选型的问题不是二选一,而是问自己"我缺的是能力,还是流程"。
16常见坑与排错
六个新手必踩的坑
description 写"处理文档、帮助用户",Claude 无法判断何时用它,等于技能不存在。修法见 07。
正文一旦激活就整篇进上下文,并留在后续回合里。超过 500 行就拆到辅助文件,靠渐进披露按需读。
技能只认 …/<技能名>/SKILL.md 这种一层结构。多套一层、少一层、或文件名大小写不对都扫不到。用 /skills 自查。
第一个 --- 必须是文件第 1 行。坏了的话正文还能用、/名字 也能敲,但自动触发全失效[1]。
正文写着"处理一下数据"却不给命令、不给脚本、不给格式,等于把确定性丢掉。要精确的操作给死命令 / 脚本(09)。
"审查 + 周报 + 翻译 + 起名"塞一起,名字难起、描述难写、误触发频发。拆成几个小技能,各管一摊。
症状对照表:出问题先查这里
| 症状 | 最可能的原因 | 快速修法 |
|---|---|---|
| 技能列表里找不到 | 放错目录 / 缺 SKILL.md / 文件名不符 / 会话启动时那个顶层目录还不存在 | 确认路径是 …/技能名/SKILL.md,跑 /skills;必要时重启一次会话[1] |
/名字 能用,但从不自动触发 | 字段区坏了,或 description 没含触发词 | claude --debug 看解析报错;把用户原话写进描述[1] |
| 动不动就乱触发 | 描述写太宽 | 让描述更具体、收窄到特定文件类型 / 场景;或加 disable-model-invocation: true[1] |
| 激活后干得不对 | 正文步骤含糊 / 缺例子 | 补编号步骤 + 输入输出例子 + "为什么"[2] |
| 带脚本的技能不跑 | 路径写错 / 权限没给 / 脚本本身报错 | 用 ${CLAUDE_SKILL_DIR}/scripts/xx.py 这种随技能走的路径;看 stderr 原样报错 |
整个技能"没反应",界面报 Shell command failed | 动态注入的命令非零退出 | 给预期会失败的命令加 || true;或改成不触发权限检查的形式[1] |
| 描述明显比别人短 | 技能清单超出预算,按调用次数从少到多丢描述 | 把低频技能设成 name-only,或提高 skillListingBudgetFraction[1] |
| 第一条回复还行,后面就不听了 | 内容还在,模型选了别的做法 | 强化描述与正文;要确定性就用钩子强制[1] |
想自己核对本文的事实?两条命令就够
官方文档站提供一份 Markdown 版本,可以直接用命令行拉下来搜(curl 是"把网址内容下载下来"的命令,grep 是"在文本里搜关键词"的命令;这也是本文写"校对于"时用的方法):
curl -sL https://code.claude.com/docs/en/skills.md | grep -n "disable-model-invocation"
curl -sL https://code.claude.com/docs/en/skills.md | grep -n '\$0'
① 技能能执行代码——别装来路不明的技能,装了先通读再跑[1][4]。② 别为了省事全局开 allowed-tools;让它弹一次权限框、你亲眼看它跑什么命令,比"先斩后奏"安全。副作用大的流程(部署 / 提交)记得加 disable-model-invocation: true[1]。
17一页纸速查
最小技能骨架(照抄即可)
# 目录结构:命令名 = 文件夹名
.claude/skills/你的技能名/
└── SKILL.md
# SKILL.md 内容
---
name: 你的技能名
description: 它做什么 + 什么时候用 + 用户会说的话。示例:汇总 git 改动并生成 commit 信息;用户说"我改了什么"时使用。
---
## Instructions
1. (编号、可执行的具体步骤)
2. (需要时引用:scripts/xx.py 或 reference.md)
放置位置速查
| 想让它…… | 放到 | 命令名 = |
|---|---|---|
| 你自己所有项目可用 | ~/.claude/skills/技能名/SKILL.md | 文件夹名 |
| 跟着这个项目 / 团队共享 | .claude/skills/技能名/SKILL.md | 文件夹名 |
| 只在某个子目录里生效 | 子目录/.claude/skills/技能名/SKILL.md | 撞名时加路径前缀 |
| 通过插件安装的现成技能 | 插件目录/skills/技能名/SKILL.md | 插件名:技能名 |
| 组织统一下发 | 受管设置目录里的 .claude/skills/ | 文件夹名 |
字段逐个是什么意思、新手该怎么填,见 05 的那张完整字段表(这里不重复第二份,免得两处漂移)。
正文里的占位符速查
| 写法 | 含义 |
|---|---|
$ARGUMENTS | 整句参数 |
$0 / $1 / $2 | 第 1 / 2 / 3 个参数(从 0 开始数) |
arguments: + $名字 | 给位置参数命名后按名字引用 |
!`命令` | 激活时先执行、把输出注入正文(动态上下文) |
```! 开头的代码块 | 同一段动态注入里跑多行命令 |
${CLAUDE_SKILL_DIR} | 技能自己的目录,装在哪都对 |
${CLAUDE_PROJECT_DIR} | 项目根目录(v2.1.196+) |
调试与维护命令速查
| 什么时候 | 做什么 |
|---|---|
| 查看当前有哪些技能 / 是否被识别 | 输入 /skills,或问"你现在有哪些技能可用?"[1] |
| 看谁常用、谁占上下文 | /skill-doctor(用量统计,v2.1.252+)与 /doctor(清单成本)[1] |
| 校验字段区语法 | claude plugin validate ~/.claude/skills 或 claude plugin validate .claude/skills(v2.1.233+)[1] |
| 技能没被识别 / 描述读不到 | 用 claude --debug 启动,看字段区解析报错[1] |
| 改完技能让它生效 | 什么都不用做——技能目录是热更新的(新建顶层目录那次要重启)[1] |
| 评估技能质量 | /plugin install skill-creator@claude-plugins-official,再让 Claude 评估[1] |
18交付前 10 问
跟写完代码要跑测试一样,写完一个技能要过一遍自检。全部打勾才算"能发布 / 能分享";有一项没勾就回去改那一项。
description能用一句话说出"做什么 + 何时用 + 触发原话"吗?说不清等于这个技能没想清楚。- 文件夹名是小写连字符,而且和
name一致吗?个人级 / 项目级里命令名只认文件夹名(04);两边写成一样,跨工具分发时才不返工。 - 放对层级了吗?
/skills里看得到吗?个人习惯放~/.claude/skills/,团队规矩放.claude/skills/。 SKILL.md第一行就是---,字段区没写坏?前面有空行 / 有 BOM / YAML 缩进错,都会让描述读不到、自动触发全失效。- 正文有编号步骤、有"输入 → 输出"例子、写清了适用边界?三件套齐了,执行质量和"别乱用"都有保障(08)。
- 正文在 500 行内?长内容拆到
reference.md/scripts/了?拆的时候保持一层深,别叠成三层。 - 引用路径都是相对路径、正斜杠,而且脚本自带错误处理?脚本要兜底、失败打到 stderr 并退出。
- 描述会不会"永远不触发"或"到处乱触发"?副作用操作上锁了吗?不触发 → 补触发原话;乱触发 → 收窄描述;会改系统 / 上线的操作 → 加
disable-model-invocation: true。 - 正文有没有写死"会过期的信息"(版本号、价格、截止日期)?确认它们没有伪装成"永远成立"的规则。
- 我拿真实任务测过两次,而且"未来的我 / 别人"能看懂吗?技能也是文档——过两周你自己还要能维护它。
更狠的一招:说完"帮我用这 10 问检查一下我的 weekly-report 技能,逐条给结论"——AI 的"外部视角"常常一眼看出你写得顺手的技能其实描述很含糊。这比你自己盯着看有效得多,也是把本文知识内化的最好练习。
19术语对照表
| 术语 | 定义 | 为什么重要 / 何时用 · 别当什么用 |
|---|---|---|
| Skill(技能) | 打包好的可复用能力=文件夹 + SKILL.md(+ 可选脚本 / 资料),按需加载 | 全文主角。把"多步流程"交给它;别把"一句话常驻规则"也塞进来——那是记忆的活 |
| SKILL.md | 技能里唯一的必需文件:字段区 + 说明正文 | 技能的"说明书"。正文别超 500 行,长内容拆到旁边文件;它不是给人看的 README,是给 AI 执行的操作手册 |
| frontmatter(字段区) | 文件顶部两条 --- 之间的 YAML 配置 | 决定"名字叫啥、何时被触发、能否自动触发、放行哪些工具"。第一个 --- 必须在第 1 行;坏了=自动触发全失效 |
| YAML | 一种写在横线之间、用"键: 值"表示配置的文本格式 | 字段区用的就是它。缩进敏感、冒号后要有空格;写错不报错但会静默失效 |
| description(描述) | 说明"做什么 + 何时用"的那一行,Claude 靠它判断是否调用 | 最重要的一行。写清触发场景和用户原话;别写成模糊宣传语,也别放会过期的时效信息 |
| name | 技能在列表里的显示名;省略时用目录名 | 个人级 / 项目级里它不改命令名(命令名只认文件夹);插件技能里才会改命令的最后一段 |
| 个人级 / 项目级技能 | 个人级放 ~/.claude/skills/(所有项目);项目级放 .claude/skills/(随项目 / 团队) | 选对层级=选对"作用范围"。自己的习惯用个人级,团队的规矩用项目级并提交 Git;别把团队规矩放个人目录,否则别人没有 |
/命令名 | 主动调用技能的方式;命令名取自文件夹名(插件技能带前缀) | 确定性的"召唤咒语"。文件夹名取小写连字符;别指望名字能替代描述 |
| 自动触发(model invocation) | Claude 在对话中匹配 description 后自动加载技能 | 实现"说人话就能用"的关键。触发靠关键词命中;太频繁就收窄描述,要完全手动就用 disable-model-invocation |
disable-model-invocation | 设为 true 时禁止 Claude 自动加载,只能你敲命令 | 给副作用大的流程(部署 / 提交)加护栏。注意它会让描述也不再进上下文——别当"懒得上锁"省掉 |
user-invocable | 设为 false 时从 / 菜单隐藏,只允许 Claude 自动触发 | 留给纯背景知识型技能。它仍占描述的匹配机会,能主动触发就别关这个口子 |
when_to_use | 追加在 description 后的额外触发语境(触发短语、例句) | 触发词太多时放这里,别让描述又长又抢重点;它不是正文,别把流程步骤写进去 |
argument-hint | 自动补全时显示"这里该填什么" | 技能要吃参数就写上;别让用户自己猜参数格式 |
$ARGUMENTS / $0 / $名字 | 正文里引用用户传入参数的三类占位符 | 让一个技能服务"同一类不同输入"。注意 $0 才是第一个参数;没有占位符接住时,参数会被追加成 ARGUMENTS: … |
| 动态上下文注入 | 正文里写 !`命令`,激活时先执行命令、把输出替换进去 | 让技能看到实时真数据(如 git 改动),比让 AI 凭记忆编可靠。命令失败会中止整次调用;预期失败的命令记得加 || true |
| 渐进披露(progressive disclosure) | 先只给名字和描述,用到时再展开正文与资源文件 | 让技能"随叫随到又不占地"。做技能时主动用:SKILL.md 只留主线,细节放辅助文件,一层深引用 |
| 辅助文件 | 和 SKILL.md 放同一目录的参考文档、脚本、模板 | 省上下文的唯一正规手段。别把大段规范直接堆进正文——那样每次激活都要全付一遍 |
| 脚本(script) | 放进 scripts/、由技能指挥 Claude 运行的程序 | 把"必须精确一致"的操作锁死。别忘了自带错误处理;技能能执行代码,所以只装可信来源 |
| 热更新(live change detection) | 改动技能文件后,当前会话内即时生效、无需重启 | 意味着"改完马上测"的迭代极快;两个例外:会话启动时顶层 skills 目录还不存在、以及插件型技能的 hooks/ 等目录 |
| 上下文窗口 | 模型一次能"看到"的信息总量,是共享的稀缺资源 | 渐进披露的意义所在:描述常驻、正文按需。别把大正文全堆进去占每个人的额度 |
| 技能清单与预算 | 所有技能的"名字 + 描述"组成的一份常驻列表,预算是上下文窗口的 1% | 技能越多越容易被截断描述。用 /doctor 看成本、/skill-doctor 找没用的、skillOverrides 降级低频项 |
allowed-tools | 调用技能的那一回合免询问放行列出的工具 | 少弹框的便利,也是"先斩后奏"的信任状;下一条消息即失效。别一上来就全局放行 |
| 子代理(Subagent) | 一套独立的执行者:自己的上下文、模型、工具与权限 | 用 context: fork 把技能丢进去跑长任务、跑研究,不污染主对话;别指望它看到你们的对话历史 |
| 插件(Plugin) | 技能的分发单位,可同时打包子代理、钩子、MCP 服务器 | 装官方 / 社区技能包的入口;插件技能带 /插件名:技能名 前缀,所以和你本地的同名技能不冲突 |
| MCP | Model Context Protocol:让 AI 连上外部工具与数据源的开放协议 | 补的是"能力"不是"流程"。需要连数据库 / 第三方服务时才引入;别拿它替代技能 |
| 内置技能(bundled skill) | Claude Code 自带的技能,如 /code-review、/doctor、/debug | 它们是"提示词驱动"的,你的同名技能会替换掉它但不会替换它的别名;用 disableBundledSkills 可整体关闭 |
| Agent Skills(开放标准) | 跨工具的技能规范与目录,定义 SKILL.md 的通用字段与目录约定 | 决定"同一份技能能不能给别的工具用":出了 Claude Code 只认六个字段,多写一个直接硬报错 |
CLAUDE.md(记忆) | 常驻的项目 / 个人规则文件,每次会话都读 | 与技能分工:一句话规则进记忆、多步流程进技能;别用技能去替代"永远要遵守"的规则 |
20常见问题
/命令 有什么区别?/xxx,本质就是写一个同名技能(老式的 .claude/commands/*.md 也还在,但已并入技能体系)。CLAUDE.md 省的原因。要注意正文一旦进上下文就会留在后续回合里,遇到自动压缩时按"每个技能保留前 5000 token、共享 25000 预算"重新挂回[1]。description 没写对:没含用户会自然说出的话,或写得太宽让它判断不了"此刻最合适"。官方排查步骤是:① 检查描述是否含用户会说的关键词;② 确认它出现在"你现在有哪些技能可用?"里;③ 换个更贴近描述的说法再试;④ 如果它是用户可调用的,直接 /技能名 兜底[1]。还不触发就用 claude --debug 看字段区有没有解析失败。|| true;或者把它改成不触发权限检查的形式,否则权限检查不是"允许"时同样会中止调用[1]。/plugin,同步来的要在 claude.ai 上关(手动删目录下次同步还会回来)[1]。想"留着但别再自动跑",加 disable-model-invocation: true,或用 skillOverrides 设成 "user-invocable-only"——后者不用改文件[1]。~/.claude/skills/,整个拷走或备份即可;项目级技能在 .claude/skills/,提交进 Git 全组自动共享[1][4]。多台设备可以把个人技能目录本身纳入一个 git 仓库管理。要按组织统一部署,走受管设置目录。name 和文件夹名则建议一律英文小写连字符——它要频繁敲、也要跨工具通用。/write-tests /fix-issue 123,Claude Code 会展开第一个加后面最多五个,并把尾部文字作为各自的参数[1]。至于"一不一定照做"——技能正文是很强但非绝对的指令,它会作为一条消息留在上下文里,后续回合不会重读文件[1],所以要把贯穿整个任务的指导写成"长期有效的指令"。如果它"跑着跑着就不管用了",官方判断通常是内容还在、模型选了别的做法[1]。21参考来源与证据边界
本文事实于 2026-09-13 对照下述官方来源校对,版本口径为 Claude Code v2.1.269(npm 上该版本发布于 2026-09-11)。文中加 [n] 处的说法均可在对应来源复核。
| # | 来源 | 本文用它核对了什么 |
|---|---|---|
| [1] | Claude Code 官方文档 — Extend Claude with skills https://code.claude.com/docs/en/skills | 七个技能位置与同名优先级、命令名来源、字段区完整字段表、跨工具只认六个字段、1536 字符描述上限与清单预算、动态注入与失败行为、参数占位符(含 $0 是第一个)、context: fork、技能内容生命周期与压缩行为、skillOverrides、权限规则、/skill-doctor、热更新与两个例外、各类删除方式、同步技能 |
| [2] | 官方作者指南 — Skill authoring best practices platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices | 精简优于详尽(含 50 / 150 token 的正反例)、自由度三档与"窄桥 / 开阔地"类比、第三人称描述、命名约定、渐进披露的三种组织方式、单层引用、跨模型测试 |
| [3] | Agent Skills 规范 https://agentskills.io/specification | 跨工具的字段约束(name 必填且须与父目录同名、≤64 字符、不能连续连字符;description 1–1024 字符)、可选目录 scripts/ references/ assets/、三层渐进披露的 token 量级、一层深引用、skills-ref validate |
| [4] | 官方技能仓库 anthropics/skills https://github.com/anthropics/skills | 插件市场与两套装法、template/ 空模板全文、演示用途与 source-available 的边界说明、"技能会执行代码"的安全提醒 |
| [5] | Claude Code 版本与变更记录 github.com/anthropics/claude-code/blob/main/CHANGELOG.md | 2.1.269 这个版本号的确认,以及各字段 / 命令的"需要 vX.Y.Z+"门槛 |
一处明确的分歧(两边都留着)
跨工具规范说 name 是必填且必须与父目录同名;Claude Code 文档说字段全部可选、只有 description 是推荐字段,个人级 / 项目级技能里 name 只影响显示名[1][3]。这不是笔误,而是"本地读文件"与"打包上传 / 跨工具"两个不同关口的差异。本文的处理是:讲清楚两边口径,并给出可执行建议(照规范写,Claude Code 也会照常接受)。详见 05。
- 一文两口径:
argument-hint、when_to_use、arguments、context、agent、background、hooks、paths、shell、metadata、disallowed-tools都是 Claude Code 的扩展字段,不在跨工具规范的六个字段里;依赖它们就等于绑定 Claude Code。 - 版本门槛会变:
/skill-doctor(v2.1.252+)、claude plugin validate(v2.1.233+)、background: false(v2.1.218+)、${CLAUDE_PROJECT_DIR}(v2.1.196+)这些门槛随版本演进;旧版本上照本文做可能遇到"字段没生效"。 - 描述与清单的具体数字是当前值:单条 1536 字符上限、清单约 1% 的预算比例、每个技能压缩后保留 5000 token、共享 25000 token——这些都可以通过设置项调整,也随版本变化。
- "写作手感"部分是推荐而非约束:三段式描述、步骤配例子、先写描述再写正文、目录卫生约定,来自官方作者指南与工程实践总结,属于建议;官方没有把它们写成字段级要求。
- Claude Code 迭代很快:本文锚定 v2.1.269。若你使用中发现与最新文档不符,多为版本演进所致——以官方最新文档为准。工具类教程将按需刷新。
想自己复核?两条命令就能重跑一遍校对
# 官方文档的 Markdown 版本,可以直接搜
curl -sL https://code.claude.com/docs/en/skills.md | grep -n "Frontmatter reference"
# 看当前最新版本号
curl -s https://registry.npmjs.org/@anthropic-ai/claude-code | grep -o '"latest":"[^"]*"'
99一句话总结
Skill 就是"把一套你反复讲解的流程,写进 .claude/skills/技能名/SKILL.md 的说明书"——文件夹名决定你敲什么 /命令,description 决定 Claude 什么时候自动用它,正文决定它上场后干得专不专业;抓住"同一段话重复讲了 2~3 次就固化成技能",再记住它有两种失败(不触发=改描述、乱触发=加开关),你就能把 AI 编程里的重复劳动一个个变成一句命令,从此越用越省、越用越像"你自己的助手"。