Claude Code Skills 是基于文件系统的可复用能力模块,其核心是三级渐进式披露架构:始终加载的元数据(Level 1)、触发时加载的指令(Level 2)和按需加载的资源(Level 3)。通过精心设计的 description 字段实现自动调用,并支持 context: fork 模式将任务委派给隔离的子代理执行。

Claude Code Skills 架构与创建指南:渐进式披露、自动调用与子代理执行

Agent Skills 将通用 Claude 转变为领域专家。与每次会话都需要输入的提示词不同,Skills 一次性创建,即可在所有对话中自动复用,极大地提升了工作流的效率和一致性。它们遵循开放的 Agent Skills 标准,并被 Claude Code 增强了调用控制、子代理执行等专有功能。

理解渐进式披露架构

Skills 的核心设计哲学是渐进式披露。Claude 不会在启动时一次性加载所有技能的全部内容,而是分三个阶段按需加载信息,从而高效管理上下文窗口。

三级加载机制

  1. Level 1: 元数据(始终加载)

    • 加载时机:Claude Code 启动时立即加载所有已发现技能的元数据。
    • 内容SKILL.md 文件中的 YAML frontmatter,主要包含 namedescription 字段。
    • Token 成本:每个技能约消耗 100 tokens。这意味着你可以安装大量技能而几乎不占用宝贵的上下文预算。
  2. Level 2: 指令(触发时加载)

    • 加载时机:当技能被自动匹配或用户通过 /name 显式调用时加载。
    • 内容SKILL.md 文件除 frontmatter 外的正文部分,包含工作流程和详细指导。
    • Token 成本:建议控制在 5000 tokens 以内,以保持响应效率。
  3. Level 3+: 资源(按需加载)

    • 加载时机:仅当技能执行过程中需要引用其目录下的模板、脚本等文件时加载。
    • 内容:随技能一起提供的支持文件,如模板 (template.md)、示例 (examples/)、脚本 (scripts/) 和参考文档 (references/)。
    • Token 成本:无硬性限制,因为这些文件内容通过 Bash 命令执行或被 Claude 直接读取,其内容不一定都进入上下文。

这种架构确保了高效的上下文管理:Claude 一开始只知道每个技能“存在”以及“何时使用它”,只有在真正需要时才深入了解其细节。

技能调用序列与关键机制

当用户发出一个请求(如“审查这段代码的安全性”)时,Claude 会执行以下序列:

  1. 匹配:根据启动时加载的元数据(Level 1)中的 description 字段,将用户请求与最相关的技能进行匹配。
  2. 加载指令:匹配成功后,读取该技能的 SKILL.md 正文(Level 2),获取执行任务的详细步骤。
  3. 执行与资源加载:按照指令操作。如果指令中引用了支持文件(如检查清单模板),则按需加载这些资源(Level 3)。
  4. 输出结果:基于加载的所有信息,完成任务并向用户汇报。

description 字段:自动调用的密钥

description 字段是实现自动调用的核心。它不仅需要说明技能“做什么”,更要明确“何时使用”。一个精确的描述能让 Claude 在用户提出相关问题时自动激活该技能。

  • 反面示例:“帮助处理文档”。(过于模糊)
  • 正面示例:“从 PDF 文件中提取文本和表格,填写表单,合并文档。当处理 PDF 文件或用户提及 PDF、表单、文档提取时使用。”

上下文预算限制:所有技能的 description(Level 1 元数据)总共被限制在当前上下文窗口的 1%(后备值为 8000 字符)。每个描述条目也被限制在 250 字符。如果安装的技能过多,部分描述可能会被截断。最佳实践是将最关键的触发词放在描述的开头。可以通过环境变量 SLASH_COMMAND_TOOL_CHAR_BUDGET 覆盖此限制。

SKILL.md 完整字段解析

SKILL.md 的 YAML frontmatter 是技能的“身份证”和“控制面板”。

核心字段

  • name (必需):技能的唯一标识符,仅允许小写字母、数字和连字符(最多 64 字符),且不能包含 “anthropic” 或 “claude”。
  • description (必需):如前所述,是自动调用的关键(最多 1024 字符)。

调用控制字段

通过 disable-model-invocationuser-invocable 两个字段,你可以精细控制谁可以触发技能:

场景 disable-model-invocation user-invocable 效果
默认 false (或未设置) true (或未设置) 用户和 Claude 均可调用
仅用户调用 true true (或未设置) 只有用户能通过 /name 执行,Claude 不会自动调用。适用于有副作用的操作(如 /deploy/commit)。
仅自动调用 false (或未设置) false 只能由 Claude 自动匹配并调用,不在 / 菜单中显示用户。适用于背景知识(如 legacy-system-context)。

其他重要可选字段

  • argument-hint:在 / 自动补全菜单中显示的参数提示,如 "[filename] [format]"
  • allowed-tools:限制技能可使用的工具列表(如 Read, Grep, Glob),避免意外操作。
  • model / effort:在该技能活动时临时覆盖模型(如 opus)或努力程度(low, medium, high, xhigh, max)。
  • paths:Glob 模式(如 "src/api/**/*.ts"),限制技能仅在处理匹配路径的文件时才可能被自动激活。
  • shell:指定 !`command` 动态注入和脚本执行使用的 Shell,默认为 bash,可设为 powershell
  • hooks:为该技能生命周期配置事件钩子,格式与全局钩子相同。

子代理执行模式:context: fork

这是高级功能的核心。将 context 设置为 fork,技能将在一个隔离的子代理上下文中运行,拥有独立的上下文窗口。

  • 优势:主对话不会被技能执行过程中的详细输出或中间步骤“污染”,保持对话清晰。
  • 配置:可搭配 agent 字段指定子代理类型,如 Explore(只读研究)、Plan(制定计划)、general-purpose(通用任务)或自定义代理。
  • 示例
    ---
    name: deep-research
    description: 深入研究一个主题
    context: fork
    agent: Explore
    ---
    研究 $ARGUMENTS:
    1. 使用 Glob 和 Grep 查找相关文件
    2. 阅读并分析代码
    3. 总结发现并引用具体文件
    此技能会启动一个 Explore 子代理来执行研究任务,其过程和结果不会立即显示在主会话中。

字符串替换变量

SKILL.md 正文中,你可以使用变量实现动态内容:

变量 说明
$ARGUMENTS 调用技能时传入的所有参数。
$ARGUMENTS[N]$N 按索引(从 0 开始)访问特定参数。
${CLAUDE_SESSION_ID} 当前会话 ID。
${CLAUDE_SKILL_DIR} 包含该技能 SKILL.md 文件的目录路径。
${CLAUDE_EFFORT} 当前努力程度等级(如 high),可用于实现条件逻辑(v2.1.120+)。
!`command` 动态上下文注入:在技能内容发送给 Claude 之前,立即执行 Shell 命令并将其输出内联插入。这是强大的能力,也需谨慎使用。

创建自定义技能:从结构到发布

遵循以下步骤,创建你自己的生产级技能。

第一步:规划目录结构

一个完善的技能通常包含以下结构:

my-skill/
├── SKILL.md           # 主指令文件(必需)
├── templates/         # Claude 可填写的模板
│   └── report.md
├── examples/          # 展示期望输出格式的示例
│   └── sample.md
├── references/        # 领域知识、规范文档
│   └── api-spec.md
└── scripts/           # Claude 可执行的验证或辅助脚本
    └── validate.sh

最佳实践:保持 SKILL.md 主文件在 500 行以内。将详细的参考资料、大型示例和规范文档分离到支持文件中,这些文件会在 Level 3 被按需加载。

第二步:编写 SKILL.md

---
name: generate-test-report
description: 根据测试结果生成格式化的 HTML 报告。当用户要求生成测试报告、测试摘要,或运行测试后提及“报告”、“summary”时使用。
argument-hint: "[test-results-file]"
allowed-tools: Bash(npm test *), Read, Write
context: fork
agent: general-purpose
---

# 测试报告生成技能

## 指令
1. 运行 `$1`(默认为 `npm test`)获取测试结果。
2. 解析输出,提取通过率、失败用例详情。
3. 使用 [报告模板](templates/report.html) 生成 HTML 报告。
4. 将报告保存到 `./test-report.html` 并告知用户。

## 报告格式要求
- 包含摘要部分:总用例数、通过数、失败数、通过率。
- 详细列出每个失败用例的名称、错误信息和相关日志。
- 提供指向失败用例源代码的链接(如果路径可识别)。

第三步:放置与激活

  1. 个人技能:将技能文件夹复制到 ~/.claude/skills/
  2. 项目技能:将技能文件夹放入项目的 .claude/skills/ 目录,并提交到 Git 仓库,即可与团队共享。
  3. 验证:询问 Claude “有哪些可用的 Skills?”,或直接使用 /generate-test-report 测试。

技能发现与优先级

  • 嵌套发现:当在子目录中工作时(如 packages/frontend/),Claude 也会查找该子目录下的 .claude/skills/。这非常适合 Monorepo 架构。
  • 位置优先级:当同名技能存在于多个位置时,优先级为:企业托管设置 > 个人目录 (~/.claude/skills/) > 项目目录 (.claude/skills/)。插件技能使用 插件名:技能名 的命名空间,不会冲突。
  • 子代理技能发现:从 v2.1.133 起,子代理也能像主会话一样发现并使用项目、用户和插件技能,使技能与子代理的工作流组合更加可靠。

安全与调试

  • 安全第一:仅使用来自可信来源的技能。恶意技能可能指示 Claude 执行有害的工具调用或代码。
  • 禁用动态注入:在安全敏感的环境中,可以通过在设置中将 disableSkillShellExecution 设置为 true,来禁用所有技能中的 !`command` 动态注入功能。
  • 调试技巧:如果技能未被触发,首先优化 description 字段,加入更具体的关键词。使用 /context 命令检查是否有因描述被截断而未加载的技能。

相关资源

要进一步探索,可以阅读:


FAQ

Q: 为什么我的技能没有被 Claude 自动调用? A: 最常见的原因是 description 字段描述不够具体。尝试在其中加入用户可能直接使用的关键词和短语。同时,确保技能文件位于正确的目录(如 ~/.claude/skills/your-skill/SKILL.md)。

Q: 如何防止 Claude 自动执行有副作用的技能(如部署)? A: 在该技能的 SKILL.md 的 frontmatter 中添加 disable-model-invocation: true。这样,只有用户能通过显式输入 /deploy 来触发它。

Q: 项目技能和个人技能同名时,哪个会生效? A: 默认情况下,项目技能会覆盖个人技能。你可以在 ~/.claude/settings.json 或项目的 .claude/settings.json 中通过 skillOverrides 设置调整这一行为,例如设置为 "off" 可强制个人技能优先。

Q: 技能的 description 有长度限制吗?如果太多技能描述被截断怎么办? A: 所有技能的 description 总和受限于上下文窗口的 1%(约 8000 字符)。如果安装的技能过多,部分描述可能会被截断。最佳实践是确保最关键的信息在描述的开头。你可以通过环境变量 SLASH_COMMAND_TOOL_CHAR_BUDGET 调整总预算。