Skill 规范审计之错误写法

给 Claude Code 写了很多自定义 Skill,用了几个月,直到按官方规范做了一次全面审计,才发现每一个 Skill 的 description 都踩了同一个坑。

这个坑不是语法错误,不是功能缺陷,而是一个认知陷阱:我一直在告诉 Claude “ 我是谁 “,而不是 “ 什么时候该找我 “。

1. Description 是路由条件,不是功能说明

Skills 是上下文工程里一种有效的模式:系统提示只保留索引,完整知识按需加载。

1
2
3
4
可用 Skills:
- deploy: 部署到生产环境的完整流程
- code-review: 代码审查检查清单
- git-workflow: 分支策略和 PR 规范

Claude Code 在每次对话启动时,将所有 Skill 的 name 和 description 注入系统提示词。Claude 扫描这份清单,决定当前任务是否需要加载某个 Skill 的完整内容。有明确匹配时读取 SKILL.md,多个匹配时优先选最具体的,没有匹配就跳过。

整个决策过程可以用一张路由流程图概括:

%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#3B82F6', 'primaryTextColor': '#1E3A5F', 'primaryBorderColor': '#2563EB', 'lineColor': '#60A5FA', 'secondaryColor': '#10B981', 'tertiaryColor': '#F59E0B'}}}%%
flowchart TD
    A["对话启动"] --> B["扫描所有 Skill 的 description"]
    B --> C{"任务与 description 匹配?"}
    C -->|"无匹配"| D["跳过, 不加载任何 Skill"]
    C -->|"单个匹配"| E["加载该 Skill 的 SKILL.md"]
    C -->|"多个匹配"| F["选最具体的 Skill 加载"]
    E --> G["按正文执行"]
    F --> G

    classDef default fill:#EFF6FF,stroke:#2563EB,color:#1E3A5F
    classDef decision fill:#FEF3C7,stroke:#F59E0B,color:#92400E
    classDef skip fill:#FEE2E2,stroke:#EF4444,color:#991B1B
    classDef load fill:#D1FAE5,stroke:#10B981,color:#065F46
    class C decision
    class D skip
    class E,F,G load

所以 description 是路由判断依据,不是功能说明书。每个启用的 Skill 描述符常驻上下文,数量一多,长描述的累积 token 成本很可观:

1
2
3
4
5
6
7
8
# 低效(约 45 tokens)
description: |
This skill handles the complete deployment process to production.
It covers environment checks, rollback procedures, and post-deploy
verification. Use this before deploying any code to production.

# 高效(约 9 tokens)
description: Use when deploying to production or rolling back.

路由准确率差距不大,但 45 tokens × 20 个 Skill = 900 tokens 常驻开销,9 tokens × 20 = 180 tokens,差 5 倍。

描述太短也有问题。help with backend 会让任何后端工作都触发,路由会乱。有效的描述符应是路由条件:Use when... 说明什么时候该用,Don't use when... 划清边界,再补反例。

测试数据显示:没有反例时路由准确率从基准 73% 掉到 53%,加上反例后升到 85%,响应时间降了 18.1%。反例不是可选项,是描述符正确路由的关键。

但我之前写的 description 全在做自我介绍:

1
2
3
4
# 原始写法
description: 顶级战略产品师。对当前项目进行深度战略审视,通过犀利提问暴露产品盲区,
输出竞品调研、产品重构方案和商业化路径。融合 Marty Cagan 的产品发现思想、
Peter Thiel 的垄断战略和 Y Combinator 的增长方法论。

这段 description 有 3 个问题:

  • 角色宣言开头:” 顶级战略产品师 “——Claude 不需要知道你自封了什么头衔
  • 流程摘要:把 Skill 正文的工作流程压缩到了 description 里
  • 缺少触发条件:Claude 读完知道这个 Skill 很厉害,但不知道什么情况下该用它

理解了 description 的路由本质后,接下来看最容易踩的一类错误:在 description 里概括工作流程。

2. 流程摘要是最危险的陷阱

在所有错误中,” 在 description 里概括工作流程 “ 杀伤力最大。

官方规范的测试发现:当 description 写了 “code review between tasks”,Claude 只做了一次 review。但 Skill 正文的流程图明确要求两次——先查规范合规,再查代码质量。

原因是 Claude 把 description 当成了快捷指令,跳过了正文。Description 越详细,Skill 正文越容易被忽略。

我的 code-simplifier 就是典型反面教材。原始 description 长达 300+ 字符,包含功能说明、两种工作模式,甚至内嵌了 example 标签:

1
2
3
4
5
6
7
# 反面教材:300+ 字符的 description
description: "代码简化与优化专家/代码简化。Use this agent when you need to simplify,
optimize, refactor, or clean up code. This agent helps reduce complexity,
improve readability, and ensure code follows best practices like YAGNI, KISS,
and DRY principles. Supports two modes: analysis mode (provides simplification
suggestions) and execution mode (directly modifies code). Works with any
programming language. Examples: <example>..."

Claude 读到这段 description 就已经 “ 知道该怎么做了 “,SKILL.md 正文里精心设计的评估维度、简化策略、代码模式对比?大概率直接跳过。

修正后只保留触发条件:

1
2
description: Use when code has excessive complexity, deep nesting, unused
abstractions, or violates YAGNI/KISS/DRY principles and needs simplification
维度修正前修正后
开头“ 代码简化与优化专家 ““Use when”
内容功能说明 + 模式介绍 + 示例触发场景
长度300+ 字符~120 字符
Claude 行为按 description 执行,跳过正文匹配后加载正文,按正文执行

写完 description 后可以用一条标准检验:如果 Claude 只读 description、不读 SKILL.md 正文,它的行为会和读了正文一样吗?如果答案是 “ 差不多 “,说明 description 泄露了太多信息。好的 description 让 Claude 知道 “ 需要加载这个 Skill”,但不知道 “ 加载后该怎么做 “。

修正了流程摘要问题后,还有 4 类常见的 description 错误模式。

3. 五类 Description 错误模式

审计完 19 个 Skill,错误可以归为 5 类。除了前面展开的流程摘要式,其余 4 类用对比表说明。

3.1 角色宣言式

1
2
3
4
5
6
7
# ❌ 我是谁
description: 顶级 UI/UX 设计审计师。
description: 代码重构专家/代码重构。
description: 每日书籍推荐官。

# ✅ 什么时候找我
description: Use when auditing UI/UX design quality, reviewing visual aesthetics...

“ 顶级 “” 专家 “” 官 “ 这些词对路由判断没有信息量。Claude 不会因为你自称 “ 顶级 “ 就优先加载。

3.2 功能说明式

1
2
3
4
5
6
# ❌ 我能做什么
description: 价值判断与打分工具。对书籍、文章、GitHub项目进行多维度评分。

# ✅ 什么场景需要我
description: Use when evaluating whether a book, article, GitHub project...
is worth investing time in

3.3 穷举触发词式

1
2
3
4
5
6
7
8
9
# ❌ 列举所有可能的触发场景
description: 当用户需要:(1) 查询某领域最新新闻 (2) 了解某公司动态
(3) 追踪某人物近况 (4) 获取某地区新闻 (5) 了解某产品最新情况
(6) 追踪某事件进展 (7) 询问需要最新信息才能回答的问题...
触发关键词包括:新闻、动态、最新、最近、近况、进展、资讯等。

# ✅ 概括核心场景
description: Use when the user asks about latest news, recent developments,
or current status of any topic, company, person, or event

穷举 7 个场景 + 7 个关键词,浪费 token,还暗示 “ 不在列表里的场景不要触发 “。

3.4 混合语言堆叠式

1
2
3
4
5
6
7
# ❌ 中英文混杂 + 关键词堆叠
description: codereview / code review / 代码审查 - Go 代码审查技能,
专注于性能、并发安全、安全性和可读性四大核心维度。

# ✅ 清晰的触发条件
description: Use when reviewing Go code for performance, concurrency safety,
security vulnerabilities, or readability issues

codereview / code review / 代码审查 这种 SEO 式关键词堆叠,在 Claude 的语义理解面前完全多余。

Description 层面的问题修完之后,正文同样需要审查。

4. 正文层面的常见问题

审查正文时发现了 4 类需要处理的问题。

4.1 “ 你是…” 角色扮演

19 个 Skill 里有 10 个以 “ 你是…” 开头:

1
2
3
4
5
# ❌ 角色扮演
你是一位资深 Go 架构师,遵循 Effective Go 及 Uber Go Style Guide 规范。

你是一位融合乔纳森·艾维(Apple)的克制精密与原研哉(MUJI)的空灵留白的
首席设计官。你有 15+ 年的产品设计经验,曾主导过亿级用户产品的设计系统。

Skill 规范定义很明确:Skills are reusable techniques, patterns, tools, reference guides,不是角色卡。

“ 你是一位资深 Go 架构师 “——Claude 已经知道自己会写 Go。” 你有 15+ 年的产品设计经验 “——虚构的履历对输出质量没有帮助,反而浪费 token,可能干扰模型的能力边界判断。

直接以核心原则开头:

1
2
3
4
# ✅ 直接切入
## Overview
Go 代码审查,聚焦性能、并发安全、安全性和可读性四个维度。
遵循 Effective Go 及 Uber Go Style Guide。

每个 “ 你是…” 前言占 30-80 个 token,10 个 Skill 累计 300-800 token,每次加载都在消耗上下文预算,换来的只是一段模型会忽略的人格设定。

4.2 超长 Skill 需要拆分

我的 mermaid-generator 有 608 行、1,694 个词——规范建议上限是 500 词。

原因是我把 16 种图表的完整模板全部内联到了 SKILL.md 里。每次用户说 “ 画个流程图 “,Claude 要加载全部 16 种图表模板,包括用不到的桑基图、象限图、Git 图。

规范建议:Heavy reference (100+ lines) 拆到 supporting file。

1
2
3
mermaid-generator/
SKILL.md # 核心规则 + 选型逻辑(130 行,530 词)
chart-templates.md # 16 种图表模板(448 行,按需引用)

拆分后 SKILL.md 从 1,694 词降到 530 词,模板文件只在 Claude 确认了图表类型后才被引用加载,单次对话节省约 1,100 token 的无效加载。

4.3 相似 Skill 必须划清边界

code-simplifier 做代码简化,code-refactor 做代码重构。听起来不同,但用户说 “ 这段代码太复杂了帮我改改 “ 时,Claude 不知道该加载哪个。两个 Skill 的 description 都能匹配,最终靠运气。

规范的 SKILL.md 结构里有 ## When to Use 章节,要求包含 “When NOT to use”。对于功能相近的 Skill,这是路由正确分流的关键。

修正方式是互相指向对方:

1
2
3
4
5
6
7
8
9
# code-simplifier
## When NOT to Use
- 需要改接口签名、拆模块、引入设计模式 → 用 code-refactor
- 需要审查安全/并发问题 → 用 go-code-review

# code-refactor
## When NOT to Use
- 只需要删代码、降复杂度、去冗余 → 用 code-simplifier
- 非 Go 语言代码 → 用 code-simplifier(支持任何语言)

划界的本质是给 Claude 一张路由表:用户意图匹配 A 还是 B,边界条件是什么,歧义时选哪个。没有这张表,Claude 只能猜。

4.4 重复代码需要抽取

7 个内容生成类 Skill 各自实现了一套几乎相同的去重逻辑:读取历史文件 → 查重 → 重试 → 生成 → 追加记录 → FIFO 淘汰。每个 Skill 里这段逻辑占 50-80 词,7 份就是 350-560 词的纯重复。

抽取为通用 supporting file,各 Skill 用两行引用替代:

1
2
3
4
## 去重与保存
去重流程参见 shared/dedup-history.md。本 Skill 配置:
- 历史文件:wisdom_history.json,领域轮换排除最近 2 条
- 输出目录:wisdom_decoder_outputs/

规范里有对应建议:”Use cross-references — Don’t repeat what’s in cross-referenced skills”。同一段逻辑写 7 遍,改一处要改 7 处,还容易漏。

正文问题之外,还有一类容易被忽视的优化:低频 Skill 的触发策略。

5. 低频 Skill 应降级为手动触发

审计还暴露了另一个问题:7 个 “ 每日内容生成器 “ 做成了自动匹配的 Skill。

这些 Skill 每天最多用一次,不辅助编程任务,本质上是固定格式的 Prompt 模板。作为自动匹配 Skill 存在的代价是:每次对话启动时 Claude 都要扫描它们的 description 判断是否需要加载。对于编程助手来说,99% 的对话不需要 “ 每日书籍推荐 “。

解决方案不是删除,而是降级为手动触发:

1
2
3
4
5
6
# 自动匹配模式(Claude 每次都要扫描判断)
description: Use when the user asks for book recommendations...

# 手动触发模式(Claude 扫描时直接跳过)
description: Only invoke when explicitly requested via "书籍推荐"、"@book-rec".
Do NOT auto-trigger.

Do NOT auto-trigger 让 Claude 在常规扫描时跳过这个 Skill,用户主动提及触发词时仍然可以加载。成本从 “ 每次对话都扫描 “ 降为 “ 仅在需要时加载 “。

6. Frontmatter 只支持两个字段

规范明确说 frontmatter 只支持 namedescription。但我有 3 个 Skill 加了 compatibility: opencode——为了兼容另一个 AI 编码工具。Claude Code 会静默忽略它,但它占 token、可能影响解析,属于无效负载。删除即可。

7. 一条检验标准

触发条件归 description,执行逻辑归正文。各司其职。

description 说 “ 什么时候该加载我 “,正文说 “ 加载后怎么做 “。两者职责不同,不应混淆。一旦 description 泄露了执行逻辑,Claude 就会走捷径跳过正文,Skill 里精心设计的流程形同虚设。

8. Autoresearch 优化 Skill

主要使用 :https://github.com/karpathy/autoresearch

  • 下载 skill。从这里获取,放进你在 Claude Code 或 Cowork 里的 skills 文件夹。
  • 选一个要改进的 skill。 说 “ 对我的 [skill 名称] skill 跑 autoresearch”。选最让你头疼的那个——时好时坏、输出不稳定的那个。
  • agent 问你 3 件事。 要优化哪个 skill、用什么测试输入(比如 “ 为一款 AI 生产力工具写落地页文案 “),以及你的 checklist 问题是什么。
  • 它跑一遍你的 skill,给出起始分数。这是基准线。我的落地页 skill 起步 56%——标题模糊、流行词泛滥、CTA 软弱。超过一半的检查项都没过。
  • 浏览器弹出实时 dashboard。分数曲线、每项 checklist 的通过/失败、每次改动日志。每 10 秒刷新一次。
  • 走开。agent 开始循环。找最薄弱的地方,改一点,测试,分数升就留,分数降就撤。然后再来一次。再来一次。一直跑,直到你叫停,或者连续三次超过 95%。

9. 参考资料