本教程聚焦 Claude Code Skill 开发中最容易被忽视、却直接决定一个 Skill 生死的一环——触发准确性。一个写好的 SKILL.md 如果在该出现的时候不出现、在不该出现的时候乱入,等同于不存在。本教程基于官方 description 字段机制、1,536 字符截断规则、渐进披露加载模型,给出一套从"0 次自动触发"到"精准按需激活"的系统化调优方法。适合已经写过至少一个 Skill、却苦于"模型总是不用它"或"模型乱用它"的开发者。
/run、/verify 等 bundled skills 依赖此版本)SKILL.md,熟悉 YAML frontmatter 基本结构git,有一个可测试的真实项目仓库description 是 Skill 的唯一命脉很多开发者把 80% 精力花在 SKILL.md 正文(body)上,却随手写一行 description。这恰恰搞反了优先级。理解下面三个机制,你就明白为什么 description 才是命脉。
Claude Code 采用渐进披露(Progressive Disclosure)加载策略:
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 一旦加载就常驻)。官方文档明确:description 与 when_to_use 拼接后的文本,在 Skill 列表中被截断到 1,536 个字符。超过部分模型完全看不到。这不是软建议,而是硬约束。
⚠️ 后果:如果你在
description里把重要触发条件写在第 1,600 字符之后,对模型而言它根本不存在。
description + when_to_use 合并参与触发when_to_use 字段不是独立信号,它会被追加到 description 之后,合并后一起参与触发判断、一起计入 1,536 字符上限。如果你把触发短语堆在 description 里,又重复堆在 when_to_use 里,只是白白消耗配额,不会让触发更敏感。
理解了这三点,后面所有的调优技巧都有了理论依据。
官方文档的 Troubleshooting 章节列出了三个典型故障。这里给出每个故障的现象、根因和定位命令。
现象:你问了一个明显属于该 Skill 的问题,模型却不用它,而是自己硬答或调了别的 Skill。
根因排查清单:
| 可能根因 | 定位方法 |
|---|---|
description 太宽泛,被其它更具体的 Skill "抢走"了相关性 |
在 / 菜单看是否有同义 Skill |
disable-model-invocation: true 写错了,禁止了自动触发 |
检查 frontmatter 该字段 |
| 触发关键词是英文而你用中文提问(或反之) | description 里补上双语触发词 |
description 核心信息落在 1,536 字符之后 |
字符计数工具核对 |
paths 字段限定了 glob,但当前文件不匹配 |
检查 paths 配置 |
现象:每次提问都自动加载这个 Skill,即使完全无关,导致 context 被无意义占用。
根因排查清单:
| 可能根因 | 定位方法 |
|---|---|
description 含"代码""文件""任务"等高频词 |
通读 description 删泛词 |
| 该 Skill 本质是"手动动作"(如部署、发消息)却没禁自动触发 | 加 disable-model-invocation: true |
description 用了"Use when..."句式但条件太松 |
收紧为具体场景 |
现象:明明写了完整描述,模型触发判断却像是只看了前半段。
根因:description + when_to_use 超过 1,536 字符。修复:把最关键的"动作 + 对象 + 触发场景"压到前 200 字符,删掉所有铺垫性文字。
下面是一组真实场景的正反例。每对都来自常见的"Skill 不被用"的坑。
# ❌ 反例:宽到和一切相关
description: 帮助处理数据库相关的工作,包括查询、优化、迁移、备份、设计等。
问题:几乎所有涉及数据的工作都会"匹配"。结果是该精确触发时不触发(被淹没),不该触发时乱触发。
# ✅ 正例:动作+对象+场景+边界
description: 重写慢 SQL 查询。当用户抱怨查询慢、要优化 EXPLAIN 结果、或给出具体慢 SQL 时使用。不用于 schema 设计或数据迁移。
改进点:动词精确到"重写",触发场景具体到"抱怨慢/给 EXPLAIN/给具体 SQL",并用"不用于..."划定边界。
# ❌ 反例:说了等于没说
description: API 约定。
# ✅ 正例
description: 本仓库 API 端点设计规范。写新 endpoint 或评审 PR 中的路由时加载:强制 RESTful 命名、统一错误格式、必带请求校验。
这是过度触发的头号元凶。下面这些词几乎和所有任务相关,应避免单独作为触发主体:
代码 / 文件 / 任务 / 帮助 / 处理 / 分析
如果你必须用,必须搭配一个收敛性的具体场景:
# ❌ 反例
description: 帮助分析和处理代码文件。
# ✅ 正例
description: 检测 Python 代码中未关闭的文件句柄和未释放的数据库连接。仅在审查 .py 文件的 PR 时使用。
把下面这个模板当作起步骨架,再按实际裁剪:
description: <动词><具体对象>。<触发场景1>;<触发场景2>。不用于<反场景>。
实例:
description: 生成符合公司品牌的会议纪要。当用户说"整理纪要""会议总结""转写会议"时使用。不用于代码评审或技术文档撰写。
记住一个检验标准:把 description 念给一个不熟悉你项目的人听,他能准确说出"什么时候该用、什么时候不该用",就及格了。
目标:做一个 release-notes Skill,从 git log 生成发布说明。我们走完整的失败→诊断→迭代过程。
# ~/.claude/skills/release-notes/SKILL.md
---
description: 生成发布说明文档。
---
根据最近的提交生成发布说明。
测试结果:用户在项目里说"帮我写这次发布的说明",模型直接自己写了,没触发 Skill。
诊断:
---
description: 生成发布说明。当用户要求写发布说明、release notes、changelog、版本说明时使用。
---
测试结果:触发了,但过度触发——用户说"我要发布到生产"(部署意图),它也被激活了,因为"发布"被命中。
诊断:"发布"同时命中了 release-notes 和 deploy 两个意图,而 release-notes 的描述没把"生成文档"这个产出物和"部署动作"区分开。
---
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。
测试结果:
paths 进一步收口如果这个 Skill 只在该仓库用,可在项目级 Skill 加 paths 限定,避免在无关仓库乱触发:
---
description: 从 git log 生成发布说明。...
paths:
- "CHANGELOG.md"
- "package.json"
- "VERSION"
---
设置 paths 后,Claude 仅在处理匹配这些 glob 的文件时才会自动加载该 Skill。这是一个非常有效的"防过度触发"兜底,特别适合仓库专属 Skill。
当 description 调优到极限仍不够时,用下面四种机制做确定性收口。
when_to_use 承载触发短语把"触发短语"从 description 挪到 when_to_use,让 description 聚焦"做什么",when_to_use 聚焦"何时做":
---
description: 从 git log 生成 Markdown 发布说明。
when_to_use: |
触发短语:写发布说明 / 整理 changelog / 生成 release notes / 这次发版都改了什么。
典型请求示例:"帮我把这周的提交整理成发布说明"。
---
注意两者合计仍在 1,536 字符内。
paths 做 glob 限定(上文已演示)最适合"只在特定文件类型/目录下生效"的 Skill,是防止跨仓库误触发的最强手段。
disable-model-invocation / user-invocable 控制调用方| 字段设置 | 你能 /调用 |
模型能自动调用 | description 是否在 context |
|---|---|---|---|
| 默认 | 是 | 是 | 是 |
disable-model-invocation: true |
是 | 否 | 否 |
user-invocable: false |
否 | 是 | 是 |
关键决策:
disable-model-invocation: true。你不希望模型因为"代码看起来好了"就自动部署。附带好处:description 不进 context,省 token。legacy-system-context,解释老系统怎么工作)→ user-invocable: false。模型该在相关时知道,但 /legacy-system-context 对用户不是有意义的动作。skillOverrides 四态收口当 Skill 不归你改(比如团队仓库里的、MCP 提供的),用 settings.local.json 的 skillOverrides 控制可见性。/skills 菜单里按空格切换状态即可写入:
{
"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 改完后,必须用固定的测试集验证触发行为,而不是改一次问一次凭感觉。建议的最小验证流程:
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
测试集设计原则:
通过线建议:正例触发率 ≥ 80%,反例误触发率 ≤ 20%,可视为调优达标。如需更严格的量化,可用 bundled 的 /skill 相关评测能力或第三方 eval 框架跑批量。
额外两个必检项:
description + when_to_use ≤ 1,500 字符(留余量,别贴着 1,536)。/调用 一次。把全文方法串成一条可复用的工作流:
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"的分水岭 |
/run /verify bundled skills:理解官方 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 等场景全覆盖。
