SKILL 23 / DATA · DEEP-DIVE

按域拆 Reference 的 Skill 结构

一个 SKILL.md 只放导航 · 用到哪份读哪份 · schema 与口径规则该落在哪一层

2026-09-24 · BigCat

上期的结论是:口径没人能卖给你,只能自己写。这期解决紧接着的那个问题——写完放哪。四个官方 skill 的真实目录摆在一起看,从「压根没拆」到「两轴矩阵」,中间那几道线画在哪。

前置 → Skill 22 数据分析类 Skills 榜单(口径那一格谁也卖不给你)

// WHY THIS MATTERS

口径和 schema 写出来之后有个非常实际的问题:放哪。塞进 SKILL.md,一份仓库表结构就能把它撑到上千行,而且每次触发都整份进 context;塞进 CLAUDE.md 更糟——那是无条件常驻的,每个会话都付这笔钱。官方给的答案是按域拆成多份文件,SKILL.md 只留一张路由表。本期不从原理讲起,先把 anthropics/skills 里四个真实目录摊开——pdf 平铺两份、mcp-builder 一个 reference/、skill-creator 一个 references/、claude-api 直接做成两轴矩阵——再回头说这几档之间怎么选。

// 01

它替你干掉什么:整份 schema 常驻 context 的税

论断:拆 reference 省的不是磁盘,是 token。官方把这件事说得很直白——文件躺在那儿一个 token 都不花,被读了才花。

官方写死的三条加载规则

Skill authoring best practices 的 Runtime environment 一节列了三条,是这套结构全部的经济学依据:① Metadata pre-loaded——启动时只有所有 skill 的 name 与 description 进系统提示;② Files read on-demand——相关了才读 SKILL.md,其余文件再按需读;③ No context penalty for large files,原话是 Reference files, data, or documentation don't consume context tokens until actually read.

装法:四个加载位置,挑一个

# 个人级:本机所有项目可见
~/.claude/skills/<skill-name>/SKILL.md
# 项目级:随仓库走,能进 git(团队共享口径就用这个)
.claude/skills/<skill-name>/SKILL.md
# 插件级:调用时带命名空间 /plugin-name:skill-name
<plugin>/skills/<skill-name>/SKILL.md
# 子目录级:在 <subdir> 或其下启动的会话才加载
<subdir>/.claude/skills/<skill-name>/SKILL.md

# 想先看现成的(19 个官方 skill 全在里面)
/plugin marketplace add anthropics/skills
/plugin install example-skills@anthropic-agent-skills

第一条立刻能跑的用法:照抄官方 Pattern 2

官方 best-practices 里的 Pattern 2: Domain-specific organization 给了一个 bigquery-skill 的骨架,原样可用:SKILL.md 加一个 reference/,里面 finance.md / sales.md / product.md / marketing.md 四份。SKILL.md 正文只放三种东西——一句话说这个 skill 管什么、一张按域路由的表、一条 grep 提示:

mkdir -p .claude/skills/warehouse/reference

# SKILL.md 里的路由表,官方原样:
**Finance**: Revenue, ARR, billing → See [reference/finance.md](reference/finance.md)
**Sales**: Opportunities, pipeline, accounts → See [reference/sales.md](reference/sales.md)

# 以及一条 quick search 提示,让它自己捞:
grep -i "revenue" reference/finance.md

口径规则写进对应那份域文件,不写进 SKILL.md——官方举的例子正是「always exclude test accounts」这类规则,它属于哪个域就落在哪份里。什么时候别拆:SKILL.md 还没到 500 行、只有一个域、或者域之间强耦合(问 A 必然要读 B)——拆了只是多一跳。官方那条界线写得很硬:Keep SKILL.md body under 500 lines... Split content into separate files when approaching this limit.

出处 · Anthropic · Skill authoring best practices(Progressive disclosure patterns / Runtime environment 两节)· Claude Code · Skills(四个加载路径表),两页均为 2026-09 访问
// 02

机制:SKILL.md 是目录页,文件系统是索引

论断:拆得好不好,全看那张路由表有没有写清「什么情况下读哪份」。文件拆了而路由没写,等于没拆——模型永远不会去读它,还不报错。

四个官方 skill 的真实目录,摊开看

pdf/ SKILL.md(约 270 行) + forms.md + reference.md + scripts/ ← 平铺,一层深 mcp-builder/ SKILL.md + scripts/ + reference/ mcp_best_practices.md evaluation.md node_mcp_server.md python_mcp_server.md ← 一个 reference 目录,4 份 skill-creator/ SKILL.md + references/schemas.md + agents/ assets/ eval-viewer/ scripts/ ← 目录按用途分,不止 md claude-api/ SKILL.md + shared/(28 份 .md) + python/ typescript/ java/ go/ ruby/ csharp/ php/ curl/ ← 两轴矩阵:主题 × 语言 docx/ xlsx/ pptx/ web-artifacts-builder/ SKILL.md + scripts/ 而已 ← 压根没拆 template/ 只有一个 SKILL.md ← 起手式
出处 · 据 anthropics/skills · skills/ 各目录页,2026-09(该目录下共 19 个 skill)

三种路由写法,都能在上面这几个里读到原文

  1. 按任务路由——claude-api 的 Reading Guide:先读 {lang}/claude-api/README.md,然后按任务加料——Chat UI 加 streaming.md,tool use 加 shared/tool-use-concepts.md + {lang}/claude-api/tool-use.md,缓存读 shared/prompt-caching.md,省钱读 shared/cost-optimization.md。
  2. 按条件路由——mcp-builder:同一步里分叉,选 TypeScript 读 ./reference/node_mcp_server.md,选 Python 读 ./reference/python_mcp_server.md;而 mcp_best_practices.md 与 evaluation.md 是无条件读的。条件路由的价值在于「不该读的那份连名字都不会被展开」。
  3. 按域路由——官方 Pattern 2 的 bigquery 例:finance / sales / product / marketing 四份,问哪个域读哪份。上一期说的口径问题,落点就在这一格。

两条硬约束,都是为了对付「预览式读取」

一个真实的坑:仓库里 skills/pdf 的文件名是小写 forms.md / reference.md,而它 SKILL.md 正文写的是「read FORMS.md」「see REFERENCE.md」。macOS 默认文件系统大小写不敏感,照跑;Linux 容器里就是两个不同的名字。自己拆 reference 时,路由行里的路径从 ls 的输出里复制,别手打。
// 03

真实用法与边界:schema 和口径到底写在哪一层

论断:这三样东西该落在三个不同的层——SKILL.md 放导航与跨域硬规矩,reference/<域>.md 放 schema 与口径,scripts/ 放能机器校验的部分。放错层,要么每次白交 token,要么该读的永远没读。

三层落位

三条判据,用来在上面四档之间取舍

  1. 域之间会不会被同时问到?会 → 别拆,拆了每次都要读两份还多一跳。不会 → 按域拆。这正是 claude-api 把 shared/ 和语言目录分开的理由:问 Python 的人不需要 Ruby 那 8 份。
  2. 有没有第二根轴?只有「主题」一根 → reference/ 平铺就够,mcp-builder 四份到顶。主题 × 语言、或主题 × 环境两根都在 → 才值得做成 claude-api 那样的矩阵。两轴的代价是路由表必须写成 {lang}/xxx.md 这种带占位符的模板,人读着累、改起来更累。
  3. 这份文件会过期吗?会 → 在文件里标日期。claude-api 的 SKILL.md 把模型与定价表标成 as of 2026-06-24,是本期最该抄走的一个小动作:volatile 的内容自己声明保质期,别让读者替你猜。

什么时候这套不成立

// 04

代价与替代品:拆出来的每一份,都新增一条要维护的路由行

论断:文件改名、域合并、新增一类——只要路由表不同步,模型读到的就是一份指向空气的目录页,而且全程没有报错。

三笔账

不拆的话,你还能怎么办

  1. 就不拆。单文件跑到 500 行再说。官方 template/ 至今只有一个 SKILL.md,起手式本来就是这样。
  2. 把口径放进 CLAUDE.md。代价是无条件常驻,每个会话都付这笔 token;只适合真的每次都用得上的两三条。
  3. 让 schema 走 MCP,别走文件。表结构由 server 现查现给,永远不会过期;代价是每问一次都要一轮工具调用,且多一个 context 税源(见本站 Skill 9 与 Skill 22)。
  4. 给每个域开一个 subagent。上下文隔离更彻底,协调税更高——这条留到 Skill 26 展开。
最后一条诚实的代价:这套结构优化的是 token,不是正确性。reference/finance.md 里写错的口径,按需加载只会让它更晚被发现——因为你连它有没有被读过都不知道。拆 reference 之前,先保证那几份文件里的内容是对的。

// 一页选购卡

先读这三份:① 官方 best-practices 的 Progressive disclosure patterns 一节——Pattern 1/2/3、一层深、100 行目录,本期几乎所有规则的出处。② skills/claude-api 的 SKILL.md——看那张 Reading Guide 怎么把 28 份 shared/ 和 8 种语言目录压成一张表。③ skills/mcp-builder 的 SKILL.md + reference/——四份文件,是「最小可用的按域拆」的标准答案。

按需再看:skills/pdf(平铺两份 md 长什么样)· skills/skill-creator(references/schemas.md 与 agents/ assets/ scripts/ 的分工)· skills/docx 与 skills/xlsx(不拆也能很重的反例)· template/SKILL.md(起手式)· code.claude.com/docs/en/skills(四个加载路径)。

明确别做:因为「官方都这么做」就拆(官方 19 个 skill 里多数没拆)· 把整份 schema 写进 SKILL.md · 引用套引用超过一层 · 路由行里的路径手打不核大小写 · 拆完不在 volatile 的文件里标日期。

// 术语表

progressive disclosure(渐进披露)
只有 name/description 常驻,SKILL.md 触发时读,其余文件按需读的三级加载模型。它让「带一大堆资料」不再等于「烧一大堆 token」。
SKILL.md
skill 的入口文件,YAML frontmatter 必须有 name(≤64 字符,小写字母数字连字符)与 description(≤1024 字符)。正文官方建议 500 行以内。
routing table(路由表)
SKILL.md 里那几行「什么情况 → 读哪份文件」。本期的中心论点:路由表没写清,拆出来的文件等于不存在。
one level deep(一层深)
所有 reference 都要从 SKILL.md 直接链到,不许 A 链 B、B 链 C。官方 anti-pattern 之一。
shared/ 与 {lang}/
claude-api 的两轴拆法:与语言无关的概念放 shared/,与语言绑定的放各语言目录,路由表里用 {lang} 占位符统一指。
口径(metric definition)
「活跃用户」到底怎么算这一类规则。它是域知识,该落在 reference/<域>.md,不该落在 SKILL.md。
bundled resources(随附资源)
skill 目录里除 SKILL.md 之外的一切:.md、脚本、模板、资产。官方判断它多不多余的标准只有一条——有没有被真的访问过。

// 延伸阅读