TL;DR:在 .claude/skills/<your-skill>/SKILL.md 中创建一个带有 YAML frontmatter(name、description)的 Markdown 文件,并在下方写上指令。智能体会自动发现它,并在遇到匹配任务时调用它。
技能是教给智能体某件事最轻量、最低仪式感的方式。只需在 .claude/skills/ 中放入一个 Markdown 文件,给它命名,用普通语言写下指令。智能体下一轮就能读取它,并永远记住你的做事方式。
每个代码库都有不成文的规矩:命名要这样,错误处理要那样,某类文件总是需要这个额外步骤。新成员在最初几周里会不断碰壁;智能体在每次全新的对话中也面临同样的困境。每天重复解释五次"表名用 snake_case,不用 camelCase"的成本并不低,最尴尬的情况是智能体连续犯了四次同样的错,仅仅因为没有人把它记录下来。
把这些规则写进 CLAUDE.md 的直觉,对于全项目范围内的不变约定是正确的。但很多习惯并不是全局性的,它们是情境性的:"写测试的时候,这样做。""准备推代码之前,先跑这个。""用户说'ship it'的时候,别只是部署——先打个 release tag。"一个塞满了"在这种特定情况下做这件特定的事"的 200 行 CLAUDE.md,对任何读者(模型或人类)来说都很难使用,而且智能体每次都会把所有内容全部加载进来。
技能是更细粒度的替代方案:每种情境对应一个 Markdown 文件,仅在相关时才加载。格式极其简单——带有名称和描述的 frontmatter,加上包含指令的正文,旁边可附上可选的辅助文件。智能体通过读取描述来判断技能是否适用;如果适用,就加载正文。多个技能可以共存而互不干扰;你可以在两分钟内写好一个技能,然后把它忘掉,直到对应情境再次出现。
SKILL.mddisable-model-invocation 禁止模型自动调用在 .claude/skills/ 下创建一个以技能命名的文件夹,在其中放入 SKILL.md:
.claude/
└── skills/
└── tdd/
├── SKILL.md ← 必需
└── examples.md ← 可选;补充材料
这就是完整的结构。文件夹名即技能名,SKILL.md 是必需的入口文件。文件夹中的其他任何文件都可以在技能正文中引用。
打开 SKILL.md,以 YAML frontmatter 开头:
---
name: tdd
description: Use this when the user asks for a test, when adding a new function, or when fixing a bug — write the test FIRST, then implement.
---
# Body goes here
When working in TDD mode:
1. Read the existing tests in the same module.
2. Write a failing test for the new behavior.
...
description(描述)是最重要的字段。智能体会读取所有可用技能的描述,并根据用户的输入决定加载哪些技能。模糊的描述("帮助处理测试")会被忽略;具体的描述("当用户要求测试或修复 bug 时,先写测试")才会被匹配。
描述的写法建议用"Use this when [触发条件]"或"For [情境], do [操作]"的形式。措辞的影响比你想象的更大。
SKILL.md 的正文是实际的指令集。目标是控制在 200 行以内。使用祈使句("先写测试,再写实现")、具体示例,以及明确的"这样做,不要那样做"对比——尤其是在错误做法很有诱惑力的地方。
你可以通过相对路径引用技能文件夹中的其他文件,智能体在加载技能时会读取它们。辅助文件适合放:长代码示例、检查清单、参考表格。
技能文件夹可以放在两个位置:
.claude/skills/<name>/,放在项目根目录或任意上级目录中。适合代码库特有的约定("在这个 repo 中,表名用 snake_case")。~/.claude/skills/<name>/。适合跨所有项目的个人习惯("提交前总是先跑我的 lint 检查")。项目级技能保留其原始名称。打包在插件中的用户级技能会以 <plugin>:<skill> 的形式命名空间化——两个插件各自可以有一个 tdd 技能而不会冲突。项目级的 tdd 会覆盖任何插件中的 tdd。
技能不仅可以由模型自动调用。手动触发有两种方式:
/<skill-name>(或对带命名空间的技能使用 /<plugin>:<skill>),技能立即加载。在智能体的自动匹配没有触发时非常有用。disable-model-invocation 逃生舱有些技能威力强大,你不希望模型自行决定使用的时机——比如破坏性操作、高成本操作、调用第三方 API 的操作。在 frontmatter 中加上这一行:
---
name: deploy-to-prod
description: Build, sign, and deploy to production.
disable-model-invocation: true
---
此后模型的系统提示词中不会出现这个技能,它无法自动调用。但斜杠菜单中仍会显示它,人类可以主动运行。这是"我想随时用到它,但我想亲自决定何时使用"这类场景的正确设置。