1. 为什么 2000 字的 SKILL.md 会被 Claude 静默忽略
如果你正在用 Claude 的 Skill 机制做代码审查、文档生成或者数据分析,大概率踩过这个坑:把团队所有规范、检查清单、优化套路全塞进一个 SKILL.md,洋洋洒洒两千字,结果 Claude 跑起来该报的 SQL 注入没报,该揪的 N+1 查询漏了。你以为它读懂了,其实它只读了开头三段,后面一千五百字在上下文里被静默丢弃。
这不是模型笨,是上下文膨胀逼出来的选择性失明。Token 池子就那么大,正文越长,注意力越分散,真正关键的触发条件反而被淹没在流程描述里。Claude 在决定要不要进入一个 Skill 时,看的根本不是你的正文,而是顶部那段 YAML frontmatter。正文是命中之后才加载的二等公民,frontmatter 才是路由依据。
所以正确做法是把 SKILL.md 当路由器,不是说明书。这篇就围绕 Claude Skill 的 SKILL.md 结构设计展开:为什么长说明书会被忽略,怎么用 YAML frontmatter 做路由与渐进式披露,最后给出可复制的骨架和在 Claude 里验证触发与按需加载的完整步骤。适合已经在写 Skill、但发现触发不稳定或执行不完整的开发者。
2. 前置准备:TaoToken 接入与 Skill 调试环境
要验证 Skill 的触发行为,你需要一个能稳定调用 Claude 的入口。我这边用的是 TaoToken 的 API 通道,它兼容 Anthropic 的接口格式,配置成本低,适合做 Skill 的反复调试。
先去控制台拿一个 API Key,地址是 https://taotoken.net/api-keys ,登录后在密钥管理页新建一个,复制出来保存好。注意 Key 只在创建时完整显示一次,丢了就得重建。
拿到 Key 之后,接入文档在 https://taotoken.net/doc ,里面有 Anthropic SDK 和原生 HTTP 两种调用方式。如果你用的是 Claude Code 这类命令行工具,参考 https://taotoken.net/claude-code-anthropic 的配置说明,把 base_url 指向 https://taotoken.net/api 即可。
环境变量建议这样设,避免把 Key 硬编码进脚本:
export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="sk-你的Key"设完之后可以用一个最小请求验证通道是否通:
curl https://taotoken.net/api/v1/messages \ -H "x-api-key: $ANTHROPIC_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "max_tokens": 64, "messages": [{"role": "user", "content": "reply with ok"}] }'返回里能看到content字段带ok就说明通道正常。这一步别跳过,后面 Skill 触发异常时,先排除是不是通道本身的问题。
3. SKILL.md 骨架:YAML frontmatter 字段逐个配
Skill 的目录结构一般是这样的,SKILL.md 放在 Skill 根目录,reference 子目录放按需加载的细节文件:
skills/ code-reviewing/ SKILL.md reference/ security.md performance.md quality.mdSKILL.md 顶部那段 YAML frontmatter 是 Claude 真正读的部分。一个完整的骨架长这样:
--- name: code-reviewing description: Performs structured code reviews following team standards. Checks security vulnerabilities, performance issues, and code quality in priority order. Use when user asks to "review code", "do a code review", "check this PR", "audit this function", or provides code and asks for feedback. argument-hint: "[file or directory]" disable-model-invocation: false allowed-tools: - Read - Grep - Glob model: sonnet context: fork ---逐个字段说清楚:
name是唯一标识符,最多 64 字符,省略时用目录名。建议和目录名保持一致,避免路由时对不上。
description是路由匹配的真正依据,上限 1024 字符。Claude 在决定要不要进入这个 Skill 时,只看这一段。很多人把心思花在正文,description 随便糊一句「帮助用户处理代码相关任务」,等于把灵魂写废了。
argument-hint是参数提示,在/菜单里显示,告诉用户这个 Skill 接受什么参数。
disable-model-invocation决定触发方式。设为true时禁止自动调用,只能通过/skill-name手动触发,适合有副作用的操作比如提交代码。设为false时允许语义匹配自动触发。
allowed-tools是工具白名单,精确控制能力边界。代码审查类给Read、Grep、Glob就够,给Write就是给自己挖坑。
model指定用哪个模型。简单任务用 haiku 更快更省,复杂分析用 sonnet。
context: fork表示在隔离子智能体中执行,不污染主对话上下文。
4. description 写法:三句话公式决定触发率
description 写得好不好,直接决定 Skill 会不会被触发。对比一下三种写法:
# 错误:Claude 根本不知道何时触发 description: Helps with projects. # 错误:只写了做什么,没写触发场景 description: Generates API documentation. # 正确:触发词 + 使用场景 + 能力边界 description: Generate API documentation from Express, FastAPI, or Spring Boot source code. Use when user asks to "write API docs", "document endpoints", "create OpenAPI specs", or mentions "Swagger". Supports route detection, request/response schema extraction, and authentication requirement marking.三句话公式:前两句说能力,Claude 靠这两句判断意图;中间用Use when...枚举用户可能说的关键词,这是路由匹配的核心;最后限定能力边界,避免误触发。
关键词要覆盖用户的实际说法,不是你以为的说法。用户说「帮我看看这段代码有没有安全问题」,你的 description 里得有security、vulnerability、audit这类词。用户说「这个接口文档补一下」,得有API docs、document endpoints。
1024 字符是上限,别超。超了会被截断,后面的触发词就丢了。
5. 路由器思维:Quick Reference 表才是正文主角
正文不是给你写说明书用的,是给 Claude 当路由表用的。复合型 Skill 最该这么写:
## Quick Reference | Analysis Type | When to Use | Reference | |---------------|-------------|-----------| | Security Check | SQL 注入、XSS、硬编码密钥、越权 | `reference/security.md` | | Performance | N+1 查询、未加索引、循环内重复计算 | `reference/performance.md` | | Code Quality | 函数过长、命名不清、空 catch、违反 DRY | `reference/quality.md` |Claude 看到这张表就知道:用户问安全问题加载security.md,问性能加载performance.md。正文本身只放路由表和总流程,具体检查项全部分散到 reference 下,按需加载。
我试过给一个 ArkTS 项目的代码审查 Skill 把所有规范铺了一千八百字在正文里,结果 Claude review 时连@State没初始化这种低级问题都没揪出来。后来改成路由器加契约式引用,正文压到两百字,反而灵了。
正文控制在两百到四百字之间,只保留三样东西:Quick Reference 路由表、总执行流程、输出格式要求。其他全部下沉到 reference。
6. 契约式引用:加载条件 + 路径 + 内容预期
弱引用是另一个坑。你写一句See reference/security.md for more details,Claude 压根不知道何时该去读。
# 错误:弱引用,Claude 不知道何时加载 See `reference/security.md` for more details. # 正确:契约式引用,三要素齐全 ## Security Check When the user asks about SQL injection, XSS, hardcoded secrets, or access control: → Load `reference/security.md` for detection patterns and fix examples.契约三要素:加载条件(用户问 SQL 注入、XSS、硬编码密钥时)、路径(reference/security.md)、内容预期(检测模式和修复示例)。三要素齐全,模型才知道「哦,现在该去读这个文件了」。
reference 文件本身也要有结构,别又是一篇长文。每个文件控制在五百字以内,用二级标题分节,方便 Claude 定位。
7. 渐进式披露:三层加载链路串起来
把前面几步串起来,就是渐进式披露的完整链路:
第一层,路由阶段。Claude 只看 frontmatter 的 description,判断要不要进入这个 Skill。这一层不加载正文,成本最低。
第二层,命中后加载 SKILL.md 正文。但正文里只有 Quick Reference 路由表和总流程,没有具体细节。
第三层,深度执行。根据契约式引用,按需加载reference/*.md里的具体检查项和公式。
每一层只加载当下需要的,上下文窗口始终干净。你写的两千字详细流程,拆成五个 reference 文件分散加载,比一次性塞进去强十倍。
验证渐进式披露是否生效,可以在 Skill 里加一行调试输出,看 Claude 实际加载了哪些文件。或者在 reference 文件里放一个独特的标记字符串,执行后检查输出里有没有出现。
8. 权限设计:最小权限,禁止 Bash(*)
allowed-tools不是越宽越好,是越精确越好。四套现成模板:
# 审计类:严格只读 allowed-tools: [Read, Grep, Glob] # 生成类:可写不可改 allowed-tools: [Read, Grep, Glob, Write] # 分析类:只读 + 特定脚本 allowed-tools: [Read, Grep, Glob, Bash(python:*)] # 执行类:受控命令 allowed-tools: - Read - Bash(git status:*) - Bash(git add:*) - Bash(git commit:*) - Bash(npm test:*)Bash 的精细控制语法记一下:Bash(git:*)允许所有 git 子命令,Bash(git log:*)只允许 log,Bash(./scripts/*:*)只允许 scripts 目录。Bash(*)等于授权所有 shell,禁用。
代码审查 Skill 给Read、Grep、Glob就够。给Write意味着 Claude 可以改你的代码,风险自己掂量。
9. 动态上下文注入:$ARGUMENTS 和 !command
任务型 Skill 经常要接参数、要感知当前环境。两个语法搞定。
$ARGUMENTS是全部参数,$0、$1、$2是位置参数:
--- name: migrate-component description: Migrate a component between frameworks argument-hint: "[component] [from] [to]" disable-model-invocation: true --- Migrate the $0 component from $1 to $2. Preserve all existing behavior and tests.用户敲/migrate-component Button Vue React,正文里的$0就替换成Button。
!command是动态上下文注入,命令输出在加载时就被嵌进正文:
## Current State (Auto-detected) Git status: !`git status --short 2>/dev/null || echo "Not a git repository"` Staged changes: !`git diff --staged --stat 2>/dev/null || echo "Nothing staged"`Claude 一进 Skill 就能看见当前 git 状态,不用再跑一遍命令。提交类 Skill 用这招最省事。
10. 验证触发与按需加载:完整操作步骤
配置写完了,怎么验证真的生效?按下面步骤走。
第一步,确认 Skill 被正确加载。在 Claude Code 里输入/看菜单里有没有你的 Skill 名。没有的话检查目录结构,SKILL.md 必须在 Skill 根目录。
第二步,验证语义触发。用 description 里没写过的说法问一句,比如「帮我看看这段代码有没有安全问题」,看 Claude 会不会自动进入 Skill。如果没触发,说明 description 里的关键词覆盖不够。
第三步,验证显式触发。输入/code-reviewing看是否正常执行。如果报错,检查 frontmatter 格式,YAML 对缩进敏感,冒号后面要有空格。
第四步,验证按需加载。在 reference 文件里放一个独特标记,比如SECURITY_CHECK_V2,执行后看输出里有没有出现。没出现说明契约式引用的加载条件没写清楚。
第五步,验证权限边界。故意让 Skill 执行一个不在allowed-tools里的操作,看是否被拒绝。被拒绝说明权限配置生效。
11. 常见报错与排查
Skill 不触发:九成是 description 问题。检查有没有Use when...枚举触发词,关键词是不是用户的实际说法。另外确认disable-model-invocation没被误设为true。
触发后执行不完整:正文太长导致注意力分散。把正文压到四百字以内,细节下沉到 reference。
reference 文件不加载:契约式引用三要素缺了。检查有没有写清楚加载条件、路径、内容预期。
YAML 解析报错:缩进用了 Tab 而不是空格,或者冒号后面没空格。YAML 对格式严格,建议用编辑器插件校验。
权限被拒绝:allowed-tools里没加对应的工具。检查 Bash 的精细控制语法,Bash(git:*)和Bash(git log:*)范围不同。
模型选错:简单任务用了 sonnet 导致慢且贵,复杂分析用了 haiku 导致质量差。按任务复杂度选model字段。
12. 下一步:把长说明书拆成路由器
如果你手头有个写了两千字正文的 Skill,别继续赌 Claude 心情好读完。花半小时拆成路由器加 reference,触发率和执行质量都会有明显提升。
需要长期跑编码任务或 Agent 的,可以看看 Coding Plan 的配置方式:https://taotoken.net/coding-plan 。想先验证模型对话效果的,直接去 https://taotoken.net/chat 试几句。接入过程中遇到报错的,对照接入文档排查:https://taotoken.net/doc 。Key 管理和新建在控制台:https://taotoken.net/api-keys 。
拆分的优先级:先把正文里的检查清单按类别拆成独立 reference 文件,再写 Quick Reference 路由表,最后精简 description 的触发词。三步做完,你的 Skill 就从说明书变成了路由器。