技能分层:让我们 80+ 个技能远离上下文的四桶模型
渐进式披露意味着 80 个技能可以是 3,200 token 的元数据,也可以是零。这是我们如何把 Statnive 仓库里的每一个技能分类为始终开启、自动可调、仅手动或 fork — 以及我们用来做决定的那一道问句测试。
为什么更多技能不必意味着更少上下文
Statnive 的 Claude Code 配置加载了 80 多个技能,覆盖产品管理、后端脚手架、QA、安全审计、WordPress 特定模式、发布打包等等。我们所基于的框架(jaan.to)交付了 141 个。一种天真的理解是:技能更多,上下文开销更多,留给真正工作的空间更少。
实际的算术更有趣。80 个技能可以耗 3,200 token 的永久元数据,也可以是零 — 取决于每一个的配置方式。差别在于 Claude Code 技能系统定义的四桶分层模型,以及挑选合适桶的那一道问句测试。
本文走一遍全部四个桶,给出 Statnive 真实的技能分布、我们用来决策的测试,以及我们在做对之前做错的三件事。
渐进式披露:底层机制
在分层模型说得通之前,加载机制必须先说得通。Claude Code 对技能使用三层渐进式披露:
| 层 | 加载内容 | 何时 | 成本 |
|---|---|---|---|
| 1 — 元数据 | YAML 前置元数据 name + description | 启动时始终加载 | 每个技能约 30–50 token |
| 2 — 正文 | 完整的 SKILL.md 内容 | 当技能被调用时 | Anthropic 建议 ≤ 500 行 / 约 5K token |
| 3 — 打包资源 | 引用的脚本、模板、参考文件 | 仅在被访问时 | 零基线成本 |
这就是分层模型用的杠杆。元数据层是唯一始终在上下文里的部分。其他都是按需。
对一个 141 个技能的框架来说,仅元数据就有4,200–14,100 token 的永久开销,与技能数量呈线性关系。如果描述冗长,会更大。如果您让某些技能完全跳过元数据注册表,会更小 — 甚至为零。
一个有据可查的 bug(Claude Code GitHub issue #14882)报告称某些插件技能在启动时可能会消耗其完整正文,而不仅是前置元数据。我们在自己的 /context 输出中留意这种情况。如果您的技能元数据行显示出远高于「约 50 token × 您的自动可调技能数」的数字,您正在踩到它。
四个桶
Statnive 仓库中的每一个技能都属于这四个桶之一。决定每一个桶的关键前置元数据字段:
桶 1 — 始终开启(默认前置元数据)
---
name: simplify
description: Review changed code for reuse, quality, efficiency. Auto-fixes issues.
---
这些是模型应自动路由到的核心工作流技能。标准前置元数据 — 没有特殊标记。元数据在启动时加载;正文在调用时加载。
Statnive 示例: simplify、statnive-release、statnive-release-zip。它们在大多数与发布相关的工作上触发。
每个技能成本: 上下文中永久约 40 token 元数据。
桶 2 — 自动可调(默认前置元数据,简洁描述)
从 Claude Code 的角度看,配置与「始终开启」相同。区别是编辑层面的:这些是仅在触发关键词匹配时才触发的领域技能。纪律在于让描述以触发为导向并简短。
---
name: wp-rest-api
description: Use when building REST endpoints in WordPress plugins.
---
不好的描述(仍能工作,成本更高):
description: A comprehensive skill for working with the WordPress REST API,
including endpoint registration, controller patterns, schema validation,
authentication, response shaping, and CPT/taxonomy exposure...
好的描述(上面那条):13 token。坏的描述:38 token。在 60+ 个自动可调技能上,差距大约是 1,500 token 的永久元数据节省。
Statnive 示例: wp-rest-api、wp-plugin-development、wp-performance、react-best-practices、wp-block-development,以及所有 jaan-to:* 规划技能。
每个技能成本: 上下文中永久约 30–50 token 元数据。
桶 3 — 仅手动(disable-model-invocation: true)
---
name: statnive-emergency-rollback
description: Emergency-only rollback procedure for a botched deploy.
disable-model-invocation: true
---
技能存在,斜杠命令也能用(/statnive-emergency-rollback),但元数据从不进入 <available_skills> 注册表。除非用户显式调用,否则 Claude 不知道它存在。
每个技能成本:0 token。 这是魔法桶。
何时使用它:罕见工作流、破坏性操作、任何您不希望模型自动路由到的内容。如果把某个技能标为仅手动会阻止工作流完成,那么它应该属于桶 1 或桶 2。
Statnive 示例: 紧急回滚、手动数据库手术、一次性迁移脚本,以及任何「以防万一」存在但不应机会主义触发的内容。
我们把大约一半的技能标为 disable-model-invocation: true。在 80+ 个技能上,这是约 1,800 token 的基线元数据被收回 — 而剩下的自动可调技能上路由质量反而提升,因为 Claude 不再需要在近似重复之间做选择。
桶 4 — Fork / Subagent(context: fork)
---
name: simplify
description: Review changed code for reuse, quality, efficiency. Auto-fixes issues.
context: fork
---
Fork 模式在隔离的 subagent 上下文中运行技能,它有自己的对话历史和自己的 200K token 窗口。工作输出留在主上下文窗口之外。仅有摘要返回。
对于代码评审、安全审计和多步研究等自包含工作流,这是变革性的。Anthropic 记录的 subagent 表现是从 10,000+ token 的内部工作中返回约 500–1,000 token — 在 subagent 进行了大量阅读和处理的复杂任务上对主上下文减少约 37%。
Statnive 示例: simplify(三个并行评审 agent,返回摘要)、jaan-to:backend-pr-review、jaan-to:sec-audit-remediate、jaan-to:detect-dev。任何读取很多文件并返回结论的内容。
每个技能成本: 约 40 token 元数据,但工作本身在隔离环境中发生。
那道问句测试
四个桶听起来像四个决定。其实它们只是一个:主对话需要看到该技能的中间工作吗?
| 答案 | 桶 |
|---|---|
| 是 — 该技能写的代码主会话还会继续编辑 | 始终开启 或 自动可调 |
| 否 — 该技能返回结论、摘要或报告 | Fork / subagent |
| 也许 — 但它绝不应自动触发(罕见、破坏性、奇怪) | 仅手动 |
如果是「否」,设 context: fork。您的主上下文保持清洁,并且您可以让 subagent 重读取的工作使用 Haiku 4.5($1/$5 每 MTok),同时主会话使用 Sonnet 或 Opus。这是上下文胜利之外再叠加一个 3× 的成本胜利。
如果是「是」,它进入桶 1 或 2。在「始终开启」和「自动可调」之间的选择是编辑层面的:Claude 能多有信心地从自然语言线索中触发它?强烈、毫不含糊的触发进入「自动可调」。模型应在大多数会话中考虑的工作流进入「始终开启」。
如果该技能存在但不应自动触发,把它标为「仅手动」并收回它的元数据成本。
Statnive 的真实技能分布
下面是我们当前在约 85 个技能上的拆分:
| 桶 | 数量 | 总元数据成本 | 备注 |
|---|---|---|---|
| 始终开启 | 8 | 约 320 token | 发布、simplify、Sprint 规划、PR 评审 |
| 自动可调 | 38 | 约 1,520 token | 触发关键词强的领域技能 |
| 仅手动 | 32 | 0 token | 仅斜杠命令 |
| Fork / subagent | 7 | 约 280 token | 评审、审计、检测 |
| 总元数据成本 | 85 | 约 2,120 token | 约占上下文 1% |
如果不分层 — 如果全部 85 个都用默认设置 — 我们会付大约 3,400 token 的永久元数据。仅 32 个仅手动技能就省下约 1,280 token。单独看显得很小;与 CLAUDE.md 精简和 MCP Tool Search叠加时就重要了。
正文上限:为什么 500 行是合适的数字
元数据这边是永久开销。正文那边是按调用开销 — 同样重要要去控制。
Anthropic 建议把每个 SKILL.md 保持在 500 行(约 5K token)以下。关于激进优化的研究把这条推到了每个技能正文 600 行的硬上限,超过的需要参考提取:把模板、长清单、多技术栈对比、反模式目录从 SKILL.md 中拉出来,放到通过清晰指针引用的独立文件里。
模式看起来像:
.claude/skills/wp-plugin-development/
├── SKILL.md # 380 lines — execution core only
└── references/
├── activation-deactivation-patterns.md # Loaded only when needed
├── settings-api-patterns.md
├── nonce-and-capability-checklist.md
└── release-packaging-checklist.md
执行核心保持紧凑且确定。参考文件按需加载,在被访问之前不耗 token。我们这样重建了我们最重的三个技能,把典型调用的预算砍掉了约 12,000 token。
值得使用的另一个正文控制字段:
allowed-tools: ["Read", "Grep", "Glob"]
这限制该技能能访问哪些工具,既减少 token 开销,也减少执行面。一个只读代码的技能不应有 Write、Bash 或 MCP 工具访问权限 — 收窄工具集会收窄技能触发时注入的 schema,并消除一整类意外行为。
我们前三次做错的事情
诚实的注意事项,与本系列其他文章一致:
- 我们一开始用了冗长的描述。 我们第一波技能的描述有 60+ token,是为人类读者优化的。它们能用,但成本是它们应有的 2 倍。第一轮修剪从自动可调桶里砍掉了约 1,400 token 的元数据。
- 我们有三个做相似事情的技能。 自动可调桶里有
pm-roadmap-add、pm-roadmap-update和pm-sprint-plan,触发重叠。路由变得像抛硬币。我们做了合并并澄清了触发。路由准确度上升;元数据成本下降。 - 我们有重技能没有用 fork 模式。
simplify最初是内联运行的。它会读 30+ 个文件,跑三轮评审,返回 2,000 token 的报告 — 全部内部工作都污染了主上下文。切换到context: fork后,每次发布会话的典型主上下文使用减少了约 9,000 token。
测量步骤
与本系列其他文章一致:/context 是诊断。给技能分层时您要看的那一行是显示技能元数据 token 数的那一行。我们使用的目标值:
| 来源 | 目标 | 硬上限 |
|---|---|---|
| 技能元数据 | ≤ 2,500 token | 5,000 |
| 自动可调技能数 | ≤ 60 | — |
| 任何单个 SKILL.md 正文 | ≤ 500 行 / 约 5K token | 600 行 / 约 8K token |
如果您的技能元数据行远超 5K token 而您的技能少于 100 个,您可能要么有冗长描述(桶 2 问题),要么命中了我们之前提到的加载 bug(桶 1 问题)。
这与 Statnive 其他部分的联系
我们每次提交都跑 141 项 PHP 单元测试。任何版本交付前都要通过31 项合规检查。编排所有这些的技能 — statnive-release、simplify、wp-plugin-development、QA 生成器 — 加起来大约 2,100 token 的永久元数据。工作发生了,上下文保持清洁,团队保持小规模。
四桶模型不是学术练习。它就是我们能在没有五人团队的前提下,交付一个在 5KB tracker 预算下的 WordPress 分析插件的原因。
试试 Statnive
由一支跑 /context 比跑 /help 还多的团队打造的隐私优先 WordPress 分析。从 WordPress.org 免费安装 Statnive — 您的数据留在您的服务器上,我们的技能库则远低于其 token 预算。