2. SKILL.md 的结构
这是什么:SKILL.md = 一份 YAML 头 + Markdown 身的说明书。规范只定义了六个 frontmatter 字段和一个目录约定,剩下都随你写。
为什么用:字段不是随便起的——name 决定命令名,description 决定它能不能被选中,allowed-tools 决定它能直接用什么工具。写错了不是报错,是技能悄悄不生效。
如何用:本章把六个字段的规矩逐个讲清,再讲正文怎么组织、文件怎么引用,最后用 skills-ref 校验一遍。
2.1 目录结构:一份必需文件 + 三个可选目录
规范的最小要求只有一个文件,但复杂技能会带上几个约定目录:
my-skill/
├── SKILL.md # 必需:元数据 + 说明书
├── scripts/ # 可选:可执行脚本
├── references/ # 可选:详细参考文档
├── assets/ # 可选:模板、图片、数据表
└── ... # 其它任意文件
三个可选目录的分工是固定的:
| 目录 | 放什么 | 加载时机 |
|---|---|---|
scripts/ |
能跑的代码(Python / Bash / JS) | Agent 按需执行 |
references/ |
长文档:REFERENCE.md、FORMS.md、领域资料 |
Agent 按需读 |
assets/ |
静态资源:模板、配置样例、图 | Agent 按需取用 |
规范里那句「SKILL.md 保持在 500 行以内」不是建议,是硬约束的软化版:正文一旦过长,就说明该把细节搬进 references/ 了。
2.2 frontmatter 六个字段
规范的 frontmatter 只有六个字段,全部写在这里:
---
name: pdf-processing
description: 提取 PDF 文本、填写表单、合并 PDF。处理 PDF 文件或用户提到 PDF、表单、文档提取时使用。
license: Apache-2.0
compatibility: 需要 Python 3.14+ 与 uv
metadata:
author: example-org
version: "1.0"
allowed-tools: Read Bash(pdftotext:*) Bash(qpdf:*)
---
逐个说明:
| 字段 | 必填 | 约束 | 说明 |
|---|---|---|---|
name |
✅ | ≤ 64 字符 | 只能用小写字母、数字和单个连字符;必须和所在目录名一致 |
description |
✅ | 1~1024 字符 | 说明「这个技能做什么」+「什么时候该用它」 |
license |
❌ | 短字符串 | 许可证名称,或指向技能包内的许可证文件 |
compatibility |
❌ | ≤ 500 字符 | 环境要求:目标产品、系统依赖、要不要联网 |
metadata |
❌ | 字符串 → 字符串映射 | 放作者、版本这类自定义信息,客户端一般不解释 |
allowed-tools |
❌ | 空格分隔的字符串 | 预授权工具(实验性),各家支持程度不一 |
name 的硬规矩
规范对 name 的限制相当严格,踩了就是加载失败:
name: pdf-processing # ✅
name: data-analysis # ✅
name: PDF-Processing # ❌ 大写不行
name: -pdf # ❌ 不能以连字符开头
name: pdf--processing # ❌ 不能有连续两个连字符
等效的正则是 ^[a-z0-9]+(-[a-z0-9]+)*$。另外注意:name 要和文件夹名一致——目录叫 pdf-processing,name 就得写 pdf-processing。
description 决定生死
对比两版:
# ❌ 差:Agent 根本不知道什么时候该用它
description: Helps with PDFs.
# ✅ 好:做什么 + 什么时候用 + 关键词
description: Extracts text and tables from PDF files, fills PDF forms, and merges multiple PDFs. Use when working with PDF documents or when the user mentions PDFs, forms, or document extraction.
规范的建议是:description 里既说功能也说触发场景,并塞进具体关键词。因为它会被拼进 Agent 的技能目录,是模型检索时唯一的依据。
2.3 工具的私有扩展字段
各家工具会在规范六个字段之外加自己的字段,比如 Claude Code 支持:
| 字段 | 作用 |
|---|---|
disable-model-invocation: true |
只允许人手动触发,模型不能自己用 |
user-invocable: false |
只给模型用,不在命令菜单里露脸 |
context: fork |
在独立子代理里跑,不污染主上下文 |
paths |
只在处理匹配路径的文件时才自动加载 |
argument-hint / arguments |
命令提示与参数占位 |
但这些字段不能随便带。要上传到 claude.ai 或者走 Skills API 时,只认规范那六个字段,多一个就直接硬报错:
Unexpected key(s) in SKILL.md frontmatter: argument-hint. Allowed properties are: allowed-tools, compatibility, description, license, metadata, name
所以规矩是:要跨工具复用,就守住规范六个字段;只在某个工具里用,才加它的私有字段。本栈后面所有例子都按规范写。
2.4 正文怎么写
正文没有格式限制,但规范给了三条推荐:
- 分步骤的指令(怎么做)
- 输入输出示例(做成什么样算对)
- 常见边界情况(什么时候别这么干)
还有一条经验来自 Claude Code 的官方文档:技能一旦加载,正文会在多轮之间一直留在上下文里,所以每一行都是重复的 token 开销。写「做什么」,别写「为什么要这么做」——理由是你(人)看的,步骤是 Agent 看的。
🤝 记忆口诀:frontmatter 写规矩,正文写步骤;六个字段保兼容,私有字段慎加码。
2.5 引用别的文件
引用用相对于技能根目录的路径,并且只引用一层:
详见 [参考指南](references/REFERENCE.md)。
执行抽取脚本:
scripts/extract.py
别搞成 references/guide/advanced/REFERENCE.md 这种三层套娃——Agent 每次都要顺着猜,深了容易迷路,也容易让引用链断掉。
2.6 校验:skills-ref
规范官方提供了一个 Python 参考库 skills-ref 来做校验:
pip install skills-ref
skills-ref validate ./my-skill
你会看到(示意):
my-skill: OK
✓ frontmatter 字段合法
✓ name 与目录名一致
✓ name 符合 ^[a-z0-9]+(-[a-z0-9]+)*$
✓ description 长度 87 ≤ 1024
它只查格式,不查内容好不好——但格式不过的工具根本不会加载,先过这关再说。
动手改
- 照着第 2.2 节建一个
pdf-processing技能目录,SKILL.md六个字段全写上,然后故意把name改成大写,跑skills-ref validate看它怎么报错 - 给你现有的某个技能(哪怕是刚写的草稿)补一个
references/REFERENCE.md,把正文里啰嗦的部分挪进去,对比一下正文行数变化 - 给技能加一个私有字段(比如
argument-hint),跑一次校验,确认规范校验器只报格式问题——再想想这个技能如果要上传到 claude.ai 会发生什么
小结
- 目录:
SKILL.md必需,scripts/references/assets/按需;正文别超 500 行 - 规范六个字段:
namedescriptionlicensecompatibilitymetadataallowed-tools name只允许小写字母数字和单连字符,且必须等于目录名;description要写清「做什么 + 何时用」- 工具私有字段(
disable-model-invocation、context: fork等)只在自家用,跨工具复用时别带 - 引用文件用相对路径、只一层;用
skills-ref validate把格式关先过了
下一章:渐进式披露,搞清楚「描述写不好,技能就选不中」到底怎么回事 🐸