Frontmatter 核心字段速查
SKILL.md frontmatter 中最常用的控制字段

Skills 把 CLAUDE.md 里的步骤性程序剥出来,变成按需加载的独立指令包,大幅降低日常 token 消耗。本篇完整拆解 Skills 的文件结构与四级作用域、Frontmatter 全部字段(description/disable-model-invocation/allowed-tools/paths/context 等)、调用控制三状态、动态上下文注入(!`cmd` 预处理语法)、context: fork 子 Agent 隔离执行、auto-compaction 后的 token 预算机制,以及 skillOverrides 的四种可见性控制,附五条可落地的实践建议。
Research Brief
CLAUDE.md 越来越长,token 越烧越快,而大半内容其实只在特定场景用得上。Skills 就是为了解这个问题而存在的——它把那些「按需才用」的指令从常驻上下文里剥出去,只在真正需要的时候加载进来。1.claude/commands/ 下的自定义命令文件,和 Skills 现在是同一套机制。一个 .claude/commands/deploy.md 和一个 .claude/skills/deploy/SKILL.md 都创建 /deploy 命令,效果完全相同。只是 Skills 支持更多特性——目录结构、调用控制、子 Agent 执行。SKILL.md:~/.claude/skills/summarize-changes/
└── SKILL.md # 必须my-skill/
├── SKILL.md # 主指令(必须)
├── reference.md # 详细参数文档,按需加载
├── examples.md # 样例输出
└── scripts/
└── helper.py # 可执行脚本SKILL.md 尽量控制在 500 行以内。大段参考文档放到 reference.md 里,在 SKILL.md 里说明「需要详细参数时看 reference.md」,Claude 就能在真正需要时才加载它,而不是每次调用都把全部内容一口气塞进来。SKILL.md 顶部可以加 YAML frontmatter,控制 Skill 的名称、触发条件、工具权限等行为。所有字段都是可选的,但 description 强烈建议加上:---
name: deploy-staging
disable-model-invocation: true
allowed-tools: Bash(git *) Bash(npm run *)
---| 字段 | 作用 |
|---|---|
description | Claude 据此判断何时自动调用该 Skill |
when_to_use | 补充触发场景,和 description 合并后最多 1536 字 |
disable-model-invocation | true 时 Claude 不会自动触发,只能用 /skill-name 手动调用 |
user-invocable | false 时从 / 菜单隐藏,只有 Claude 能自动加载 |
allowed-tools | Skill 激活期间免确认的工具列表 |
disallowed-tools | Skill 激活期间禁用的工具(下次发消息后解除) |
model | 覆盖当前 session 模型,本次 turn 结束后恢复 |
effort | 覆盖当前 effort 级别(low/medium/high/xhigh/max) |
context | 设为 fork 时在隔离子 Agent 中运行 |
paths | glob 模式,只有在匹配路径下工作时才自动激活 |
description + when_to_use 的合并文本在 Skill 列表里会被截断到 1536 字。把最关键的触发条件写在 description 最前面,不然在 Skill 数量多的时候可能被截掉。1| 级别 | 路径 | 覆盖范围 |
|---|---|---|
| Enterprise(企业) | Managed settings | 组织内所有用户 |
| Personal(个人) | ~/.claude/skills/<name>/SKILL.md | 你的所有项目 |
| Project(项目) | .claude/skills/<name>/SKILL.md | 仅此项目 |
| Plugin(插件) | <plugin>/skills/<name>/SKILL.md | 插件启用范围 |
plugin-name:skill-name 命名空间,不会和其他级别冲突。--add-dir 的特殊规则:通过 --add-dir 或 /add-dir 加入的目录里的 .claude/skills/ 会被自动加载,但 settings.json 里 permissions.additionalDirectories 配置的目录不加载 Skills——这个区别经常被忽视。/skill-name 调用,Claude 也可以自动触发。两个 frontmatter 字段改变这个默认行为:# 只有我能触发,Claude 不会自动跑
disable-model-invocation: true
# 从 / 菜单隐藏,只有 Claude 能自动加载(用于背景知识类 Skill)
user-invocable: false| 设置 | 你能手动调用 | Claude 能自动触发 | Description 在上下文中 |
|---|---|---|---|
| 默认 | ✓ | ✓ | 始终在 |
disable-model-invocation: true | ✓ | ✗ | 不在(也不会被搜到) |
user-invocable: false | ✗ | ✓ | 始终在 |
deploy、send-slack-message、commit 这类有副作用的操作,都应该加 disable-model-invocation: true——你不希望 Claude 因为看到代码「看起来可以了」就自己跑部署。SKILL.md 里用 !`command` 语法,可以在 Skill 内容送达 Claude 之前先执行一条 shell 命令,把输出直接替换进去。1---
---
## 当前变更 {#当前变更}
!`git diff HEAD`
## 指令 {#指令}
总结上方变更的要点,列出任何你注意到的风险…!`git diff HEAD` 先跑,真实 diff 内容替换进来,Claude 收到的是已经填好数据的完整提示词。这不是 Claude 在执行命令——是「预处理」,Claude 只看到结果。```! 代码块:## 当前环境 {#当前环境}
```!
node --version
npm --version
git status --short
一个重要的边界条件:`!` 必须出现在行首或空格之后。如果写成 `` KEY=!`cmd` ``,因为 `!` 跟在 `=` 后面,不会被执行,会原样保留为字面文本。
要禁用这个特性,在 `settings.json` 里设 `"disableSkillShellExecution": true`。企业环境里常用这个配置,防止项目 Skill 里的 shell 命令在不受控环境执行。
## 子 Agent 执行:`context: fork` {#子-agent-执行context-fork}
给 Skill 加 `context: fork`,它的内容会变成一个隔离子 Agent 的任务 prompt,在独立上下文里运行,结果汇报给主会话。这对需要大量文件读取、不想污染主会话上下文的探索性任务很有用:
```yaml
---
name: deep-research
context: fork
agent: Explore
---
深入研究 $ARGUMENTS:
1. 用 Glob 和 Grep 找相关文件
2. 读取并分析代码
3. 用具体文件引用总结发现agent 字段可以指定内置类型(Explore、Plan、general-purpose)或 .claude/agents/ 里的自定义子 Agent。省略时使用 general-purpose。context: fork 的 Skill 不会被 disable-model-invocation: true 阻止自动加载——这是文档里明确说明的一个细节。/skill-name 调用一次即可恢复完整内容。skillOverrides:不改 SKILL.md 就能控制可见性SKILL.md(比如团队仓库里的 Skill),可以在 .claude/settings.local.json 里用 skillOverrides 覆盖它的可见性:{
"skillOverrides": {
"legacy-context": "name-only",
"deploy": "off"
}
}| 值 | Claude 能看到 | / 菜单显示 |
|---|---|---|
"on" | 名称 + 描述 | ✓ |
"name-only" | 仅名称 | ✓ |
"user-invocable-only" | 隐藏 | ✓ |
"off" | 隐藏 | ✗ |
/skills 菜单里高亮一个 Skill 按 Space 可以循环切换这四个状态,Enter 保存到 .claude/settings.local.json,不需要手动编辑文件。disable-model-invocation: true,按需 /skill-name 触发。description 的首句决定触发质量
Claude 匹配 Skill 时用的是 description 文本。把最重要的触发场景放在第一句:「用户要求部署、commit 或上线时使用」比「这是一个部署工具」触发准确率高得多。paths 字段做单仓库多包隔离
monorepo 里不同包有不同规范?在各包的 .claude/skills/ 下放对应 Skill,加 paths: packages/frontend/** 这样的 glob,只在操作该包文件时才激活,避免后端 Skill 干扰前端操作。!`cmd` 的最佳用途是把动态数据喂给 Claude(当前 diff、环境变量列表、配置文件内容),而不是把完整业务逻辑塞进一条命令。逻辑复杂时写成 scripts/ 下的脚本,Skill 只调用脚本。/skill-name 调用一次刷新它在上下文里的位置。
Add more perspectives or context around this Post.