首页 › tutorials › 调优Skill描述:让技能精准触发

Claude Code Skill 描述字段调优实战:让技能精准触发

概述

很多开发者第一次创建 Skill,写完 SKILL.md 却发现:明明场景吻合,Claude 就是不调用它。本教程聚焦 Claude Code Skill 里最关键、也最容易被忽视的一个字段——description。你将从零创建一个 api-error-triage 技能,亲手经历「不触发 → 误触发 → 精准触发」的完整调优过程,掌握「what + when + 第三人称」的描述写法、三类探针验证法,以及一份可复用的故障排查清单。适合已跑通 Claude Code、想做出可靠自定义技能的中级用户。

前置条件


第 0 步:先搞懂一件事——Skill 的路由是「推理」不是「匹配」

在动手前,必须建立一个正确的心智模型,否则后面的所有调优都是盲目的。

绝大多数人以为 Skill 是靠「关键词命中」触发的,于是拼命往描述里堆关键词。但官方文档与社区实测都指向同一个事实:Claude Code 的技能路由是纯 LLM 语义推理,而不是算法匹配(不是正则、不是关键词索引、不是 GBNF 规则)。

这意味着:

常见误解 实际机制
描述里写了 error 就会在出现 error 时触发 Claude 读懂整句话的语义与意图才决定是否调用
关键词越多、列表越长,触发率越高 堆砌关键词反而稀释语义、降低命中
技能名 debug-tool 决定何时触发 名字只影响可读性与 / 调用,描述才是路由信号

结论:你的 description 是写给一个「会推理的读者」看的。它需要在极短的篇幅里讲清楚两件事——这个技能做什么(what),以及什么情况下该用它(when)。整篇文章都在围绕这两点展开。


第 1 步:搭出最小骨架

一个 Skill 的物理形态极其简单:一个文件夹,里面一个 SKILL.md。先把它搭出来。

操作命令:

# 准备实验室目录
mkdir -p ~/triage-lab/.claude/skills/api-error-triage/references
cd ~/triage-lab

# 写出第一个 SKILL.md(先故意写一个「会失败」的版本)
cat > .claude/skills/api-error-triage/SKILL.md <<'EOF'
---
name: api-error-triage
description: Helps with errors.
---

# API Error Triage

分析 API 错误,输出诊断报告。
EOF

目录结构预期:

~/triage-lab/
└── .claude/
    └── skills/
        └── api-error-triage/
            ├── SKILL.md
            └── references/

验证已加载: 在 ~/triage-lab 下启动 Claude Code,输入:

/skills

应能看到 api-error-triage 出现在技能列表里。如果你看到的描述是空的,或技能根本没出现——几乎可以断定是你的 frontmatter YAML 写坏了(缩进错、冒号后没空格、引号没闭合)。官方文档明确指出:frontmatter 解析失败时,技能体会被以「空元数据」加载,于是 /skills 里它要么不显示、要么描述为空。

常见问题:name 必须是 kebab-case(小写、连字符分隔,如 api-error-triage),且要和文件夹名一致。写成 Api_Error_Triage 会导致加载异常。


第 2 步:写一个「不触发」的描述(反面教材)

现在我们有了一个能加载、但永远不会被调用的技能。先实测它的失败表现。

操作: 在 Claude Code 里直接粘贴一段真实的 API 错误,不要点名任何技能:

我的请求返回了这个:
{"error":{"code":"permission_denied","message":"Missing access to resource res_abc123"}}

帮我看看怎么回事?

预期(失败)结果: Claude 会用自己的通用知识回答,完全不会调用 api-error-triage。因为描述 Helps with errors. 对一个推理引擎来说信息量约等于零——它既没说处理哪类错误,也没说何时该用。

为什么不触发: Helps with errors. 违反了三条铁律——

  1. 没有 when:没说处理哪种错误、什么场景下用。
  2. 没有 what:没说输出什么(报告?修复脚本?翻译?)。
  3. 主语模糊:「Helps」是第一人称视角的口语,不是对技能的客观描述。

第 3 步:用「what + when + 第三人称」重写描述

这是全文的核心。Anthropic 在《Lessons from building Claude Code: How we use skills》里反复强调:描述要用第三人称写,说清楚做什么和何时用。下面是同一技能的三版迭代,请逐字对照。

迭代 A:加 when,但主语还是错的

description: Use this when the user pastes an API error.

进步:有了 when。但 Use this 是祈使句、隐含第二人称,语义仍偏弱,且没说做什么。

迭代 B:补上 what,但动词太泛

description: Analyzes API errors when the user pastes a failing request or error response, and helps debug them.

进步:第三人称(Analyzes),有 when 也有 what。问题在 helps debug them——「debug」是个筐,什么都往里装,和 Claude 自带的调试能力区分度不够,容易被忽略。

迭代 C(最终版):语义饱和、边界清晰

description: Triages HTTP and API errors—4xx/5xx responses, stack traces, error JSON, connection or timeout failures—into a structured root-cause report with a category, the likely cause, and the single next troubleshooting step. Use whenever the user pastes an error, shares a failing request/response, or asks "why is this error happening" or "what does this error mean".

为什么这版能稳定触发,逐句拆解:

元素 写法 作用
动词 Triages(第三人称单数) 明确动作类型=分类诊断,区别于「修复」「翻译」
输入边界 4xx/5xx responses, stack traces, error JSON, connection or timeout failures 给推理引擎具体的可识别形态,不是抽象词
输出物 structured root-cause report with a category, the likely cause, and the single next troubleshooting step 告诉它产出什么,且独一无二
触发时机 Use whenever the user pastes an error, shares a failing request/response, or asks "why..." 直接列举用户会说的原话与动作

把这一版覆盖回 SKILL.md 的 frontmatter,保存。

口诀:动词用第三人称单数;输入给具体形态;输出给独一无二的结构;when 直接引用用户原话。四件齐全,触发率立竿见影。


第 4 步:用三类探针验证触发可靠性

改完描述不能靠「感觉对了」收工。用一个最小测试套件——三类探针——量化验证。在同一个会话里依次抛出:

探针 1:正例(应该触发)

curl 返回 {"error":{"code":"permission_denied",...}},怎么办?

✅ 期望:Claude 调用 api-error-triage,输出结构化报告。

探针 2:边界正例(口语化触发)

这个 502 是什么意思啊,帮我看看

✅ 期望:仍触发。检验描述里的「asks why...」语义是否覆盖口语。

探针 3:反例(不该触发)

帮我写一个返回 4xx 的 mock 接口

❌ 期望:不触发。这是「生成错误」而非「诊断错误」。如果这里也触发了,说明描述边界太宽(你写了 errors 却没限定「已发生的错误」),需要收紧。

如何确认技能真的被调用:调用时 Claude Code 会在界面显示技能加载提示(如「Loaded skill: api-error-triage」),你也能从输出风格(是否严格遵循报告格式)判断。建议每个探针跑 2–3 次——因为路由是推理、带一定随机性,单次不可靠,多次稳定才是真稳定。

常见问题:正例偶尔触发、偶尔不触发。多半是描述里缺少「输入形态」清单(迭代 C 第一行那串具体例子),补上即可显著提升一致性。


第 5 步:渐进披露——SKILL.md 保持精简,细节拆到引用文件

触发解决后,下一个坑是上下文预算。技能一旦被调用,SKILL.md 正文会被整篇载入上下文。正文越长,每次调用越烧 token。正确做法是「渐进披露」:SKILL.md 只放骨架与指针,细节放进按语义命名的文件,让 Claude 按需读取。

操作: 把错误码知识库拆出去。

references/error-codes.md:

# 常见 API 错误码速查

## permission_denied
- 类别:鉴权/授权
- 常见原因:API Key 缺少该资源的 scope,或资源归属其他账号
- 下一步:检查 Key 权限范围,或在控制台重新授权该资源

## rate_limit_exceeded
- 类别:限流
- 常见原因:短时间请求过多
- 下一步:读取响应头 Retry-After,按指数退避重试

## 5xx / 502 / 503
- 类别:上游故障
- 常见原因:服务端过载或网关异常
- 下一步:等待 30s 重试;持续失败则查状态页

精简后的 SKILL.md 正文(frontmatter 保持迭代 C):

# API Error Triage

收到 API 错误时,输出一份结构化根因报告。

## 流程
1. 从错误中识别 code / status / message。查 `references/error-codes.md` 拿到对应条目。
2. 按下方格式输出,每项不超过一句话。

## 输出格式
- **类别**:<鉴权 / 限流 / 上游故障 / 参数错误 / 其它>
- **最可能原因**:<一句话>
- **下一步**:<单个、可立即执行的动作>

为什么这样写有效:

常见问题:把所有内容塞进 SKILL.md。后果是每次调用都把几百行知识库灌进上下文,既慢又贵。原则——SKILL.md 像目录页,引用文件像章节正文。


第 6 步:故障排查清单

把踩过的坑沉淀成一张速查表,遇到不触发直接对照:

症状 可能原因 修复
/skills 里看不到技能 YAML 解析失败 / 文件夹名与 name 不一致 检查缩进、冒号后空格;name 用 kebab-case 且等于文件夹名
看得到但从不触发 描述无 when、无 what、主语非第三人称 回到第 3 步四要素重写
偶尔触发、不稳 描述缺「输入形态」清单 补具体形态(如 4xx/5xx、stack trace)
误触发(反例也中招) 边界过宽,动词太泛(debug/help) 收紧 when,用独一无二的结构输出
与其他技能打架 两个技能描述语义重叠 给每个补独有边界,必要时用 disable-model-invocation 让其一改为 / 手动调用

关于 disable-model-invocation:这是一个可选的布尔 frontmatter 字段。设为 true 时,该技能不再被模型自动调用,只能通过 /技能名 显式触发。适合那些「容易和别的技能抢戏、但你希望完全手动控制」的场景——比如一个重型的安全审查技能,宁可手动唤起也不要它擅自介入。


实战案例:完整的 api-error-triage 技能

把前面所有步骤合起来,这是一个可直接复制运行的完整项目。

目录结构:

~/triage-lab/.claude/skills/api-error-triage/
├── SKILL.md
└── references/
    └── error-codes.md

SKILL.md(完整):

---
name: api-error-triage
description: Triages HTTP and API errors—4xx/5xx responses, stack traces, error JSON, connection or timeout failures—into a structured root-cause report with a category, the likely cause, and the single next troubleshooting step. Use whenever the user pastes an error, shares a failing request/response, or asks "why is this error happening" or "what does this error mean".
---

# API Error Triage

收到 API 错误时,输出一份结构化根因报告。

## 流程
1. 从错误中识别 code / status / message。查 `references/error-codes.md` 拿到对应条目。
2. 按下方格式输出,每项不超过一句话。

## 输出格式
- **类别**:<鉴权 / 限流 / 上游故障 / 参数错误 / 其它>
- **最可能原因**:<一句话>
- **下一步**:<单个、可立即执行的动作>

references/error-codes.md 内容见第 5 步。

端到端测试: 启动 Claude Code,粘贴:

POST /v1/charges 返回:
HTTP 429
{"error":{"code":"rate_limit_exceeded","message":"Too many requests"}}
怎么办?

期望输出:

- 类别:限流
- 最可能原因:短时间请求过多,触发服务端限流。
- 下一步:读取响应头 Retry-After,按指数退避(如 1s → 2s → 4s)重试。

至此,你拥有了一个会精准触发、上下文精简、输出稳定的生产级技能。把它从项目目录 .claude/skills/ 复制到 ~/.claude/skills/,即可升级为个人全局技能,在所有项目里通用。


工作流程图

图一:技能发现与调用流程(路由靠语义推理)

flowchart TD
    A[用户输入消息] --> B{Skill 路由判断}
    B -->|纯 LLM 语义推理<br/>非关键词匹配| C{description 是否<br/>语义吻合?}
    C -->|否| D[使用通用能力回答<br/>技能未触发]
    C -->|是| E[加载该技能 SKILL.md 正文]
    E --> F{正文是否引用<br/>其它文件?}
    F -->|是| G[按需读取 references/* ]
    F -->|否| H[直接执行]
    G --> H
    H --> I[产出结构化输出]

图二:描述字段调优闭环

flowchart LR
    W[写 description<br/>what+when+第三人称] --> T[跑三类探针<br/>正例/边界/反例]
    T --> M{多次稳定触发?}
    M -->|否| R[诊断: 无when?/边界宽?/主语错?] --> W
    M -->|是| D[确认可靠, 投入使用]

延伸阅读


训练营适用性评估


参考来源

  1. Extend Claude with skills — Claude Code Docs — 官方技能创建/管理权威文档,含 frontmatter 解析失败处置
  2. Lessons from building Claude Code: How we use skills — Anthropic 内部大规模使用技能的经验,强调描述第三人称写法
  3. Skill authoring best practices — Claude Platform Docs — 官方最佳实践:描述的 what+when 与渐进披露
  4. Claude Agent Skills Not Triggering? The Problem is in Your Description — 系统化的描述设计模式与触发率提升模板
  5. Claude Code Skills Structure and Usage Guide (gist) — 明确「技能路由为 LLM 推理而非算法匹配」的关键结论

本文由「51学通信」原创整理,站长爱卫生(微信:gprshome201101)持续输出通信与 AI 工程实战内容。

[!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学通信知识星球海报-扫码加入