<!-- title: Skill触发调优：从失效到精准激活 -->

# Claude Code Skill 触发调优：从失效到精准激活

## 概述

本教程聚焦 Claude Code Skill 开发中最容易被忽视、却直接决定一个 Skill 生死的一环——**触发准确性**。一个写好的 `SKILL.md` 如果在该出现的时候不出现、在不该出现的时候乱入，等同于不存在。本教程基于官方 `description` 字段机制、1,536 字符截断规则、渐进披露加载模型，给出一套从"0 次自动触发"到"精准按需激活"的系统化调优方法。适合已经写过至少一个 Skill、却苦于"模型总是不用它"或"模型乱用它"的开发者。

## 前置条件

- Claude Code v2.1.145 或更高（`/run`、`/verify` 等 bundled skills 依赖此版本）
- 已创建过至少一个 `SKILL.md`，熟悉 YAML frontmatter 基本结构
- 已安装 `git`，有一个可测试的真实项目仓库
- 对"上下文窗口（context window）"和 token 成本有基本概念

---

## 一、先理解：为什么 `description` 是 Skill 的唯一命脉

很多开发者把 80% 精力花在 `SKILL.md` 正文（body）上，却随手写一行 `description`。这恰恰搞反了优先级。理解下面三个机制，你就明白为什么 `description` 才是命脉。

### 机制 1：渐进披露——body 按需加载，description 常驻

Claude Code 采用**渐进披露（Progressive Disclosure）**加载策略：

```mermaid
flowchart LR
    A[会话启动] --> B[扫描所有 SKILL.md]
    B --> C[仅 description 注入 context]
    C --> D{用户/Claude 判断是否相关}
    D -->|相关| E[完整 body 加载进 context]
    D -->|不相关| F[body 永不加载 0 成本]
    E --> G[body 常驻至会话结束]
```

关键含义：在常规会话里，**所有 Skill 的 `description` 始终在 context 中**，而完整 body 只有在被触发后才加载，并且加载后常驻整场会话。这意味着：

- `description` 是模型决定"要不要加载这个 Skill"的**唯一决策依据**。body 写得再好，模型在触发阶段根本看不到。
- 如果 `description` 写错，要么永远不触发（body 白写），要么错误触发（污染整场会话的 context，因为 body 一旦加载就常驻）。

### 机制 2：1,536 字符硬截断

官方文档明确：`description` 与 `when_to_use` 拼接后的文本，在 Skill 列表中被**截断到 1,536 个字符**。超过部分模型完全看不到。这不是软建议，而是硬约束。

> ⚠️ 后果：如果你在 `description` 里把重要触发条件写在第 1,600 字符之后，对模型而言它**根本不存在**。

### 机制 3：`description` + `when_to_use` 合并参与触发

`when_to_use` 字段不是独立信号，它会被**追加到 `description` 之后**，合并后一起参与触发判断、一起计入 1,536 字符上限。如果你把触发短语堆在 `description` 里，又重复堆在 `when_to_use` 里，只是白白消耗配额，不会让触发更敏感。

理解了这三点，后面所有的调优技巧都有了理论依据。

---

## 二、三大触发故障：先学会诊断

官方文档的 Troubleshooting 章节列出了三个典型故障。这里给出每个故障的现象、根因和定位命令。

### 故障 A：Skill 不触发（not triggering）

**现象**：你问了一个明显属于该 Skill 的问题，模型却不用它，而是自己硬答或调了别的 Skill。

**根因排查清单**：

| 可能根因 | 定位方法 |
|---------|---------|
| `description` 太宽泛，被其它更具体的 Skill "抢走"了相关性 | 在 `/` 菜单看是否有同义 Skill |
| `disable-model-invocation: true` 写错了，禁止了自动触发 | 检查 frontmatter 该字段 |
| 触发关键词是英文而你用中文提问（或反之） | `description` 里补上双语触发词 |
| `description` 核心信息落在 1,536 字符之后 | 字符计数工具核对 |
| `paths` 字段限定了 glob，但当前文件不匹配 | 检查 `paths` 配置 |

### 故障 B：Skill 过度触发（triggers too often）

**现象**：每次提问都自动加载这个 Skill，即使完全无关，导致 context 被无意义占用。

**根因排查清单**：

| 可能根因 | 定位方法 |
|---------|---------|
| `description` 含"代码""文件""任务"等高频词 | 通读 description 删泛词 |
| 该 Skill 本质是"手动动作"（如部署、发消息）却没禁自动触发 | 加 `disable-model-invocation: true` |
| `description` 用了"Use when..."句式但条件太松 | 收紧为具体场景 |

### 故障 C：描述被截断（descriptions cut short）

**现象**：明明写了完整描述，模型触发判断却像是只看了前半段。

**根因**：`description + when_to_use` 超过 1,536 字符。**修复**：把最关键的"动作 + 对象 + 触发场景"压到前 200 字符，删掉所有铺垫性文字。

---

## 三、description 工程化写作法：正反例对比

下面是一组真实场景的正反例。每对都来自常见的"Skill 不被用"的坑。

### 反模式 1：功能罗列型（太宽）

```yaml
# ❌ 反例：宽到和一切相关
description: 帮助处理数据库相关的工作，包括查询、优化、迁移、备份、设计等。
```

问题：几乎所有涉及数据的工作都会"匹配"。结果是该精确触发时不触发（被淹没），不该触发时乱触发。

```yaml
# ✅ 正例：动作+对象+场景+边界
description: 重写慢 SQL 查询。当用户抱怨查询慢、要优化 EXPLAIN 结果、或给出具体慢 SQL 时使用。不用于 schema 设计或数据迁移。
```

改进点：动词精确到"重写"，触发场景具体到"抱怨慢/给 EXPLAIN/给具体 SQL"，并用"不用于..."划定边界。

### 反模式 2：标题自解释型（太窄/太抽象）

```yaml
# ❌ 反例：说了等于没说
description: API 约定。
```

```yaml
# ✅ 正例
description: 本仓库 API 端点设计规范。写新 endpoint 或评审 PR 中的路由时加载：强制 RESTful 命名、统一错误格式、必带请求校验。
```

### 反模式 3：泛功能词污染

这是过度触发的头号元凶。下面这些词几乎和所有任务相关，应避免单独作为触发主体：

`代码 / 文件 / 任务 / 帮助 / 处理 / 分析`

如果你必须用，必须**搭配一个收敛性的具体场景**：

```yaml
# ❌ 反例
description: 帮助分析和处理代码文件。

# ✅ 正例
description: 检测 Python 代码中未关闭的文件句柄和未释放的数据库连接。仅在审查 .py 文件的 PR 时使用。
```

### 推荐的 description 模板

把下面这个模板当作起步骨架，再按实际裁剪：

```yaml
description: <动词><具体对象>。<触发场景1>；<触发场景2>。不用于<反场景>。
```

实例：

```yaml
description: 生成符合公司品牌的会议纪要。当用户说"整理纪要""会议总结""转写会议"时使用。不用于代码评审或技术文档撰写。
```

记住一个检验标准：**把 description 念给一个不熟悉你项目的人听，他能准确说出"什么时候该用、什么时候不该用"，就及格了。**

---

## 四、实战案例：从 0 触发到精准激活

目标：做一个 `release-notes` Skill，从 git log 生成发布说明。我们走完整的失败→诊断→迭代过程。

### v1：第一版（触发失败）

```yaml
# ~/.claude/skills/release-notes/SKILL.md
---
description: 生成发布说明文档。
---

根据最近的提交生成发布说明。
```

**测试结果**：用户在项目里说"帮我写这次发布的说明"，模型直接自己写了，**没触发 Skill**。

**诊断**：

1. "发布说明文档"太抽象，且"文档"是泛词。
2. 没有给出触发动词（用户说的是"写发布说明"）。
3. body 太薄，即便触发也产出不稳定。

### v2：补触发词，但仍过度触发

```yaml
---
description: 生成发布说明。当用户要求写发布说明、release notes、changelog、版本说明时使用。
---
```

**测试结果**：触发了，但**过度触发**——用户说"我要发布到生产"（部署意图），它也被激活了，因为"发布"被命中。

**诊断**："发布"同时命中了 release-notes 和 deploy 两个意图，而 release-notes 的描述没把"生成文档"这个**产出物**和"部署动作"区分开。

### v3：动作+产出物+反场景收口

```yaml
---
description: 从 git log 生成 Markdown 格式的发布说明。当用户要"写发布说明""整理 changelog""生成 release notes"时使用。输出是文档，不是执行部署。不用于执行部署或打 tag。
---

## 任务

基于 git 历史，生成本次发布的 Markdown 说明：

1. 运行 `git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:"%s"` 获取自上个 tag 以来的提交
2. 按类型分组：feat（新功能）、fix（修复）、其他
3. 输出 Markdown，中文表述，每条附简短说明
4. 如果没有提交，明确告知"自上次发布无变更"

## 边界

只读 git 历史，不执行任何 git 写操作，不部署，不打 tag。
```

**测试结果**：

- "帮我写发布说明" → ✅ 触发，产出正确
- "我要发布到生产" → ✅ 不触发（deploy 的描述接管）
- "整理这次的 changelog" → ✅ 触发

### v4（可选）：用 `paths` 进一步收口

如果这个 Skill 只在该仓库用，可在项目级 Skill 加 `paths` 限定，避免在无关仓库乱触发：

```yaml
---
description: 从 git log 生成发布说明。...
paths:
  - "CHANGELOG.md"
  - "package.json"
  - "VERSION"
---
```

设置 `paths` 后，Claude 仅在处理匹配这些 glob 的文件时才会自动加载该 Skill。这是一个非常有效的"防过度触发"兜底，特别适合仓库专属 Skill。

---

## 五、高级触发控制：四种武器叠加

当 description 调优到极限仍不够时，用下面四种机制做确定性收口。

### 武器 1：`when_to_use` 承载触发短语

把"触发短语"从 `description` 挪到 `when_to_use`，让 `description` 聚焦"做什么"，`when_to_use` 聚焦"何时做"：

```yaml
---
description: 从 git log 生成 Markdown 发布说明。
when_to_use: |
  触发短语：写发布说明 / 整理 changelog / 生成 release notes / 这次发版都改了什么。
  典型请求示例："帮我把这周的提交整理成发布说明"。
---
```

注意两者合计仍在 1,536 字符内。

### 武器 2：`paths` 做 glob 限定（上文已演示）

最适合"只在特定文件类型/目录下生效"的 Skill，是防止跨仓库误触发的最强手段。

### 武器 3：`disable-model-invocation` / `user-invocable` 控制调用方

| 字段设置 | 你能 `/调用` | 模型能自动调用 | description 是否在 context |
|---------|------------|--------------|--------------------------|
| 默认 | 是 | 是 | 是 |
| `disable-model-invocation: true` | 是 | **否** | **否** |
| `user-invocable: false` | **否** | 是 | 是 |

**关键决策**：

- 部署、发消息、commit 这类**有副作用**的动作 → `disable-model-invocation: true`。你不希望模型因为"代码看起来好了"就自动部署。附带好处：description 不进 context，省 token。
- 背景知识类（如 `legacy-system-context`，解释老系统怎么工作）→ `user-invocable: false`。模型该在相关时知道，但 `/legacy-system-context` 对用户不是有意义的动作。

### 武器 4：`skillOverrides` 四态收口

当 Skill 不归你改（比如团队仓库里的、MCP 提供的），用 `settings.local.json` 的 `skillOverrides` 控制可见性。`/skills` 菜单里按空格切换状态即可写入：

```json
{
  "skillOverrides": {
    "legacy-context": "name-only",
    "deploy": "off",
    "noisy-helper": "user-invocable-only"
  }
}
```

四态含义：

| 值 | 对模型列出 | 在 `/` 菜单 |
|----|-----------|------------|
| `"on"` | 名称+描述 | 是 |
| `"name-only"` | 仅名称 | 是 |
| `"user-invocable-only"` | 隐藏 | 是 |
| `"off"` | 隐藏 | 隐藏 |

`"name-only"` 是个微妙的中间态：当某个 Skill 的 description 写得很差、容易和你的 Skill 抢触发，但你又不能改它时，把它降到 `name-only`，削弱它在触发竞争中的权重。注意：plugin skills 不受 `skillOverrides` 影响，需走 `/plugin`。

---

## 六、调优验证流程：量化而非凭感觉

description 改完后，必须用**固定的测试集**验证触发行为，而不是改一次问一次凭感觉。建议的最小验证流程：

```mermaid
flowchart TD
    A[准备 5-8 条测试提问] --> B[一半正例 一半反例]
    B --> C[每条单独新开会话提问]
    C --> D[记录: 是否触发目标 Skill]
    D --> E{正例触发率 + 反例未触发率}
    E -->|均达标| F[调优完成]
    E -->|未达标| G[分析失败样本]
    G --> H[改 description/when_to_use/paths]
    H --> C
```

**测试集设计原则**：

- 正例（应该触发）：用真实用户会说的话，覆盖中文/英文、正式/口语。
- 反例（不该触发）：刻意构造"边界陷阱"，比如 release-notes 案例里的"发布到生产"。
- 每条在**全新会话**中测试，避免上一轮 Skill 加载污染判断。

**通过线建议**：正例触发率 ≥ 80%，反例误触发率 ≤ 20%，可视为调优达标。如需更严格的量化，可用 bundled 的 `/skill` 相关评测能力或第三方 eval 框架跑批量。

**额外两个必检项**：

1. 用字符计数工具核对 `description + when_to_use` ≤ 1,500 字符（留余量，别贴着 1,536）。
2. 触发后检查 body 是否在后续轮次仍生效。官方提示：若 Skill 在首轮后"失效"，通常是 body 已被 compact 摘要截断——auto-compaction 会为每个被触发的 Skill 保留前 5,000 token，所有 Skill 共享 25,000 token 预算，从最近触发的开始填。**应对**：强化 description 让模型持续偏好它，或用 hooks 确定性强制行为，或在 compact 后重新 `/调用` 一次。

---

## 七、完整工作流程

把全文方法串成一条可复用的工作流：

```mermaid
flowchart LR
    A[写初版 SKILL.md] --> B[固定测试集验证]
    B --> C{触发是否符合预期}
    C -->|不触发| D[诊断: 宽泛/缺触发词/超截断/paths]
    C -->|过度触发| E[诊断: 泛词/缺反场景/缺disable]
    C -->|被截断| F[压缩到1500字符内]
    D --> G[改 description]
    E --> G
    F --> G
    G --> B
    C -->|达标| H[叠加高级控制]
    H --> I{有无副作用/边界需求}
    I -->|是| J[disable-model-invocation/paths/skillOverrides]
    I -->|否| K[提交版本控制]
    J --> K
```

---

## 训练营适用性评估

| 维度 | 评估 |
|------|------|
| 适合的训练营类型 | Claude Code 进阶开发营、AI 工程实战营、企业 Prompt/Skill 工程化营 |
| 不适合 | 零基础入门营（需先掌握 Skill 创建基础） |
| 前置课程 | Round 1 入门 + 至少一个自建 Skill 经验 |
| 建议教学时长 | 3 小时（1 小时机制讲解 + 1.5 小时案例实操 + 0.5 小时学员自带 Skill 调优） |
| 学员产出 | 每人带 1 个真实 Skill 完成触发调优，附测试集与达标报告 |
| 难点提示 | 最难的不是写 description，而是构造**高质量反例测试集**——这是区分"凭感觉用 AI"和"工程化用 AI"的分水岭 |

---

## 延伸阅读

- **官方 Skills 文档**（Frontmatter Reference、Troubleshooting 三节必读）：覆盖本文所有字段的权威定义
- **`/run` `/verify` bundled skills**：理解官方 Skill 是怎么写 description 的，是最好的模仿对象
- **Hooks in skills**：当 description 调优到极限仍需确定性强制行为时，下一步就学 hooks
- **Agent Skills 开放标准**：Skill 的跨平台可移植性基础，理解为什么 description 是跨工具通用契约

---

## 参考来源

1. [Extend Claude with skills — Claude Code Docs](https://code.claude.com/docs/en/skills) — 官方权威文档，本文 frontmatter 字段、1,536 字符截断、Troubleshooting 三节、skillOverrides 四态、auto-compaction token 预算均出自此处
2. [Equipping agents for the real world with Agent Skills — Anthropic Engineering](https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills) — Agent Skills 开放标准与渐进披露设计哲学的官方工程解读
3. [Progressive Disclosure: How Claude Loads Skills — Introduction to Agent Skills](https://www.anthropiccertifications.com/courses/introduction-to-agent-skills/progressive-disclosure) — 渐进披露机制的系统讲解，解释 description 常驻、body 按需加载
4. [Claude Agent Skills Framework Guide — Digital Applied](https://www.digitalapplied.com/blog/claude-agent-skills-framework-guide) — 跨 Claude.ai / Claude Code / API 三端的 Skills 落地指南，含 SKILL.md 结构与 description 实践（2026-04 更新）
5. [Agent Skills — wshobson/agents](https://github.com/wshobson/agents/blob/main/docs/agent-skills.md) — 社区维护的模块化 Skill 集合与文档，可作为 description 写法的真实语料库

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
