本教程聚焦 Claude Code Skills 最容易被忽视却最致命的问题——触发不准:该响应的 Skill 不响应,不该响应的 Skill 抢响应。我们将从零创建一个真实 Skill,故意写出模糊的 description,再用官方 skill-creator 的 eval 基准、benchmark 与 description 改进器,把它一步步收敛到稳定命中。适合已写过一两个 Skill、想从"靠感觉"升级到"靠数据"的 Claude Code 中级使用者。
/skills 或交互式调用name + description + 正文)很多人写 Skill 的失败不在正文,而在 frontmatter 的 description。要理解为什么,先看 Skill 的三层加载机制(渐进式披露,Progressive Disclosure):
flowchart TD
A["会话启动"] --> B["第一层:Discovery<br/>只读每个Skill的<br/>name+description≈100 tokens/个"]
B --> C{"用户输入<br/>是否匹配<br/>某个description?"}
C -->|匹配| D["第二层:Activation<br/>加载完整SKILL.md正文<br/><500行, 约1K-5K tokens"]
C -->|不匹配| E["Skill保持休眠<br/>几乎零开销"]
D --> F["第三层:Execution<br/>按需读取scripts/<br/>references/ 等捆绑资源"]
F --> G["返回结果<br/>仅保留必要上下文"]
关键洞察:Claude 在每一轮对话中,只看到 description,看不到正文。 description 不只是文档说明,它是唯一的触发信号。官方 skill-creator 的 SKILL.md 原文明确写道:
description是主要的触发机制(primary triggering mechanism)——必须同时包含"这个 Skill 做什么"和"什么场景下使用"。所有"何时使用"的信息都放在这里,而不是正文里。
而且官方指出一个反直觉的现状:Claude 当前倾向于"少触发"(undertrigger)——能用的时候不用。所以官方建议把 description 写得稍微"强势"(pushy)一点,主动列举触发关键词和场景。
这就引出本教程的核心矛盾:description 太宽泛 → 假阳性(false positive,误触发);太狭窄 → 假阴性(false negative,该触发不触发)。靠人工猜测无法平衡,必须用 eval 量化。
为了让后续优化有戏可唱,我们先造一个起点描述模糊的 Skill。案例主题:Markdown 文档结构化检查——检测标题层级断裂(h1 直接跳 h3)、代码块未闭合、内部锚点链接失效,并给出可执行的修复建议。
创建目录与文件(命令保持原文):
mkdir -p ~/.claude/skills/md-lint
写入第一个故意写差的 ~/.claude/skills/md-lint/SKILL.md:
---
name: md-lint
description: A helper for checking documents.
---
# MD Lint
Check the markdown files in the project and report problems.
## Instructions
1. Read the file the user mentions.
2. Find issues.
3. Tell the user what to fix.
预期结果:用 claude 启动会话,输入"帮我看看 README 里的文档问题"——大概率不会触发 md-lint。因为 A helper for checking documents 既没说检查什么类型的问题,也没说处理什么文件格式。Claude 更可能直接调用通用编辑工具,或被相邻的 review 类 Skill 抢走触发。
常见问题:新手以为 description 写得越通用越好,能"覆盖更多场景"。恰恰相反——通用等于没有触发信号。在装了 5~10 个 Skill 的真实环境里,通用 description 会被淹没。
这是把"靠感觉"变成"靠数据"的关键一步。官方 skill-creator 的 eval 思路:定义一批已知正确答案的测试 prompt,描述"好的结果长什么样",然后让 Claude 在有 Skill 的情况下跑这些 prompt,统计命中率。
对"触发准确性"这一目标,我们专门设计触发测试集,分两类:
flowchart LR
subgraph T["触发测试集"]
P["正例 positives<br/>这些prompt<br/>应当触发md-lint"]
N["反例 negatives<br/>这些prompt<br/>绝不应当触发md-lint"]
end
T --> R["逐条让Claude判断<br/>是否加载该Skill"]
R --> M["统计:<br/>命中率与误报率"]
把测试集存成文件,例如 ~/.claude/skills/md-lint/eval/trigger_cases.md:
# md-lint 触发测试集
## 正例(期望: 触发 md-lint)
1. "README.md 里有个代码块好像没闭合,帮我查一下"
2. "这个文档的标题层级是不是跳了,h1 下面直接是 h3"
3. "把我仓库里所有 .md 文档的结构问题扫一遍,列出每条的修复建议"
4. "安装指南里 [配置](#config) 这个链接点不动了,帮我定位"
5. "docs/ 下面有几篇 markdown 排版乱了,做一次结构检查"
## 反例(期望: 不触发 md-lint,应交给别的 Skill 或直接处理)
1. "帮我把刚才的改动写成一个规范的 conventional commit" # → commit Skill
2. "给 utils.js 里的函数补单元测试" # → test Skill
3. "这段 Python 代码有安全风险吗,review 一下" # → security-review Skill
4. "把 data.csv 里的金额列按月汇总成表格" # → 通用数据处理
5. "翻译 README 的英文段落成中文" # → 通用翻译
设计要点:
常见问题:反例写得太"明显"(如"写一首诗"),测不出真实冲突。一定要用和目标 Skill 语义相邻的 prompt 当反例。
确保已安装官方 skill-creator 插件(命令保持原文):
claude plugins install skill-creator
或在交互式会话中让 Claude 直接调用 skill-creator。触发它只需一句话:
请用 skill-creator 对我的 md-lint Skill 做一次触发评估,
测试集在 ~/.claude/skills/md-lint/eval/trigger_cases.md,
跑 benchmark 模式,统计 pass rate、耗时和 token 使用量。
skill-creator 会按官方 SKILL.md 描述的标准流程执行:
第一次跑,模糊的 A helper for checking documents 结果可能形如:
正例命中率: 1/5 (20%)
反例误报率: 2/5 (40%)
平均耗时: 8.2s/条
只有 1 条正例触发,说明严重 undertrigger;同时有 2 条反例误触发,说明描述里的 "documents"/"problems" 又过于宽泛。这就是"靠数据"的价值——你第一次清楚地看到问题在哪。
benchmark 的额外能力(官方 2026-03-03 博客公布):
这是触发优化的主菜。官方 skill-creator 内置一个专门的 description 改进器:它会拿你当前的 description,对照测试集中的正反例,给出能同时降低 false positive 和 false negative 的改写建议。 官方在自家 6 个公开文档创建 Skill 上试过,5 个的触发都变好了。
调用方式(交互式):
继续用 skill-creator,针对刚才的触发结果,
跑 description 改进器,给出优化后的 description 草稿,
并说明它如何分别降低假阳性和假阴性。
改进器可能建议把 description 改写成:
description: >
Use when the user wants to inspect, lint, or audit the STRUCTURE of
Markdown (.md) documents — detecting heading-level jumps (e.g. h1
straight to h3), unclosed fenced code blocks, and broken internal
anchor links like [x](#section). Produces a per-issue report with
file, line, and a concrete fix suggestion. Trigger whenever the user
mentions markdown formatting problems, broken doc anchors, code fence
issues, or asks to "check the structure/docs/README" — even if they
don't say "lint". Do NOT use for translating prose, summarizing
content, or reviewing source code quality (those belong to other skills).
逐项拆解这条 description 为何有效:
| 改写手法 | 对应作用 | 解决的问题 |
|---|---|---|
Markdown (.md) documents + STRUCTURE |
限定文件类型与意图维度 | 降低假阳性:不再误抓 .py / .csv 任务 |
| 明确列举三类问题(heading jump / unclosed fence / broken anchor) | 给出精确语义锚点 | 降低假阴性:正例里"标题跳级""链接点不动"能命中 |
even if they don't say "lint" |
主动覆盖同义表达 | 对抗官方指出的 undertrigger 倾向 |
Do NOT use for translating... reviewing source code |
显式排除兄弟 Skill 领域 | 降低假阳性:与 commit / test / security-review Skill 划清边界 |
把新 description 写回 SKILL.md,重跑第四步的 benchmark。你会看到正例命中率上升、反例误报率下降。
官方反复强调的写作要点(来自官方 SKILL.md 与社区权威指南):
一次改写很少一步到位。官方 skill-creator 的标准流程是一个迭代闭环:
flowchart TD
S["草拟SKILL.md<br/>(name+description+正文)"] --> E["运行eval/benchmark<br/>多agent并行,干净上下文"]
E --> A["A/B双盲对比<br/>判断改动是否真有效"]
A --> Q{"指标满意?<br/>正例命中率↑<br/>反例误报率↓"}
Q -->|否| D["改写description/正文<br/>description改进器给建议"]
D --> E
Q -->|是| X["扩充测试集<br/>大规模回归"]
X --> Y["固化eval入CI<br/>模型升级后自动跑"]
Y --> Z["Skill稳定上线"]
迭代纪律:
两种 Skill 类型的不同测试重点(官方分类):
下面给出完整可运行的最终 ~/.claude/skills/md-lint/SKILL.md,并演示它如何在一个装了 commit、test-gen、security-review 三个兄弟 Skill 的真实环境里稳定触发、不抢触发:
---
name: md-lint
description: >
Use when the user wants to inspect, lint, or audit the STRUCTURE of
Markdown (.md) documents — detecting heading-level jumps (e.g. h1 to h3),
unclosed fenced code blocks, and broken internal anchor links like
[x](#section). Produces a per-issue report with file, line, and a
concrete fix suggestion. Trigger whenever the user mentions markdown
formatting problems, broken doc anchors, code-fence issues, or asks to
"check the structure/docs/README" — even if they don't say "lint".
Do NOT use for translating prose, summarizing content, or reviewing
source-code quality (those belong to other skills).
disable-model-invocation: false
allowed-tools: Read Grep Glob
---
# MD Lint — Markdown 结构化检查
## When to use this skill
- 用户提到 .md 文档的排版、结构、格式问题时
- 用户报告 README/文档里的锚点链接点不动、代码块没闭合、标题层级跳跃
## When NOT to use this skill
- 翻译、摘要、改写正文内容(交给通用能力)
- 审查 .py/.js 等源代码质量(交给 security-review / code-review)
- 生成提交信息、补单元测试(交给 commit / test-gen)
## Instructions
1. 用 Glob 定位用户指明的 .md 文件(默认 README.md 与 docs/ 下的 .md)
2. 用 Read 读取内容,用 Grep 精确定位行号
3. 按以下三类规则扫描:
- **标题层级**:相邻标题层级差 ≤1(h1→h2 允许,h1→h3 报错)
- **代码围栏**:统计 ``` 的数量,奇数即为未闭合
- **锚点链接**:提取所有 [text](#id),检查文档内是否存在 <h* id="id"> 或对应 slug
4. 输出表格:| 文件 | 行号 | 问题类型 | 详情 | 建议修复 |
## Examples
输入:「README 里 [配置](#config) 链接失效了」
输出:
| 文件 | 行号 | 问题类型 | 详情 | 建议修复 |
|---|---|---|---|---|
| README.md | 42 | broken-anchor | #config 无对应标题 | 将该节标题改为 `## 配置` 或把链接改为 #配置 |
验证命令(命令保持原文):
# 在装了多个 Skill 的环境里,逐条跑测试集,确认触发结果
echo '帮我查 README.md 里有没有结构问题,标题是不是跳级了' | claude -p
# 期望: 自动加载 md-lint,输出结构问题表
echo '给 src/auth.ts 补单元测试' | claude -p
# 期望: 加载 test-gen,而非 md-lint
再用 skill-creator 跑一次 benchmark,理想结果是正例命中率 ≥ 4/5、反例误报率 0/5。至此,这个 Skill 从"靠感觉写、不知道灵不灵"变成"有量化基线、可在模型升级时回归"。
github.com/anthropics/claude-plugins-official 下 plugins/skill-creator/skills/skill-creator/SKILL.md,是理解 eval/benchmark/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 等场景全覆盖。
