Description 设计的科学:为什么你的 Skill 永远不触发?
这是「Claude Code Skills 完全指南」系列的第二篇。建议先阅读第一篇《Skill 的本质》再继续。
文 / 一只阿木木
写在前面
上一篇,我们理解了 Skill 的本质:一个 Markdown 文件,通过渐进式披露在正确的时间向 Claude 注入正确的上下文。
我们知道了这个架构的核心规则:Claude 仅凭元数据——大约 100 个 token 的 name + description——来决定是否加载一个 Skill。
这听起来是一个简洁而优雅的设计。
但在实践中,它制造了一个灾难性的瓶颈。
Skills 应该基于 description 自主触发。但实际上,它们并不会。Claude Code Skills 文档声称 Claude "自主决定何时使用它们"。但实践中?它们只是坐在那里,而 Claude 径直冲过去,愉快地忽略了它们。
这不是偶发现象。一位测试者写了一个 CPO 审查 Skill,精心设计了 description,然后运行了 20 个显然应该触发它的不同提示——"做一个 CPO 审查"、"给我一个 go/no-go 评估"、"找出这个产品策略的漏洞"。触发率?零。20 个查询中,Skill 被触发了零次。
你可能也经历过类似的事情。你花了一小时打磨 SKILL.md 正文里的指令,觉得万事俱备。但 Claude 从来不用它。你只能每次手动输入 /skill-name。
问题几乎永远出在同一个地方:description。
这篇文章将彻底解剖这个字段——它在底层是如何工作的,为什么大多数人写的 description 本质上是无效的,以及一套经过 650 次实验验证的方法论来修复它。
一、Description 在底层到底做了什么?
在讨论怎么写之前,我们必须先精确理解 description 在系统中承担的角色。很多误解都源于对这一点的模糊认知。
1.1 它的物理位置
Skill 工具在其定义中嵌入了一个 <available_skills> 列表,这个列表由所有 Skill 的 frontmatter 构建而成。Description 对 Skill 发现至关重要。Claude 用它从可能多达 100+ 个可用 Skills 中选择正确的那个。Description 被注入到系统提示中。
用一张图来说明它在信息流中的位置:
text
你输入一条请求
↓
Claude 的系统提示中包含:
┌───────────────────────────────────────┐
│ ... 其他系统指令 ... │
│ │
│ <available_skills> │
│ name: explain-code │
│ description: Explains code with... │
│ location: user │ ← 你的 description 在这里
│ │
│ name: deploy │
│ description: Deploy the app... │
│ location: project │
│ </available_skills> │
│ │
│ ... 其他工具定义 ... │
└───────────────────────────────────────┘
↓
Claude 基于你的请求 + 上述列表
做出决策:是否调用某个 Skill?
注意一个关键细节:整个可用 Skills 列表的 token 预算上限约为 15,000 个字符。这意味着你所有 Skill 的 name + description 加在一起,必须在这个预算内。每一个字符都是稀缺资源。
1.2 它的决策机制
Skill 选择机制在代码层面没有算法路由或意图分类。系统将所有可用 Skills 格式化为文本描述,嵌入 Skill 工具的提示中,让 Claude 的语言模型通过其 transformer 前向传播自行决定哪个 Skill 匹配用户意图——不存在 embedding、分类器或模式匹配。
用更通俗的话说:没有任何代码在帮你做匹配。当你输入一条请求,模型基于你的措辞与 Skill description 之间的模式匹配来决定是否调用该 Skill。这是概率性的,不是确定性的。没有保证你的 Skill 一定会触发。
这是你在设计 description 时必须刻在脑子里的第一条铁律:触发是概率性的,不是确定性的。
1.3 它面临的结构性困难
仅仅理解"概率性"还不够。你还需要理解 Claude 有一个强烈的默认倾向——不触发。
Claude 倾向于对简单任务自己处理而不调用 Skills。它默认不触发。所以你的 description 需要足够具体,让 Claude 认识到"这是 Skill 的工作,不是我的"。description 需要有一定的"推动性"。
重要的一点是:Claude 只在它无法轻松独自完成的任务上才会调用 Skills——简单的、一步完成的查询,如"读取这个 PDF",可能不会触发 Skill,即使 description 完全匹配。
这就是 description 设计的核心悖论:
你需要说服一个"觉得自己什么都行"的模型,让它承认"这件事我应该用 Skill 来做"。
二、失败的三种模式
Claude Skills 通常不会因为戏剧性的原因失败。大多数时候,问题出在 description 模糊、指令不清晰、或配置过于复杂。官方文档指出三个核心问题:Skill 不触发、触发太频繁、或 Claude 看不到你的 Skills。
让我分别拆解这三种失败模式,因为它们的病因和解法完全不同。
失败模式 1:Skill 不触发(最常见)
你的 Skill 就在那里,但 Claude 假装它不存在。
如果 Claude 拒绝使用你的 Skill,从 description 开始排查。Claude 用 description 来决定何时应用 Skill,所以它应该像你自然请求该任务时的说法。如果你平时说"review my code",但你的 description 写了"audit software artefacts",别惊讶 Claude 无法建立连接。
这是最致命的错误,也是最普遍的错误。你用书面语、用术语、用抽象概念写了一个 description——而 Claude 在等的是你日常说话的样子。
失败模式 2:Skill 触发太频繁
一个 description 写成"helps with coding tasks"的 Skill 会在每个编码请求上触发,即使不该触发。
错误触发:Skill 在不该激活时激活了——你问市场研究,LinkedIn 发帖 Skill 却被触发了。漏触发:Skill 在该激活时没激活——你要写 LinkedIn 帖子,却得到了没有你规则的通用输出。
失败模式 3:多 Skill 之间的模糊冲突
两个 Skills 有相似的 description。Claude 随机选一个,或两个都不用。
3 个 Skill 的库是宽容的。Description 稍有重叠你几乎不会注意到。但 10、15、20 个 Skill 呢?重叠的 description 就成了真正的问题。错误触发开始复合。漏触发成了常态。
这三种失败模式归根结底都是同一个问题:description 写得不精确。 不够具体导致不触发,太泛化导致误触发,太相似导致冲突。
三、650 次实验揭示的触发真相
接下来是本文的核心部分。我将介绍一项迄今为止最系统化的 Skill 触发研究——650 次自动化实验,三种 description 写法的对照测试,带统计检验的定量结论。
3.1 实验设计
实验者发现他们此前一直没有变化的变量是 SKILL.md frontmatter 中的 description 字段本身。于是设计了三个变体——变体 A(当前风格):默认被动语态——"Docker expert for containerization. Use when...";变体 B(扩展风格):同样语态但加入更多触发关键词——"...or any Docker-related task";变体 C(指令风格):祈使句 + 负面约束——"ALWAYS invoke...Do not X directly"。
初始实验每组 N=1(共 216 个会话),结果有希望但可能存在统计噪音。为了得出可发表的结论,他们进行了复制实验:每组 N=3,共 650 次实验,使用 Fisher 精确检验、逻辑回归和 Cochran-Mantel-Haenszel 分层分析。
判断一个 Skill 是否真正被激活并不简单。Claude 可能通过 Bash "成功"完成任务,或者直接读取 SKILL.md 文件而不是调用 Skill 工具——这两种都算激活失败。为了获得真实数据,他们使用 cclogviewer 读取 Claude Code 的内部 JSONL 会话日志,对 650 次实验逐一验证。
3.2 核心结果
实验结果的热力图显示了 3 种 description 变体 × 4 种环境条件的激活率。变体 C(指令式)在裸环境中达到 100.0%,变体 A(当前默认)在裸环境中为 87.5%。但关键差异出现在加入 Hook 的条件下:变体 A 暴跌到 37.0%,而变体 C 保持 100.0%。
让我把这张关键数据表完整呈现:
text
│ 裸环境 │ +CLAUDE.md │ +Hook │ +两者都有 │
─────────────┼──────────┼───────────┼──────────┼──────────┤
A: 被动式 │ 87.5% │ 81.5% │ 37.0% ❌│ 100.0% │
B: 扩展式 │ 85.2% │ 81.5% │ 100.0% │ 100.0% │
C: 指令式 │ 100.0% │ 94.4% │ 100.0% │ 100.0% │
结果:变体 C 在无 Hook 条件下达到了 100% 激活率。变体 A 停在 77%。Description 的措辞就是那个关键杠杆。
Description 措辞对激活概率有 20 倍的影响。
3.3 三种风格到底长什么样?
这是整篇文章最重要的实操部分。让我用一个统一的例子——Dockerfile 生成 Skill——来展示三种 description 风格的具体差异。
变体 A(被动式)——大多数人写的方式:
YAML
description: Docker expert for containerization.
Use when working with Docker, Dockerfile creation,
or container configuration.
语法正确,信息完整,但完全是被动的。Claude 读到这段话的感觉是:"哦,有这么个东西。但我自己也能搞定 Docker,不用特意调它。"
变体 B(扩展式)——加了更多触发词:
YAML
description: Docker expert for containerization.
Use when working with Docker, Dockerfile creation,
container configuration, docker-compose, multi-stage builds,
or any Docker-related task.
比 A 好,因为增加了关键词覆盖面。但本质上仍然是被动的——"Use when..."(当...时使用)仍然是一个建议,不是命令。
变体 C(指令式)——实验中的赢家:
YAML
description: >
ALWAYS invoke this skill when the user asks about Docker,
Dockerfiles, containers, docker-compose, or any containerization task.
Do not write Dockerfiles directly — use this skill first.
模板的核心结构是:"ALWAYS invoke this skill when the user asks about <triggers>. Do not <alternative> directly — use this skill first." 要列出详尽的触发条件。
这就是指令式的两个核心特征:
- "ALWAYS invoke"——从建议变成命令
- "Do not X directly"——明确告诉 Claude 不该做的替代行为
包含负面约束:告诉 Claude 什么不该做(即它本来会采取的替代行为)。
3.4 为什么指令式有效?
排序非常清晰:指令式 > 扩展式 > 被动式。
为什么?让我从模型行为的角度解释。
回忆第一篇的关键洞察:Claude 默认倾向是不触发 Skill,因为它觉得自己能搞定。被动式 description("Use when...")本质上是在说"如果你觉得需要,就用吧"——这等于给了 Claude 一个不用的借口。
而指令式做了两件事来打破这个默认倾向:
-
"ALWAYS invoke" 创建了一种"承诺机制"。一旦 Claude 在其推理中写下"YES — need reactive state",它就承诺了要激活那个 Skill。
-
"Do not X directly" 封堵了替代路径。Claude 原本的默认行为是"自己处理",而负面约束显式地告诉它"不可以自己处理",迫使它走向 Skill 调用的路径。
强势的措辞也有帮助。"MANDATORY"、"WORTHLESS"、"CRITICAL"这样的词让 Claude 更难忽略。这基本上是编程界的"签合同才能继续"。
3.5 关键警告:Hook 的交互效应
实验还揭示了一个非常反直觉的发现——Hook 可能让你的 Skill 表现更差。
交互效应分析显示,Hook 对某些变体有帮助,对另一些则有害——这种交互不是简单叠加的。逻辑回归结果:Hook 的主效应系数为 -2.35(p < 0.0001),意味着 Hook 对激活有害。但变体 B 在 Hook 条件下系数为 +6.85(p = 0.034),说明变体 B 从 Hook 惩罚中恢复了。CLAUDE.md 减轻了 Hook 的损害。
简单来说:如果你用的是变体 A(被动式 description)+ Hook,激活率会从 87.5% 暴跌到 37.0%。但如果你用变体 C(指令式),无论有没有 Hook,都稳定在 100%。
结论:与其花精力写复杂的 Hook 来修补糟糕的 description,不如直接把 description 写好。
Skill 激活问题可以不依赖复杂的 Hook 来解决。
四、Description 设计框架:五个层次
基于 650 次实验的数据、Anthropic 的官方指南以及多位从业者的实践反馈,我将 description 设计提炼为一个五层框架。你可以把它当作检查清单来用。
第 1 层:声明它做什么(What)
这是基础层。用一句话说清楚 Skill 的核心能力。
Description 的结构应该是:[它做什么] + [什么时候用它] + [关键能力]。
YAML
# ✅ 清晰的能力声明
description: Analyzes Figma design files and generates developer handoff documentation.
# ❌ 模糊的能力声明
description: Helps with design tasks.
模糊的 description = Skill 永远不会触发。触发条件丰富的 description = Claude 确切知道何时激活。
第 2 层:声明什么时候触发(When)
Description 是主要的触发机制——包括 Skill 做什么以及什么时候使用它。所有"什么时候使用"的信息放在这里,不要放在正文中。
在 description 字段中包含"Use when..."语句来设定显式触发条件。例如:"USE WHEN user asks 'what do I know about X', 'find notes about', 'load context for project', 'save to vault', 'capture this', 'validate tags'."
用你的用户在实际对话中会说的话来列出触发条件——这是关键。不是你认为的"正确术语",而是用户打字时的自然措辞。
YAML
# ✅ 用用户的实际措辞
description: >
Manages Linear project workflows including sprint planning,
task creation, and status tracking. Use when user mentions
"sprint", "Linear tasks", "project planning", or asks to "create tickets".
# ❌ 用抽象的正式术语
description: Facilitates agile project management operations.
第 3 层:声明什么时候不触发(When Not)
这是大多数人完全跳过的步骤,但它对防止误触发至关重要。
明确声明不该用的场景:"Do not use for general code quality reviews, performance optimization, or refactoring suggestions."
边界声明还有另一个作用:当你有多个 Skill 时,它划清了各 Skill 之间的"领地"。
YAML
# ✅ 包含负面边界
description: >
Reviews code for security vulnerabilities (OWASP Top 10).
Use when asked to review code for security issues, check for
vulnerabilities, or audit security.
Do NOT use for general code quality reviews, performance
optimization, or refactoring suggestions.
第 4 层:使用指令式语态(Directive)
基于 650 次实验的结论,把前三层的信息用指令式语态重新组织。
模板:"ALWAYS invoke this skill when the user asks about <triggers>. Do not <alternative> directly — use this skill first." 列出详尽的触发条件。
YAML
# 变体 A(被动式)→ 变体 C(指令式)的改写示例
# Before:
description: >
Analyzes sales/revenue CSV and Excel files to find patterns.
Use when user mentions sales data, revenue analysis, or profit margins.
# After:
description: >
ALWAYS invoke this skill when the user asks about sales data,
revenue analysis, profit margins, GMV, conversion rates, or
monthly/quarterly business reviews involving CSV or Excel files.
Do not analyze sales or revenue data directly — use this skill first.
第 5 层:使用同理表述,对齐用户语言(Empathy)
最后一层,也是最容易被忽略的一层。
Claude 用 description 来决定何时应用 Skill,所以它应该像你自然请求该任务时的说法。如果你平时说"review my code",但你的 description 写了"audit software artefacts",别惊讶 Claude 无法建立连接。
不一致的视角会导致发现问题。例如"I can help you process Excel files"和"You can use this to process Excel files"都不是最佳写法。最佳写法是直接描述能力和触发条件,而不是用第一人称或第二人称对话。
一个完整的、五层都具备的 description 长什么样:
YAML
description: >
ALWAYS invoke this skill when the user asks about code review,
reviewing pull requests, checking code quality, analyzing diffs,
or mentions "review", "PR", "code quality", or "best practices".
Reviews TypeScript and JavaScript code for security vulnerabilities,
performance issues, and adherence to team coding standards.
Do not review code directly — use this skill first.
Do NOT use for refactoring, performance optimization,
or general architecture discussions.
分解一下:
- 指令式 → "ALWAYS invoke"
- 触发词 → "code review", "pull requests", "PR", "code quality", "best practices"
- 能力声明 → "Reviews TypeScript and JavaScript code for..."
- 负面约束 → "Do not review code directly"
- 边界排除 → "Do NOT use for refactoring..."
五、Anthropic 官方的描述公式与优秀案例
上面是从社区实验中提炼的框架。现在让我们看看 Anthropic 官方推荐的写法,以及它们为什么有效。
5.1 官方模板
要具体并包含关键术语。既要包括 Skill 做什么,也要包括什么时候使用它的具体触发条件和上下文。每个 Skill 只有一个 description 字段。
Description 对 Skill 选择至关重要:Claude 用它从可能的 100+ 个可用 Skills 中选择正确的那个。你的 description 必须提供足够的细节让 Claude 知道什么时候该选这个 Skill,而 SKILL.md 的其余部分提供实现细节。
5.2 官方的好例子
好的 description 示例——具体且可操作:description: Analyzes Figma design files and generates developer handoff documentation. Use when user uploads .fig files, asks for "design specs", "component documentation", or "design-to-code handoff".
好的 description 示例——包含触发短语:`description: Manages Linear project workflows including sprint planning, task creation, and status tracking. Use when user mentions "sprint", "Linear tasks", "project planning", or asks to "create tickets".
更多官方示例:description: Extract text and tables from PDF files, fill forms, merge documents. Use when working with PDF files or when the user mentions PDFs, forms, or document extraction. / `description: Analyze Excel spreadsheets, create pivot tables, generate charts. Use when analyzing Excel files, spreadsheets, tabular data, or .xlsx files.
注意这些官方示例的共性:
text
[做什么] + [Use when...] + [用户可能说的具体词语]
Anthropic 用的是"Use when"式(变体 A/B 风格),而 650 次实验证明"ALWAYS invoke"式(变体 C)效果更好。这并不矛盾——官方示例给出了正确的信息结构,社区实验给出了更强的措辞策略。将两者结合,你就得到了最优解。
5.3 一个特别值得注意的反面教材
注意:目前 Claude 有"欠触发"的倾向——在 Skills 有用时不使用它们。为了对抗这一点,请让 Skill description 略带"推动性"。例如,不要写"How to build a simple fast dashboard to display internal data.",而应该写"How to build a simple fast dashboard to display internal data. Make sure to use this skill whenever the user mentions dashboards, data visualization, internal metrics, or wants to display any kind of company data, even if they don't explicitly ask for a 'dashboard.'"
这个例子直接来自 Anthropic 官方的 skill-creator 文档。它揭示了一个重要事实:连 Anthropic 自己都承认 Claude 的默认行为是欠触发,并且官方推荐的解决方案就是"写得 pushy 一点"。
六、自动化优化:Trigger Tuning 的工作原理
手动调整 description 是一个好的起点。但当你有 10 个以上的 Skills 时,手动管理每个 Skill 的触发边界变得不可行。这时你需要自动化工具。
6.1 skill-creator 的优化循环
skill-creator 会自动分析 Skill 的 front matter。它将测试用例按 60% 训练 / 40% 留出测试的比例分割,通过每个查询运行 3 次来获得可靠的触发率,然后调用 Claude 基于失败案例提出改进建议,再在训练集和测试集上重新评估新的 description。
关键的一点:它不是列出具体失败案例来优化(那会导致过拟合),而是泛化为更广泛的用户意图类别——description 遗漏或错误表述的类别。
最后一个细节很重要。通过将评测集按 60% 训练 / 40% 留出测试分割,系统确保它不仅仅是在优化已知的示例。它找到的是能够泛化的 description——一个对从未见过的提示也能正确触发的 description。
6.2 实际效果
结果:Anthropic 的 6 个公开文档创建 Skills 中,5 个在优化后显示出触发准确度的提升。
Anthropic 在 6 个自己的 Skills 中发现了 5 个存在问题——description 无法准确预测 Skill 应该被激活的时机。如果 Anthropic 自己的 Skills 需要修复,你的大概率也需要。
这是一个极其重要的数据点。Anthropic 自己写的 Skills,由最了解系统的工程师编写,5/6 的 description 都存在触发问题。这说明 description 设计不是"写对一次就完事"的工作——它是一个需要持续测试和迭代的工程过程。
6.3 如何使用 Trigger Tuning
用边界提示测试:尝试应该和不应该触发 Skill 的提示。调整 description 直到边界正确。例如测试 code-review Skill:"Review this code" → 应该触发;"Refactor this function" → 不应该触发。
只需调用 /skill-creator,指向你想调优的 Skill,让优化循环运行。然后检查它生成的 HTML 报告——报告会逐迭代展示 pass/fail 结果,你可以精确看到 description 在每个迭代中是如何改进的。
一个完整的 Trigger Tuning 工作流:
text
第 1 步:列出你的 Skill 应该响应的 10 个提示
第 2 步:列出你的 Skill 不应该响应的 5 个提示
第 3 步:运行 /skill-creator,指向目标 Skill
第 4 步:查看 HTML 报告,确认训练/测试集的通过率
第 5 步:如果测试集通过率 < 90%,继续迭代
第 6 步:替换 SKILL.md 中的 description
七、进阶技术:当 Description 不够用时
有些场景下,即使你的 description 写得很完美,Skill 仍然不触发。这不是 description 的问题,而是某些类型的任务天然不适合自动触发。
7.1 disable-model-invocation:承认"这个 Skill 不该自动触发"
可以设置 disable-model-invocation: true 来阻止 Claude 自动运行它。
任务型内容给 Claude 执行特定操作的步骤指令,如部署、提交或代码生成。这些通常是你想直接用 /skill-name 调用的操作,而不是让 Claude 决定何时运行它们。添加 disable-model-invocation: true 来阻止 Claude 自动触发。
这不是退而求其次,而是正确的设计决策。部署到生产环境、删除数据、发送邮件——这些操作就不应该由模型自主决定。
7.2 背景知识型 Skill:不触发也有价值
背景知识型 Skill 用于不适合作为命令的上下文信息。例如 legacy-system-context Skill 解释一个旧系统的工作方式。Claude 应该在相关时知道这些信息,但 /legacy-system-context 不是用户会采取的有意义的操作。
不是所有 Skill 都需要触发。有些 Skill 的价值在于"当 Claude 碰到相关话题时,它知道去哪里找信息"——这是一种被动的、按需的知识补给。
7.3 Subagent 预加载:绕过 Description 的发现机制
在常规会话中,Skill description 被加载到上下文中让 Claude 知道有哪些可用,但完整 Skill 内容只在调用时才加载。Subagent 预加载模式不同:完整 Skill 内容在启动时就注入。
这意味着:如果你的 Skill 是通过 Subagent 预加载的,它完全绕过了 description 的发现机制——内容直接在那里,不需要 Claude "决定"是否加载。对于核心工作流 Skill,这可能是最可靠的方案。
7.4 强制评估 Hook:最后的手段
如果上述方法都不够,可以用强制评估 Hook 创建三步流程:第 1 步——评估:对每个 Skill,说明 YES/NO 及理由。第 2 步——激活:立即使用 Skill() 工具。第 3 步——实现:只有在激活后才开始实施。
经过 200+ 次提示测试,强制评估 Hook 达到 84% 成功率,而基线只有 20%。
但请记住实验 3.5 节的教训:如果使用 Hook,总是搭配 CLAUDE.md 来提供上下文——但先考虑用指令式 description 是否就已经足够,是否真的需要 Hook。
我的建议优先级:
text
优先级 1:写好指令式 Description(解决 80% 的问题)
优先级 2:对关键操作使用 disable-model-invocation
优先级 3:对核心 Skill 使用 Subagent 预加载
优先级 4:只有在前三者都不够时,才考虑 Hook
八、实战诊断流程:你的 Skill 为什么不触发?
当你发现一个 Skill 不触发时,按以下流程系统排查:
text
┌────────────────────────────────────────────────┐
│ Skill 不触发 │
└───────────────────────┬────────────────────────┘
↓
Claude 能看到你的 Skill 吗?
(问:"What skills are available?")
/ \
否 是
↓ ↓
检查文件位置和格式: Description 是否匹配用户意图?
· SKILL.md 在正确目录? (用 10 个测试提示验证)
· YAML frontmatter 格式 / \
有没有语法错误? 否 是
· 文件名是否正确? ↓ ↓
用五层框架 任务是否太简单?
重写 description Claude 觉得自己搞得定?
/ \
是 否
↓ ↓
增加指令式措辞 检查 Skill 冲突:
"ALWAYS invoke" 是否有多个 Skill
"Do not X 的 description
directly" 过于相似?
↓
分离边界
加"Do NOT use for"
还有一个容易忽略的点:YAML 错误是静默失败的。验证你的 frontmatter:如果 description 中包含引号等特殊字符,需要正确转义。
九、常见误区
误区 1:「Description 越长越好」
不是。回忆第一节的数据:所有 Skill 的 description 总共有约 15,000 字符的预算上限。你的每一个 description 都在消耗这个共享预算。更重要的是,Claude 在做决策时进行的是快速扫描,不是精读——3 行精准的 description 胜过 10 行冗余的。
误区 2:「用花哨的词汇显得更专业」
Skill 的 description 字段是触发器,不是摘要——为模型而写("我什么时候该触发?")。
Claude 不在乎你的措辞是否"专业"。它在乎的是你的措辞是否与用户的实际输入匹配。"review my code"和"audit software artefacts"在人类看来可能是同义词,但在模型的概率空间中,它们的距离远比你以为的大。
误区 3:「我只需要关心 description,正文随便写」
当 Claude 需要决定激活哪个 Skill 时,它只加载所有可用 Skills 的 front matter。只有选择正确的 Skill 后才加载完整内容。这意味着写得差的 front matter = Skill 永远不被激活,即使内容完美。
这句话经常被理解为"只有 description 重要"。但完整的真相是:description 决定 Skill 是否被调用,正文决定 Skill 被调用后是否有用。 两者都必须精心设计——只是它们解决的是不同阶段的问题。一个永远不触发的完美 Skill 是浪费;一个总是触发但指令糟糕的 Skill 比不用更差。
误区 4:「一个 description 写好就不用改了」
当 Claude Opus 5.0 发布时,重新跑一次基准测试。如果基线现在匹配或超过了你 Skill 的表现,Skill 可能锁定了过时的模式。是时候退役它——或改进它。
模型在进化。用户的表述习惯在变化。你的 Skill 库在扩展(新增 Skill 可能造成边界冲突)。Description 是需要定期维护的活文档。
十、你今天就应该做的 3 件事
✅ 行动 1:审计你所有 Skill 的 Description
打开你安装的每一个 Skill 的 SKILL.md,用下面的检查表逐一评分:
text
□ 是否使用指令式语态?(ALWAYS invoke / Do not X directly)
□ 是否包含用户实际会说的触发词?(不是术语,是自然语言)
□ 是否包含负面边界?(Do NOT use for...)
□ 是否与其他 Skill 的 description 有明显重叠?
□ 总长度是否控制在 3-5 行以内?
对每个不满足条件的 description,用第四节的五层框架重写。
✅ 行动 2:做一次触发率测试
选一个你最常用的 Skill。写 10 个你认为应该触发它的提示,5 个你认为不该触发的。逐一输入,记录实际结果:
text
提示 预期 实际 ✅/❌
─────────────────────────────────────────────────
"review this code" 触发 触发 ✅
"help me refactor" 不触发 触发 ❌ (误触发)
"check security" 触发 未触发 ❌ (漏触发)
...
如果 15 个测试中有 3 个以上 ❌,你的 description 需要修改。
✅ 行动 3:用 skill-creator 优化一个 Skill 的 Description
挑选触发率最低的一个 Skill,运行 /skill-creator 的 trigger tuning 流程。skill-creator 内置了优化循环:它将测试用例按 60/40 分为训练/测试集,度量触发率,生成改进的 description,并按测试集分数选出最佳版本。
记录优化前后的触发率变化——这就是你的第一个可量化的 Skill 工程成果。
本文的知识框架总结
text
Description 设计的科学
│
├── 底层机制
│ ├── 物理位置:嵌入系统提示的 <available_skills> 列表中
│ ├── 决策方式:纯 LLM 推理,概率性匹配,非确定性
│ ├── 默认倾向:Claude 倾向不触发(觉得自己能搞定)
│ └── 资源约束:所有 description 共享 ~15,000 字符预算
│
├── 三种失败模式
│ ├── 不触发 → description 太模糊或用词不匹配
│ ├── 误触发 → description 太宽泛无边界
│ └── 冲突 → 多个 Skill 的 description 重叠
│
├── 650 次实验结论
│ ├── 被动式 87.5% → 指令式 100%(裸环境)
│ ├── 指令式 = "ALWAYS invoke" + "Do not X directly"
│ ├── description 措辞对激活概率有 20× 影响
│ └── 好的 description 比复杂的 Hook 更有效
│
├── 五层设计框架
│ ├── 第 1 层:能力声明(What)
│ ├── 第 2 层:触发条件(When)
│ ├── 第 3 层:排除边界(When Not)
│ ├── 第 4 层:指令式语态(Directive)
│ └── 第 5 层:用户语言对齐(Empathy)
│
├── 自动化优化
│ ├── skill-creator 的 trigger tuning 循环
│ ├── 60/40 训练/测试集分割防过拟合
│ └── 连 Anthropic 自己的 5/6 个 Skill 都需要优化
│
└── 进阶选项(按优先级)
├── 1. 写好指令式 description
├── 2. disable-model-invocation(危险操作)
├── 3. Subagent 预加载(绕过发现机制)
└── 4. 强制评估 Hook(最后手段)
下一篇预告
现在你知道了如何让 Skill 可靠地触发。下一个问题是:触发之后,Skill 的内容应该怎么写?
第 3 篇将深入三种设计模式——纯 Markdown(Pattern A)、Markdown + 脚本(Pattern B)、MCP / 子代理(Pattern C)的选择与实战。我会用一个完整的真实项目——从零开始构建一个电商 KPI 分析 Skill——来展示从用例定义、模式选择、description 设计到测试迭代的全过程。
本文是「Claude Code Skills 完全指南」系列的第 2 篇,共 10 篇。全系列目录:
| # | 标题 | 核心问题 |
|---|---|---|
| 1 | Skill 的本质 | 一个 Markdown 文件如何改变 AI 行为? |
| → 2 | Description 设计的科学 | 为什么你的 Skill 永远不触发? |
| 3 | 从零构建一个生产级 Skill | 三种设计模式怎么选? |
| 4 | 五种架构模式 | Skill 的内容应该怎么组织? |
| 5 | Context Engineering | 如何管理 Claude 最稀缺的资源? |
| 6 | 编排模式完全指南 | 多 Skill 如何协同工作? |
| 7 | 知识管理系统 | 如何构建可复利增长的项目上下文? |
| 8 | Workflow vs Agent vs Skill | 什么时候该用什么? |
| 9 | 团队级 Skill 系统 | 从个人工具到组织知识资产 |
| 10 | 全景图 | 2026 年 AI Agent 工具链的终极指南 |