Files
liuzhengdong 5e965d27a4 Refactor easysdd-feature and writing-to-explain skills for clarity and structure
- Updated easysdd-feature documentation to enhance descriptions, clarify workflow stages, and improve directory organization.
- Added new guidelines for routing user actions within the easysdd-feature skill.
- Revised writing-to-explain skill to emphasize teaching over commanding, improving guidance for AI-generated content.
- Introduced a new document, what-is-skills.md, to explain the purpose and structure of skills in the Claude Code environment.
2026-04-15 15:36:10 +08:00

10 KiB
Raw Permalink Blame History

什么是 Skill——写之前先读这份

在 Claude Code 里你经常干这种事:每开一个新会话,都要把同一份操作手册贴进聊天——部署步骤、提交规范、某个框架的 API 约定、某种文档的固定写法。贴久了烦,也容易忘贴。

Skill 就是把这份手册变成一个带着 YAML 头的 Markdown 文件放在约定位置Claude 会在需要的时候自己把它读进来。跟 CLAUDE.md 不同的地方是CLAUDE.md 是每次会话一开始就全文塞进上下文的skill 的正文平时不占上下文,只有 Claude 判断该用的时候才展开。所以你可以堆一堆长篇的参考材料,平时不花钱,用的时候才花。

Skill 和过去的 custom command 已经合并。.claude/commands/deploy.md.claude/skills/deploy/SKILL.md 都生成 /deploy 斜杠命令。skill 比 command 多了一个目录装周边文件、支持 frontmatter 控制触发行为、以及让 Claude 自己按相关性调用。


放哪里

放的位置 路径 谁能用
个人 ~/.claude/skills/<skill-name>/SKILL.md 你所有项目
项目 .claude/skills/<skill-name>/SKILL.md 只在这个项目
Plugin <plugin>/skills/<skill-name>/SKILL.md 装了这个 plugin 的地方
Managed 企业统一下发 全组织

同名冲突时优先级enterprise > personal > project。plugin 用 plugin-name:skill-name 命名空间隔离不跟别的冲突。skill 和老的 .claude/commands/ 同名时skill 优先。


一个 skill 长什么样

每个 skill 是个目录,入口是 SKILL.md

my-skill/
├── SKILL.md          ← 必须,主入口
├── reference.md      ← 可选,详细参考材料(按需加载)
├── examples.md       ← 可选,例子
└── scripts/
    └── helper.py     ← 可选,脚本,由 Claude 执行不加载为上下文

SKILL.md 必须有,其他都可选。周边文件要在 SKILL.md 里用链接或说明引用出来Claude 才知道它们存在、什么时候该读。


SKILL.md 的 frontmatter 字段

正文前面用 --- 包一段 YAML规定这个 skill 的行为:

---
name: my-skill
description: 这个 skill 干什么、什么时候用
disable-model-invocation: false
user-invocable: true
allowed-tools: Read Grep
---

只有 description 是推荐填的。所有字段:

字段 作用
name 斜杠命令名。不填就用目录名。只能小写字母、数字、连字符,最多 64 字符
description 关键字段。Claude 靠这个判断什么时候自动调用这个 skill。不填就取正文第一段
when_to_use 补充触发条件和常见触发词。跟 description 合起来在 skill 列表里最多 1536 字符,超了被截断
argument-hint 自动补全时提示参数形式,比如 [issue-number]
disable-model-invocation true 时 Claude 不会自动调用,只能用户手动 /name 触发。适合有副作用的操作(部署、提交、发消息)
user-invocable false 时不在 / 菜单里显示,只让 Claude 自己按需调用。适合"背景知识"型的 skill
allowed-tools 这个 skill 激活时 Claude 可以免审核使用的工具。空格分隔
model / effort 这个 skill 激活时用哪个模型 / 花多少思考预算
context: fork 把这个 skill 放进 fork 出来的 subagent 跑,不污染主上下文
agent 搭配 context: fork 用,指定用哪种 agentExplore / Plan / general-purpose / 自定义)
hooks 绑定到这个 skill 生命周期的 hook
paths glob 模式。设了以后 Claude 只在操作匹配路径的文件时自动调用
shell 内联 shell 命令用什么解释器,默认 bash,可选 powershell

name 必须跟目录名一致。改 name 等于改目录名。


description 为什么这么要紧

Claude 判断要不要调用一个 skill只能看 descriptionwhen_to_use 两段话。正文平时不在它的上下文里。所以 description 必须:

  1. 写清楚这个 skill 做什么——不是"关于 X 的",而是"用来做 X"
  2. 写清楚什么时候该触发——列具体的用户说法、文件类型、任务特征
  3. front-load 最常见的触发场景——因为尾部可能被 1536 字符限制截掉

反面教材:description: 一个关于 API 设计的 skill——Claude 不知道是该在写 API 时触发、还是在 review API 时触发、还是在解释 API 给新人听时触发。

好例子:description: 写新的 API endpoint 时触发——检查命名约定、错误返回格式、请求验证。触发词:"加一个接口"、"新 endpoint"、"implement API"。不覆盖 GraphQL只管 REST。

写 description 时有个小陷阱Claude 默认偏少触发,怕用错。所以 description 要稍微往"推销"的方向写一点——"即使用户没明说 X只要任务有 Y 特征就触发",比中性描述更有效。


渐进式加载progressive disclosure

Skill 体系有三层:

  1. Metadataname + description——一直在 Claude 上下文里,判断是否触发用
  2. SKILL.md 正文——触发后才加载进上下文
  3. 周边文件 / 脚本——Claude 按 SKILL.md 的指引按需读取;脚本是执行的,不加载为上下文

这决定了 SKILL.md 的体积管理:

  • 官方建议 SKILL.md 控制在 500 行以内
  • 超了就把详细参考API 细节、长例子、完整模板)拆到同目录 reference.md / examples.md
  • 在 SKILL.md 里明确说"详细看 reference.md"Claude 才知道什么时候读

注意skill 一旦触发SKILL.md 的渲染结果进入会话就留在那里,后面不会重新读文件。所以写 SKILL.md 要写成"贯穿整个任务的指引"而不是"一次性步骤"。


Skill 内容的两种性质

思考一下你的 skill 属于哪一种,会影响怎么写:

参考型Reference——给 Claude 补一套背景知识让它用在当前对话里。API 约定、代码规范、项目领域知识、某个库的坑。这类 skill 让 Claude 按需触发即可,disable-model-invocation 留默认。

任务型Task——指导 Claude 做一个特定的多步动作。部署、提交、生成某种文档。这类你通常希望自己手动触发(/skill-name),所以给它加 disable-model-invocation: true

两种的写法也不同:参考型像文档("遇到 X 时考虑 Y"),任务型像 playbook"第一步、第二步、第三步")。


传参数给 skill

skill 里用 $ARGUMENTS 拿到用户传的所有参数:

---
name: fix-issue
description: 修 GitHub 上的某个 issue
disable-model-invocation: true
---

修 GitHub issue $ARGUMENTS按项目代码规范来。

用户跑 /fix-issue 123Claude 收到的就是"修 GitHub issue 123按项目代码规范来"。

拿单个参数用 $ARGUMENTS[N] 或简写 $N0-based

Migrate $0 component from $1 to $2.

用户跑 /migrate SearchBar React Vue$0 = SearchBar$1 = React$2 = Vue。多词参数用引号包:"hello world"。


动态注入上下文

SKILL.md 里可以写 !`<shell command>`,在 skill 发给 Claude 之前执行命令,把输出替换到 placeholder 里。适合给 skill 注入实时数据。

---
name: pr-summary
description: 总结一个 PR 的改动
allowed-tools: Bash(gh *)
---

## PR 信息
- diff: !`gh pr diff`
- 评论: !`gh pr view --comments`

## 任务
总结这个 PR……

多行命令用 ```! 开头的代码块。Claude 收到的是命令运行完的结果,不是命令本身。


让 skill 在 subagent 里跑

context: fork + agent: Explore(或别的 agent 类型skill 在一个新开的隔离上下文里跑,不看当前会话历史。适合"我要研究一下 X"这种只需要产出一份总结、不需要主会话上下文的任务。

---
name: deep-research
description: 深入研究一个话题
context: fork
agent: Explore
---

深入研究 $ARGUMENTS
1. 用 Glob 和 Grep 找相关文件
2. 读代码、分析
3. 总结发现,给出具体文件引用

注意:context: fork 只对有明确任务的 skill 有意义。纯"约定文档"型的 skill"写 API 时用这些命名"fork 进去只会看到约定但没任务,什么都不做就返回。


免审核工具 allowed-tools

allowed-tools 字段授权 skill 激活时可以免审核调用指定工具:

allowed-tools: Bash(git add *) Bash(git commit *) Bash(git status *)

这不限制有哪些工具可用(别的工具还是能调,只是会触发权限提示),只是对列出的工具免审核。


常见坑

Skill 不触发

  • 看 description 里有没有用户会自然说出的关键词
  • 在 Claude Code 里问 "What skills are available?" 确认 skill 被发现了
  • 重新措辞请求,往 description 里的说法靠
  • 直接用 /skill-name 强制触发

Skill 触发太频繁

  • description 写得更具体,缩小触发范围
  • disable-model-invocation: true 改成只手动触发

Description 被截断

  • 多个 skill 挤在一起时,每个 description 会被截到适配字符预算
  • 把最重要的触发场景前置到 description 开头
  • 单个 skill 的 description + when_to_use 合起来 1536 字符上限,超了也被截
  • 环境变量 SLASH_COMMAND_TOOL_CHAR_BUDGET 可以调高总预算

Skill 触发后效果慢慢消失

  • SKILL.md 内容在会话里不会重新读取,只是模型可能选了别的工具/方式
  • 写"贯穿任务的指引"而不是"一次性步骤"
  • 用 hooks 做硬强制
  • 长会话压缩后重新 /skill-name 再调用一次恢复上下文

进一步参考