Claude Code Skills 体系学习大纲

目标:从零理解 Claude Code 的 Skills 系统 — 为什么设计、怎么工作、如何编写优秀 Skill。
参考来源:官方 Docs | Agent Skills Spec | GitHub


第一部分:为什么需要 Skill?

1.1 核心问题

痛点说明
Context Window 有限每个 Skill 的完整指令可能数千词,全部加载会耗尽上下文预算
Token 成本高昂不区分场景地注入所有 Prompt 是巨大的浪费
能力扩展困难每次增加新功能都要改代码 → 难以社区化、可组合
触发粒度粗糙Slash command 只能由用户手动输入,无法自动感知场景

1.2 Skill 的设计哲学

传统方案:    所有功能硬编码 → 系统提示越来越长 → token 爆炸 ❌
Skill 方案:  按需加载     → 元数据常驻 + 正文惰性   → token 可控 ✅

三个关键机制:

  1. 渐进式披露(Progressive Disclosure) — 只加载必要的信息到 context 中
  2. 语义匹配(Semantic Matching) — 根据用户当前意图自动激活相关 Skill
  3. 标准化格式(SKILL.md) — YAML Frontmatter + Markdown Instructions,跨工具兼容

1.3 Skill vs Slash Command 的演进关系

早期:  Slash Commands (/command) — 纯手动触发,需用户知道命令名称
现在:  Skills (/skill-name)      — 自动+手动双触发,系统根据上下文推荐
趋势:  Slash Commands 被逐步吸收进 Skill 体系

第二部分:Skill 的定义、规范与设计原则

2.1 文件结构与存放位置

SKILL.md 文件结构

---                      # ← YAML Frontmatter:元数据(约 40-100 tokens)
name: skill-name         #   必填:唯一标识 + 斜杠命令名
description: >           #   必填:做什么 + 何时用(单行!)
allowedTools: [...]      #   可选:工具白名单
context: fork            #   可选:隔离执行环境
model: sonnet            #   可选:指定模型
effort: high             #   Optional: 推理深度
priority: high           #   Optional: 触发优先级
paths: [...];            #   Optional: 路径匹配规则
hooks:                   #   Optional: 生命周期钩子
  - event: beforeToolUse
    type: prompt
    prompt: "检查权限"
---                      # ← 分割线

# ← Markdown Instructions:完整指令(仅在激活时加载)

你是安全审计助手...

同名 Skill 高优先级覆盖低优先级。

2.2 Frontmatter 字段详解

必填字段

字段类型约束作用
namestring≤64字符;小写+数字+连字符;必须与父目录同名技能标识符,同时成为斜杠命令名(如 /security-audit
descriptionstring≤1024字符;必须是单行核心触发文本 — 描述做什么 + 何时用

⚠️ 注意:description 就是 whenToUse — 没有独立的 whenToUse 字段。最佳写法:

description: >-
  Analyze code for security vulnerabilities (SQL injection, XSS, hardcoded secrets).
  Trigger when user mentions "security", "audit", "vulnerability", or "before commit".
  Do NOT use for general code review or performance analysis.  

可选字段 — 能力扩展类

字段值域作用
allowedTools["Read", "Write", "Bash(git *)"]工具白名单,执行时无需权限弹窗;支持通配符模式
context"fork" / 默认fork 时在隔离子 Agent 中执行,防止 memory bleed
modelhaiku, sonnet, opus, fable为该 Skill 指定模型,实现成本/性能调优
effortlow, medium, high, xhigh, max控制推理深度
priority枚举值影响自动触发的积极程度

可选字段 — 交互增强类

字段作用
argument-hint斜杠命令补全时显示的提示文字
arguments命名参数映射,支持 $1, $2, $ALL 等占位符
paths文件 glob 模式,匹配的文件会影响触发概率
user-invocable是否允许用户手动触发(还是仅自动触发)

Hooks — 生命周期钩子

hooks:
  - event: beforeToolUse       # 触发时机
    type: prompt               # 行为类型:command / http / prompt / agent
    prompt: "确认工具调用合理"

支持的 Events:beforeSessionStartafterSessionStartbeforeTaskUseafterTaskUsebeforeToolUseafterToolUsebeforeResponseafterResponse 等(共 ~18 种)。

🐛 已知 Bug (#17688):SKILL.md frontmatter 中的 skill-scoped hooks 在某些情况下可能不会正确触发。

2.3 内置 Skill 列表

命令描述
/simplify代码质量审查 + 自动修复
/batch并行执行多文件/多输入任务
/debug结构化调试 walkthrough
/loop定时循环任务调度
/claude-apiAnthropic API 参考查询
/code-reviewDiff 扫描(bug + 复用性优化)
/skillify元 Skill:通过对话将工作流转化为新的 SKILL.md

2.4 Token 消耗模型

启动时:每个 Skill 仅加载 name + description ≈ 40-100 tokens
──────────────────────────────────────────────────────
运行时:只有匹配的 Skill 才会注入完整 Markdown Instructions
──────────────────────────────────────────────────────
示例:10 个 Skill
  基线开销 = 系统提示 (~2K) + 元数据 (10 × 80 = 800) ≈ 3K tokens
  激活 1 个后 = 3K + skill_body (~2K) ≈ 5K tokens

2.5 设计原则总结

  1. 最小元数据原则 — Frontmatter 越精简越好,详细信息放 Markdown body
  2. 描述即触发器description 要包含关键词 + 排除场景,减少误触发
  3. 按场景选模型 — 简单检查用 Haiku,复杂分析用 Opus
  4. 权限最小化allowedTools 只声明真正需要的工具
  5. 边界清晰 — 用 Do NOT 明确说明何时不该使用该 Skill
  6. 指令结构化 — Markdown body 使用编号步骤、条件分支,便于模型遵循

2.6 Skill 的完整目录结构

Skill 目录内部结构

skill-name/                         # Skill 根目录
├── SKILL.md                        # ⚠️ 必须存在,必须命名为 SKILL.md
│                                   # 包含 YAML frontmatter + Markdown body
├── templates/                      # 可选:Prompt 模板、输出模板
│   ├── prompt.tmpl                 # 复杂 Skill 可拆分 prompt 模板
│   ├── output.json.tmpl            # 结构化输出模板
│   └── report.md.tmpl              # 报告生成模板
├── scripts/                        # 可选:辅助脚本(用于 hooks 或工具调用)
│   ├── analyze.sh                  # Bash 脚本
│   ├── validate.py                 # Python 脚本
│   └── helper.js                   # Node.js 脚本
├── assets/                         # 可选:静态资源
│   ├── icons/                      # UI 图标(未来可能支持)
│   └── examples/                   # 示例文件
│       └── sample-output.md
├── README.md                       # 可选:Skill 使用说明文档
│                                   # 对用户可见,不加载到 context
├── config.json                     # 可选:Skill 运行时配置
│                                   # 非标准字段,需在 SKILL.md 中引用
└── tests/                          # 可选:Skill 测试用例
    └── test-skill.sh               # 验证 Skill 行为的测试

文件优先级与加载顺序

Skill 发现优先级(同名覆盖)
─────────────────────────────────────

1. User-level    ~/.claude/skills/<name>/SKILL.md    ← 最高优先级
    ↓ 覆盖
2. Project-level .claude/skills/<name>/SKILL.md
    ↓ 覆盖  
3. Bundled       <internal>/<name>/SKILL.md          ← 最低优先级

加载时机:
• Claude Code 启动时扫描所有层级
• 按优先级合并,只保留最高优先级的定义
• 项目级 Skill 仅在该项目目录下生效
• 用户级 Skill 全局生效

多 Skill 协作目录布局

.claude/
├── skills/
│   ├── security-audit/          # 安全审计
│   │   └── SKILL.md
│   │
│   ├── performance-check/       # 性能分析
│   │   └── SKILL.md
│   │
│   ├── doc-generator/           # 文档生成
│   │   ├── SKILL.md
│   │   └── templates/
│   │       └── api-doc.md.tmpl
│   │
│   └── full-review/             # 组合 Skill(调用其他 Skill)
│   │   ├── SKILL.md
│   │   └── config.json          # 定义调用顺序
│   │
│   └── shared/                  # 共享资源目录(非 Skill)
│       ├── common-prompts.md    # 被多个 Skill 引用
│       └── templates/
└── hooks/
    ├── pre-commit.sh            # 全局 hook,影响所有 Skill
    └── post-tool-use.sh

目录结构最佳实践

实践原因
保持 SKILL.md 精简只有 SKILL.md 会加载到 context;辅助文件通过工具调用
复杂 Prompt 拆分到 templates降低 Token 消耗,按需加载
脚本放 scripts/通过 allowedTools: Bash 调用,不影响 context
README.md 写使用说明对用户友好,不消耗 context tokens
避免深层嵌套Claude Code 只扫描一层子目录

第三部分:Skill 的使用方式

3.1 手动触发(显式调用)

用户可以直接输入斜杠命令来触发 Skill:

用户输入: /security-audit
系统行为: 立即激活 security-audit Skill,注入完整指令

手动触发的特点:

  • 确定性:用户明确知道要使用哪个 Skill
  • 优先级最高:忽略语义匹配过程
  • 适用场景:用户对可用 Skill 有明确认知时

命名规范:

# SKILL.md
name: my-skill-name    # 会变成 /my-skill-name
# 命名建议:
#   - 使用连字符分隔:code-review 而非 codeReview
#   - 语义清晰:security-audit 而非 sec-aud
#   - 避免冲突:不要与内置 Skill 重名(除非有意覆盖)

3.2 自动触发(语义匹配)

系统会根据用户的自然语言输入,自动判断是否需要激活某个 Skill:

用户输入: "帮我检查这段代码有没有安全漏洞"
系统行为:
  1. 语义匹配阶段
  2. 发现 "安全漏洞" 与 security-audit Skill 的 description 高度相关
  3. 自动注入 security-audit 的完整指令
  4. 执行安全审计任务

自动触发的关键要素:

要素说明示例
description核心触发器,包含关键词 + 场景描述"Analyze for security vulnerabilities. Use when user mentions 'security', 'vulnerability'..."
paths文件路径匹配,增加触发权重["**/*.js", "**/*.py"]
priority控制触发的积极性high = 更容易被激活
上下文相关性用户当前对话历史、文件内容等讨论代码时更容易触发 code-review

语义匹配机制:

评分公式(简化):
  match_score =
    keyword_overlap(user_message, skill_description) × weight1
    + path_relevance(current_files, skill_paths) × weight2
    + priority_boost × weight3

  if match_score > threshold:
    activate(skill)

3.3 组合使用模式

模式 1:手动 + 自动混合

# 场景:用户在讨论性能优化,然后想进行安全审计
用户: "这段代码性能怎么样?"        # → 自动触发 performance-check
系统: [性能分析报告]
用户: "/security-audit"           # → 手动触发安全审计
系统: [安全审计报告]

模式 2:链式 Skill 调用

某些 Skill 可以在内部调用其他 Skill:

# full-review/SILL.md
name: full-review
description: Comprehensive code review combining security and performance analysis

---
# Markdown body
执行全面代码审查流程:
1. 首先调用 /security-audit 检查安全问题
2. 然后调用 /performance-check 分析性能瓶颈
3. 综合两个结果生成最终报告

模式 3:参数化调用

通过 arguments 字段支持参数传递:

name: code-review
arguments:
  - name: scope
    description: Review scope (file|module|project)
    default: file
  - name: focus
    description: Focus areas (security|performance|style)
    default: all

---
# 用户可以这样调用:
# /code-review scope=project focus=security

3.4 实战示例

示例 1:自动触发安全审计

用户: [打开一个包含数据库查询的 Python 文件]
用户: "帮我看看有没有 SQL 注入风险"

系统行为:
  ✓ 扫描所有 Skill 元数据
"SQL 注入" 与 security-audit description 匹配
  ✓ 当前文件路径匹配 paths: ["**/*.py"]
  ✓ 激活 security-audit,注入完整指令
  ✓ 执行安全分析,返回结果

示例 2:手动触发代码简化

用户: "/simplify"

系统行为:
  ✓ 用户显式调用 simplify Skill
  ✓ 扫描当前代码变更
  ✓ 分析可简化、可复用的代码模式
  ✓ 提出重构建议或自动修复

示例 3:多 Skill 协作

# 场景:准备提交代码
用户: "我要提交代码了,帮我做最后的检查"

系统可能依次触发:
1. /code-review   → 检查代码质量
2. /security-audit → 安全审计(如果发现敏感操作)
3. /simplify      → 优化代码结构

最终输出:综合报告

3.5 使用最佳实践

对用户而言

实践原因
明确时手动,模糊时自然知道要什么用 /command,探索时自然描述需求
查看可用 Skill/help/skills 查看项目可用技能
信任自动触发系统语义匹配准确率高,先让它自动工作
覆盖低质量 Skill如果内置 Skill 效果不好,创建同名自定义 Skill 覆盖
组合使用复杂任务可以用多个 Skill 协作完成

对 Skill 开发者而言

实践原因
优化 description这是触发器的核心,要包含关键词 + 使用场景
合理设置 priority高频核心 Skill 设 high,小众工具默认即可
用 paths 缩小范围只在相关文件类型下触发,避免误激活
提供 argument-hint帮助用户理解如何传参
写清晰的 README.md对用户友好,不影响 token 消耗

3.6 常见问题与排查

Q1: Skill 没有自动触发?

检查项:
□ description 是否包含用户可能使用的关键词?
□ paths 是否匹配当前文件类型?
□ priority 是否设置过低?
□ 是否有更高优先级的同名 Skill 覆盖?
□ SKILL.md 文件是否放在正确的目录?

Q2: 手动调用报错 “Skill not found”?

检查项:
□ name 字段是否与目录名一致?
□ 文件是否命名为 SKILL.md(必须大写)?
□ 是否放在 .claude/skills/<name>/ 或 ~/.claude/skills/<name>/?
□ 是否重启了 Claude Code?(某些情况需要重启)

Q3: 多个 Skill 同时触发?

行为:
  • 多个 Skill 可能同时被激活
  • 系统会按优先级排序执行
  • 或合并到一个综合响应中

最佳实践:
  • 避免创建功能重叠的 Skill
  • 或用 description 明确区分使用场景

第四部分:渐进式披露(Progressive Disclosure)

4.1 三阶段加载流程

┌─────────────────────────────────────────────────────────┐
│ Phase 1: Startup(启动时)                               │
│ ─────────────────                                     │
│ • 扫描所有 .claude/skills/ 和 ~/.claude/skills/          │
│ • 仅读取每个 SKILL.md 的 YAML frontmatter                │
│ • 注入 Context:[name, description] per skill            │
│ • Token 消耗:n 个 Skill ≈ n × (40~100) tokens          │
└─────────────────────────────────────────────────────────┘
                        ▼ 用户输入消息
┌─────────────────────────────────────────────────────────┐
│ Phase 2: Semantic Matching(语义匹配)                    │
│ ──────────────────────                                  │
│ • 将用户消息与所有 loaded description 做语义对比          │
│ • 基于 prompt classification(非 embedding),在模型侧完成  │
│ • 匹配成功的 Skill:将其 Markdown Instructions 注入 context│
│ • 未匹配的 Skill:继续休眠,零额外成本                     │
└─────────────────────────────────────────────────────────┘
                        ▼ Skill body 已注入
┌─────────────────────────────────────────────────────────┐
│ Phase 3: Execution(执行)                                │
│ ──────────────────                                      │
│ • 模型按 Skill 的 Markdown 指令执行                       │
│ • 若 context: fork → 派生子 Agent 隔离执行                 │
│ • allowedTools 生效:白名单工具免弹窗                      │
│ • hooks 按事件触发                                        │
└─────────────────────────────────────────────────────────┘

4.2 图示理解

Context Window 视角
═══════════════════════════════════════════════

Phase 1          │ System Prompt
                 │ [Skill1: name="security", desc="Analyze for vulns..."]
                 │ [Skill2: name="debug",     desc="Structure debugging..."]
                 │ [Skill3: name="review",    desc="Code review for bugs..."]
                 │ ... (所有元数据紧凑排列)

Phase 2          │ System Prompt
                 │ [所有元数据...]
                 │ ╔═══════════════════════════╗
                 │ ║ ← 匹配到的 Skill Body     ║
                 │ ║ "你是一个安全审计助手..."   ║    ← 动态插入
                 │ ╚═══════════════════════════╝

Phase 3          │ System Prompt
                 │ [所有元数据...]
                 │ [Skill Body...]
                 │ User: "帮我看看这段代码有没有 SQL 注入"
                 │ → 模型按指令执行 → Tool Use → Response

4.3 为什么这样设计?

维度一次性全量加载渐进式披露
启动开销O(∑ 所有 body)O(n × metadata)
Token 成本每轮都支付仅支付活跃 Skill
扩展性添加 Skill = 永久增长新增 Skill 不影响基线
精确度大量无关干扰只注入相关内容

4.4 开发者视角:如何控制披露粒度

# 技巧 1:把通用逻辑放 body,专用细节放 hooks
# (hook 只在特定事件才注入)

# 技巧 2:用 model 字段分层
# 简单验证用 haiku(便宜快),深度分析用 opus(贵但准)

# 技巧 3:用 priority 控制匹配积极性
# 高频场景设 high,低频场景省略

# 技巧 4:用 paths 限定触发范围
# 只对特定文件类型激活,减少误匹配

4.5 内置与自定义 Skill 的生命周期对比

维度内置 Skill自定义 Skill
存在位置CLI 二进制内部.claude/skills/~/.claude/skills/
能否修改不能(随版本更新)能(热重载)
Token 代价始终计入(有人提议可关闭)完全可控
覆盖关系可被同名自定义 Skill 覆盖覆盖同名的内置 Skill

延伸阅读