先说几个核心观点:SKILL.md 是 Claude Code 体系中最基础、也最具潜力的扩展单元。它不仅仅是一个配置文件,更像是一个可复用的“认知微服务”——你可以为其配置触发条件、限定工具权限、设定执行上下文,甚至挂载生命周期钩子。深入理解 SKILL.md 的设计逻辑,基本就能掌握 Claude Code 的工程化搭建思路。
从一个实际应用场景出发:假设你期望 Claude 在审查代码变更时,能自动识别安全漏洞、风格违规以及性能瓶颈,而无需每次都手动编写一遍提示词。这时,你所需的正是这样一个 Skill。
Skills
一个 Skill 的目录结构大致如下:
SKILL.md← 导航页:概述 + 引用(< 500 行)├── reference.md← 详情页:具体内容├── examples.md ← 详情页:使用示例└── scripts/make.sh ← 工具:可执行脚本
其中 SKILL.md 的顶部是 YAML 格式的 frontmatter,负责定义技能的行为模式;正文 Markdown 内容则告知 Claude 具体该执行哪些任务。

Frontmatter 字段一览
| 字段 | 必需 | 类型 | 说明 |
|---|---|---|---|
name |
否 | 字符串 | 技能标识符,同时也是 /slash-command 的名称,默认取自目录名 |
description |
推荐 | 字符串 | 用于告知 Claude 何时加载该技能,是自动触发的核心依据 |
disable-model-invocation |
否 | 布尔 | 设为 true 时禁止 Claude 自动触发,仅允许用户通过 /name 手动调用 |
user-invocable |
否 | 布尔 | 设为 false 时用户不可调用,仅作为 Claude 的背景知识使用 |
allowed-tools |
否 | 字符串列表 | 限制技能激活时可使用的工具,形成安全屏障 |
argument-hint |
否 | 字符串 | 自动补全提示,例如 [issue-number] |
context |
否 | 字符串 | 设为 fork 时技能在子会话中隔离运行,无主对话上下文 |
agent |
否 | 字符串 | 当 context: fork 时指定子会话类型,例如 Explore |
hooks |
否 | 对象 | 技能级别的生命周期钩子,在特定工具调用前后执行脚本 |
paths |
否 | 字符串/列表 | Glob 模式,限制技能仅在匹配的文件上自动激活 |
shell |
否 | 字符串 | !command`` 块所使用的 shell,bash(默认)或 powershell |
mode |
否 | 布尔 | 设为 true 标记为“模式命令”,用于修改 Claude 的行为或上下文 |
description —— 技能的“灵魂”
description 并非写给人类阅读,而是为 Claude 设计的语义触发器。撰写时可套用一个简单的公式:[做什么] + [怎么做] + [什么时候用]。
description: 审查代码质量、安全性和最佳实践。检查 bug、性能问题和风格违规。用于用户请求代码审查、希望获得代码反馈、提到审查更改或询问代码质量时。
disable-model-invocation —— 控制谁能触发
对于那些具有副作用的操作——比如部署、发送消息、提交代码——强烈建议将其设置为 true,以防止 Claude 自作主张。举个例子:
disable-model-invocation: true # 仅用户可通过 /deploy 手动触发
user-invocable —— 控制用户可见性
如果某个技能属于背景知识(例如遗留系统说明),且不希望暴露在用户菜单中,可以将其设置为 false。这样 Claude 仍可自动按需加载,但用户无法通过 / 命令直接触发。
user-invocable: false # 用户菜单隐藏,Claude 自动按需加载
allowed-tools —— 工具安全屏障
通过限定工具集,可以实现“只读分析”或“可执行命令”等不同安全等级的技能:
# 只读分析型技能
allowed-tools: Read Grep Glob
# 需要执行命令的部署型技能
allowed-tools: Bash
context: fork —— 隔离执行
技能在独立子会话中运行,无法访问主对话历史,非常适合自包含的工作流:
context: fork
agent —— 指定子会话类型
与 context: fork 搭配使用,指定隔离运行时的会话类型:
context: fork
agent: Explore # 使用 Explore 会话,擅长代码库探索和调研
主会话仅接收子会话的摘要结果,从而有效保持主上下文窗口的精简性。
hooks —— 技能级生命周期钩子
在技能激活期间,特定工具调用前后可以自动执行脚本——例如安全检查、代码格式化等:
hooks:
PreToolUse:
- matcher: Bash
command: ./scripts/security-check.sh
PostToolUse:
- matcher: "Write|Edit"
command: ./scripts/lint-fix.sh
paths —— 文件范围限定
限制技能仅在操作匹配的文件时自动激活,避免在不相关的场景中加载:
paths: "src/api/**/*.ts"
# 或多个模式
paths:
- "src/api/**/*.ts"
- "src/models/**/*.ts"
完整示例
将以上字段组合起来,即可构成一个完整的 Code Review Skill:
---
name: code-review
description: 审查代码变更的质量和安全性。用于用户请求审查、提到 review 或询问代码质量时。
disable-model-invocation: false
allowed-tools: Read Grep Glob
---
# Code Review Skill
## 审查步骤
1. 读取变更文件
2. 检查安全漏洞、性能问题
3. 输出审查报告
两种技能类型
参考型
参考型技能的核心特点是没有执行步骤,没有固定输出模板,不设置 disable-model-invocation,工具权限限定为只读。Claude 可以自动判断是否需要加载。
---
name: git-commit-guidelines
description: "提供 Git 提交信息规范和示例,适合用于检查提交信息格式、生成标准化提交说明。"
---
# Git Commit Guidelines
一个参考型 Skill,用于给出 Git 提交信息的规范和最佳实践,不要求生成固定输出格式。
## 何时使用
当用户需要:
- "帮我写一条符合规范的提交信息"
- "Git commit message 应该怎么写"
- "提交信息格式规范是什么"
- "检查一下这条提交说明是否合理"
## 参考内容
....
### 提交信息格式
....
总结一下参考型的特征:
- 没有执行步骤:并非先做 A 再做 B,而是“遵循这些规范”。
- 没有输出模板:不要求 Claude 输出固定格式的报告。
- 没有设置
disable-model-invocation:Claude 可以自动判断何时需要。 - 只读工具:
allowed-tools限制为 Read/Grep/Glob。
任务型
与参考型正好相反,任务型技能需要明确的执行步骤、具体的输出模板以及足够的文件执行权限。通常通过 /skill-name 触发,或者让智能体自动判断触发时机,输出结构化结果。
---
name: repo-refactor
description: 自动执行代码重构、格式化和提交建议。用于用户请求"帮我修复代码风格"、"重构这个模块"或"请生成可执行的修复步骤"时。
disable-model-invocation: true
allowed-tools:
- Read
- Grep
- Bash
---
# Repo Refactor Skill
## 任务说明
1. 阅读变更文件和代码段
2. 自动检查风格/重构问题
3. 生成修复命令或补丁
4. 返回结构化执行结果
## 输出模板
- status: success|failure
- summary: 简要说明
- steps:
- description: 步骤说明
command: 具体命令或修复建议
command 类型
command 的目录是 .claude/commands/,本质上是带参数的提示词模板,必须由用户通过 /command-name 手动触发,不会被智能体自动执行。
与 Skill 的核心区别:
| 对比项 | Skill(SKILL.md) | Command(.claude/commands/) |
|---|---|---|
| 触发方式 | 用户手动 + 智能体自动 | 仅用户手动 /name |
| 有 description | 是(语义触发器) | 否 |
| 有 frontmatter | 是(完整配置) | 否(纯 Markdown) |
| 适用场景 | 可复用的认知能力 | 一次性的参数化任务 |
示例:翻译文件
文件路径:.claude/commands/translate.md
将指定文件翻译为目标语言。
步骤:
1. 读取需要翻译的文件
2. 保持原有格式(Markdown 标记、代码块、链接等不变)
3. 翻译后写入同目录下的新文件,文件名添加语言后缀(如 README.en.md)
目标语言和文件路径:$ARGUMENTS
使用方式:/translate en README.md
Skill + Command 结合使用
Command 虽然需要人工触发,但可以通过 Hook 的方式整合进 Skill 执行流程中,也可以为单独的 Skill 配置专属 Command:
---
name: api-migration
description: api/ 下已存在的 App API 函数,并完成返回数据映射适配。
argument-hint: "[接口地址] 要改为的新 App API 接口地址,如 /img/list"
license: MIT
metadata:
author: libokaifa
version: "1.0"
hooks:
PostToolUse:
- matcher: "Edit|Write"
hooks:
- type: command
command: "test -f .claude/.migration-active && cat .claude/skills/api-migration/review-checklist.md || true"
timeout: 5000
statusMessage: "API 迁移代码审查中..."
---
**前置操作**:技能开始时,必须先执行 `touch .claude/.migration-active` 创建标记文件,以激活 PostToolUse 审查 hook。
**最后执行**: `rm -f .claude/.migration-active` 移除标记文件**,关闭
聪明的你可能已经注意到,示例中配置了前置条件和最后执行。这是因为 Hook 在 setting.json 中有全局配置:
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "test -f .claude/.migration-active && cat .claude/skills/api-migration/review-checklist.md || true",
"timeout": 5000
}
]
}
]
}
它的逻辑是:在执行任务型 Skill 后都会触发 PostToolUse Hook,但这里通过一个标记文件 .claude/.migration-active 来精确控制——只有当标记存在时,才会执行特定的 Command。这样设计的好处是保持了 Command 的单一性、可复用性和范围性,而不是把执行步骤写死在 Skill 内部。
总结
Skill 的设计逻辑与代码中的封装思想如出一辙。对主 Agent 来说,子 Agent 就是一个黑盒——你只需将输入传递进去,再拿回结果即可。此外,Skill 还能跨会话拉取上下文,只需在对应的 Skill 中放置参数 ${CLAUDE_SESSION_ID}。
值得一提的是,Opus 4.7 已经发布,在跨会话能力上有了明显提升,大多数场景下已经无需单独配置 CLAUDE_SESSION_ID 了。
