Agent Skills 的创建、结构与调用

一个文件夹加一份 SKILL.md,就是一个技能。真正决定它好不好用的是描述那一行——它是唯一常驻的部分。

约 11 分钟

技能是把一套流程或一份参考资料打包成一个它能自己调用的东西

什么时候该做一个技能,见上一节重复性工作的固化时机。这一节讲怎么做。

最小的一个

一个文件夹,里面一份 SKILL.md

~/.claude/skills/interview-coding/
└── SKILL.md

SKILL.md 的内容:

Markdown
---
description: 把访谈转写稿整理成编码表。当用户提到访谈编码、
             提取主题、整理受访者原话时使用。
---

## 步骤

1. 读取指定目录下的所有转写稿
2. 逐份提取主题,每条记录格式为「编号 | 主题 | 原话」
3. 原话必须逐字摘录,不改写、不合并相邻短句
4. 输出到 coding.md
5. 统计每份提取了多少条,少于 5 条的单独列出

## 输出格式

| 编号 | 主题 | 原话 |
|---|---|---|

就这样。 之后你可以:

  • 自己调用:输入 /interview-coding
  • 让它自己判断:你说「把这批访谈整理一下」,它会认出来该用这个

放在哪

位置 范围
~/.claude/skills/<名字>/SKILL.md 你的所有项目
.claude/skills/<名字>/SKILL.md 只有这个项目(可以进版本库,团队共享)

同名冲突时,个人的盖过项目的。

命令名来自文件夹名,不是 description 里的名字。 文件夹叫 interview-coding,命令就是 /interview-coding

改了文件立刻生效,不用重启会话。

描述那一行是全部的关键

这是这一节最重要的一段。

在你调用它之前,进入上下文的只有 description 那一行。技能的正文一个字都没加载。

所以:

  • 描述写不好 → 它永远不会自己想到用这个技能
  • 描述写得太宽 → 不该用的时候也用

怎么写描述

两件事:做什么,以及什么时候用

处理访谈 把访谈转写稿整理成编码表。当用户提到访谈编码、提取主题、整理受访者原话时使用。
报告工具 生成月度调研报告。当用户要求出月报、汇总本月数据、更新客户简报时使用。

把用户会自然说出的词写进去。 你平时怎么说这件事,就把那些词放进描述里。

描述有长度上限description 加上可选的 when_to_use合起来在技能清单里会被截断到 1536 个字符。所以最关键的触发场景要放最前面。

常用的几个配置项

全都是可选的。 但下面这四个值得知道。

disable-model-invocation —— 只许我调,你别自己调

YAML
---
description: 把整理好的编码表发给客户
disable-model-invocation: true
---

加了这一行,它不会自己调用这个技能,只有你输入 /名字 才会跑。

有副作用的操作都该加这一行——发送、提交、部署、覆盖。

还有一个附带好处:描述也不进上下文了,完全不占地方。

allowed-tools —— 免掉这一轮的权限询问

YAML
---
description: 保存当前进度到版本库
disable-model-invocation: true
allowed-tools: Bash(git add *) Bash(git commit *) Bash(git status *)
---

在调用这个技能的那一轮里,这几条命令不会问你。

注意有效期:你发下一条消息,这个授权就失效了。 它不是永久的。

paths —— 只在处理某类文件时才激活

YAML
---
description: 访谈转写稿的处理规范
paths:
  - "interviews/**/*.txt"
---

只有当它在处理匹配的文件时,这个技能才会被自动加载。

这条对「一份只在特定场景下才需要的规范」很合适。

context: fork —— 派出去做,不占我的上下文

YAML
---
description: 把这批材料全部读一遍,找出提到价格的段落
context: fork
agent: Explore
---

加了这一行,这个技能会在一个独立的子代理里跑,读了多少材料都不占你这边。

⚠️ 只对「有明确任务」的技能有意义。

如果你的技能只是一份参考资料(「处理这类文件时遵循这些约定」),加了 context: fork 之后子代理会拿到一份指南但没有活干,返回一堆没用的东西。

一个会影响成本的机制

技能一旦被调用,它的正文会作为一条消息留在会话里,直到会话结束。

这有两个后果:

① 正文要写成「常驻指令」,不是「一次性步骤」。 它不会在后面几轮重新读这个文件。

② 正文要简洁。 官方对写法的建议是:

说做什么,而不是叙述怎么做和为什么。 用和 CLAUDE.md 一样的简洁标准。

因为它每一轮都在那儿占着地方。

长内容怎么办:渐进式披露

官方建议 SKILL.md 不超过 500 行。

超了就往外拆:

interview-coding/
├── SKILL.md          ← 概览和导航
├── reference.md      ← 完整的编码规范,用到时才读
├── examples.md       ← 示例,用到时才读
└── scripts/
    └── check.sh      ← 脚本,是执行不是读取

然后在 SKILL.md 里指路:

Markdown
## 补充资料

- 完整的编码规范见 [reference.md](reference.md)
- 输出示例见 [examples.md](examples.md)

关键在于「指路」这一步。 不写清楚每份文件是什么、什么时候该读,它不会去读。

这套做法的原理见上下文工程

带参数

/fix-issue 123

SKILL.md 里用 $ARGUMENTS 接住。想要提示的话:

YAML
---
description: ...
argument-hint: [访谈目录]
---

输入 / 的时候会显示这个提示。

三个实用技巧

① 让它把命令的输出直接嵌进来

SKILL.md 里写:

Markdown
## 当前情况
- 目录内容:!`ls interviews/`

反引号加感叹号的那段命令,会在内容送到它面前之前就先执行掉,输出替换进去。

这是预处理,不是它执行的。 好处是它拿到的第一眼就是真实情况,不用先去查一遍。

② 一次调多个

/写规范 /fix-issue 123

可以在一条消息开头堆叠技能,最多第一个加后面 5 个。

③ 让它自己给你写

不用手写。直接说:

可复制的提示词
我每次整理访谈稿都要重复说这些要求:〈把你的要求粘上〉
帮我做成一个技能,放在 ~/.claude/skills/ 下面。

复制为纯文本,换行与缩进原样保留,可直接粘贴进对话框。

它会建目录、写文件。 更系统的做法见用元提示词生成 Skill,用 /doctor 精简配置

管理

命令 做什么
/skills 列出所有技能。t 按占用大小排序,按空格切换可见性
/doctor 找出装了从来没被调用过的
/context 看技能清单占了多少地方

/skills 里那个「按占用大小排序」很有用。 技能清单本身是有预算的——默认是上下文窗口的 1%,超了会从最少用的开始丢描述。

也就是说:装太多技能,会让你真正常用的那个反而不被列出来。

一条安全提醒

从别处拿来的项目,它的 .claude/skills/ 里可能有技能。

技能里的 allowed-tools 可以给自己授予相当宽的工具权限。

官方明确提醒:信任一个仓库之前,先看一眼它的项目技能。

Claude Code 有一道防线——项目技能里的 allowed-tools 要你接受了那个文件夹的信任对话框之后才生效。 但这道防线要你自己不乱点。

做完之后

别急着用。先验证它真的生效了。

技能有一个特别容易误判的地方:你写完技能之后立刻测试,而此时你写技能时的那些对话内容还在上下文里——它照做可能是因为你刚跟它讲过,不是因为技能生效了。

正确的做法是开一个全新的会话、换一个空目录测。 完整方法见规则生效性的验证方法

本节事实查证日期:2026-08-05。 依据:官方 Extend Claude with skills

← 回到手册目录