Skills
Skills 基础
Skill 是一份自然语言指令文件(通常是 Markdown),教 Agent 何时以及如何完成某类任务。如果把 Agent 比作一个新入职的员工,Skill 就是给他的操作手册——不改变他"会什么",但决定他"怎么做"。
Skills 与 Function Call、MCP 的区别:
| 概念 | 本质 | 作用域 |
|---|---|---|
| Function Call | 调用外部函数的能力 | 执行层 |
| MCP | 工具集成的统一标准("AI 的 USB-C") | 执行层 |
| Skill | 注入领域知识和流程策略 | 推理层 |
Function Call 和 MCP 解决的是"怎么执行外部操作",Skill 解决的是"怎么思考和规划任务"。一个 Skill 可以引导 Agent 调用 MCP 工具或 Function Call,但它本身运行在 Agent 的上下文窗口内。
客户端怎么使用 Skills
存放位置
Skills 存放在两个层级:
- 项目级:
.claude/skills/— 跟随项目仓库,团队共享 - 用户级:
~/.claude/skills/— 跨项目个人偏好
用户级 Skills 优先级高于项目级。当同名 Skill 存在于两个位置时,用户级版本覆盖项目级。
渐进式披露(Progressive Disclosure)
Skills 不是一次性全部加载的。客户端使用三层加载策略来控制上下文占用:
Level 1: Metadata(始终在上下文中)
└─ name + description(约 100 词)
└─ 客户端据此判断是否需要加载
Level 2: SKILL.md 正文(触发时加载)
└─ 核心指令(建议 < 500 行)
└─ 包含任务流程、判断规则、输出格式
Level 3: Bundled Resources(按需加载)
└─ scripts/ — 可执行脚本
└─ references/ — 参考文档
└─ assets/ — 模板、图标等
这个设计的核心逻辑是:客户端始终把所有 Skill 的 name + description 放在上下文中供 Agent 扫描,但只有匹配当前任务的 Skill 才会被完整加载。参考文档等大文件则进一步延迟到真正需要时才读取。
触发机制
Skills 有三种触发方式:
1. 自动触发(Model Invocation)
Agent 扫描所有 Skill 的 description 字段,根据当前用户请求判断是否需要调用。这是一个语义匹配过程——不是简单的关键词匹配,而是 Agent 理解用户意图后决定是否需要某个 Skill 的指导。
用户:"帮我重构这个认证模块"
Agent 内部:匹配到 superpowers:brainstorming(需要先探索意图)
→ 匹配到 superpowers:writing-plans(多步骤任务需要计划)
2. 斜杠命令(Slash Command)
用户显式调用:/skill-name。适合用户明确知道要用哪个 Skill 的场景。
3. 组合触发
一个用户请求可以同时触发多个 Skills。Agent 按优先级顺序处理:流程类 Skill(brainstorming、debugging)优先于实现类 Skill(frontend-design、mcp-builder)。
调用控制
通过 frontmatter 字段控制 Skill 的行为:
---
name: my-skill
description: 做 X 的指南
disable-model-invocation: true # 禁止自动触发,只能 /my-skill 调用
user-invocable: false # 禁止斜杠命令调用
allowed-tools: [Read, Edit, Bash] # 限制 Skill 可用的工具
model: opus # 指定运行模型
---
参数传递
Skills 支持参数替换:
$ARGUMENTS— 用户传入的完整参数$0,$1— 按位置分割的参数
还支持动态上下文注入,通过 shell 命令实时获取信息:
当前分支状态:!`git status`
执行时,!`git status` 会被替换为实际的命令输出。
Skills 太多的影响与优化
问题:上下文膨胀
每个 Skill 的 name + description 始终驻留在上下文中。假设你有 30 个 Skills,每个 description 平均 100 词,这就是 3000 词的固定开销——在有限的上下文窗口中,这会挤压实际工作空间。
更严重的问题是触发噪音。当 Skills 过多时:
- Agent 可能在不相关的 Skill 之间犹豫,增加决策延迟
- 语义相近的 Skills 互相竞争,导致误触发
- 用户需要额外的心智模型来理解"现在有哪些 Skills 在起作用"
优化策略
1. 精简 Description
description 是触发的关键。写得越精准,误触发越少。Skill Creator 推荐的 description 优化流程:
好的 description 要"略微激进"——因为 Agent 天然倾向于不触发 Skills(undertrigger),所以描述要稍微宽泛一些。
2. 分层架构(从 3 个到 100+ 个 Skills)
当 Skills 数量超过上下文窗口能承受的范围时,需要引入分层检索:
Layer 1: Intent Router
└─ 轻量分类器,过滤掉 90% 无关 Skills
Layer 2: Skill RAG
└─ 向量检索 description,取 Top-K 最相关的
└─ 将 System Prompt 从数千行压缩到数十行
Layer 3: Dynamic Assembly
└─ 结构化 Markdown / JSON Schema 格式化
└─ 动态 few-shot 示例注入
Layer 4: Multi-Agent Decomposition
└─ Manager Agent 拆分任务
└─ 每个 Specialist Agent 只携带窄域 Skills
Layer 5: Performance Layer
└─ Context Caching 缓存静态 Skill 内容
└─ SFT 将高频 Skills 内化到模型参数中
核心思想:最好的 Prompt 不是写出来的,而是根据上下文实时组装出来的。
3. 按职责拆分 Agent
与其给一个 Agent 配 50 个 Skills,不如拆成多个 Specialist Agent,每个只带 5-10 个 Skills。Manager Agent 负责路由,Specialist Agent 负责执行。
4. 定期审计
- 删除不再使用的 Skills
- 合并功能重叠的 Skills
- 将高频 Skills 内化为 Agent 的默认行为(通过 Rules 或 Hooks)
Skills 的标准定义
目录结构
skill-name/
├── SKILL.md # 必需:核心指令文件
├── scripts/ # 可选:可执行脚本
├── references/ # 可选:按需加载的参考文档
└── assets/ # 可选:模板、图标、字体等
SKILL.md 格式
由 YAML Frontmatter + Markdown 正文组成:
---
name: docx
description: >
Use this skill whenever the user wants to create, read, edit,
or manipulate Word documents (.docx files). Triggers include:
any mention of 'Word doc', '.docx', or requests to produce
professional documents with formatting like tables of contents,
headings, page numbers, or letterheads.
---
# Docx Skill
## When to use
[具体指导...]
## Workflow
[步骤说明...]
Frontmatter 字段
| 字段 | 必需 | 说明 |
|---|---|---|
name | 是 | Skill 标识符,用于斜杠命令和引用 |
description | 是 | 触发机制的核心——描述何时使用、做什么 |
allowed-tools | 否 | 限制 Skill 可使用的工具列表 |
model | 否 | 指定运行模型(如 opus、sonnet) |
disable-model-invocation | 否 | 设为 true 禁止自动触发 |
user-invocable | 否 | 设为 false 禁止斜杠命令调用 |
argument-hint | 否 | 斜杠命令的参数提示 |
context | 否 | 额外上下文配置 |
agent | 否 | 指定使用哪个 Agent 执行 |
hooks | 否 | 关联的生命周期钩子 |
编写原则
1. Description 是最重要的字段
它决定了 Skill 何时被触发。写得具体、带场景、稍微"激进":
差: "Helps with documents"
好: "Use this skill whenever the user wants to create, read, edit,
or manipulate Word documents (.docx files). Triggers include:
any mention of 'Word doc', '.docx', or requests to produce
professional documents..."
2. 解释 Why,而不是堆砌 MUST
不要用大量 ALWAYS、NEVER 来强制行为。LLM 有很强的理解能力,告诉它为什么这样做比命令它必须这样做更有效:
差: "ALWAYS use this exact template. NEVER deviate."
好: "使用这个模板是因为它经过团队验证,能确保输出格式
与现有文档体系一致。偏离模板会导致自动化工具解析失败。"
3. 保持正文精简
SKILL.md 正文建议不超过 500 行。超出时,将详细内容放入 references/ 目录,并在正文中给出明确的指针:
## Cloud Deployment
详见 `references/aws.md`、`references/gcp.md`、`references/azure.md`。
根据用户选择的云平台,只加载对应的参考文件。
4. 打包可复用脚本
如果多个测试用例都独立写了类似的脚本,说明这个脚本应该成为 Skill 的一部分:
cloud-deploy/
├── SKILL.md
└── scripts/
└── deploy.sh # 被反复用到,应该打包
这样每次调用 Skill 时不需要重新发明轮子。
5. 用示例代替冗长说明
## Commit message 格式
**示例:**
输入:Added user authentication with JWT tokens
输出:feat(auth): implement JWT-based authentication
Description 优化流程
当 Skill 的触发准确率不理想时,按以下流程优化:
- 生成测试集:20 个查询,一半应触发、一半不应触发,重点放在边界情况
- 评估当前 description:每个查询跑 3 次,统计触发率
- 分析失败案例:哪些不该触发的触发了?哪些该触发的没触发?
- 重写 description:基于失败模式调整措辞
- 重复:直到测试集通过率满意
关键洞察:简单查询(如"读这个文件")几乎不会触发任何 Skill——Agent 觉得自己能搞定就不会去加载 Skill。所以测试查询应该有足够复杂度,让 Agent 感受到"我需要指导"。