代码语言
知识点思维导图
29 个知识节点
参考资料
Skill(06) - 渐进式披露与 Token 优化
读完后,你应能完成以下任务:
- 绘制“Skill(06) - 渐进式披露与 Token 优化 / 一个比喻先建立直觉”的关键对象与数据流,解释“他脑子里常备一份「能力清单」:知道自己会哪些活(但不记每件活的全部细节)。 -> 当你提一个需求,他翻开对应那本手册的目录和正文。 -> 手册里说「具体参数见附录 C」,他才去翻附录 C。”,并用源码位置、日志或 Trace 标注证据。
- 为“Skill(06) - 渐进式披露与 Token 优化 / 三层加载机制”设计正常与异常输入,验证“越靠前的层,被加载得越频繁、越要省;”,输出首个偏差位置与回归测试结果。
- 实现“Skill(06) - 渐进式披露与 Token 优化 / 这套机制解决了什么矛盾”的最小代码或配置,检验“渐进式披露就是解药:把又多又细、但不常用的内容沉到第 3 层,平时不加载、不花钱;”,输出命令、结果与 Diff,并说明不适用边界。
本章目标:搞懂「三层加载」机制,理解为什么前面反复强调「入口精简、细节外置」。学完你会拿到一张「什么内容放哪一层」的决策表。这是全书的「内功心法」。
一、一个比喻先建立直觉
想象你请了一位专家顾问。你不会一上来就把他书架上所有的书都塞进他脑子里——那既慢又贵。合理的方式是:
- 他脑子里常备一份「能力清单」:知道自己会哪些活(但不记每件活的全部细节)。
- 当你提一个需求,他翻开对应那本手册的目录和正文。
- 手册里说「具体参数见附录 C」,他才去翻附录 C。
Claude 用技能的方式,几乎一模一样。这套「需要时才加载更多细节」的机制,就叫渐进式披露(Progressive Disclosure)。
二、三层加载机制
技能的内容被分成三层,加载时机各不相同:
第 1 层:frontmatter(name + description)
└─ 何时加载:始终常驻。所有技能的这一层都在 Claude 的「待选清单」里。
└─ 成本:最敏感。每个技能都占一点,所以必须极短。
第 2 层:SKILL.md 正文
└─ 何时加载:技能被触发后,整段读入。
└─ 成本:中等。只有用到这个技能时才花,但一旦触发就全量加载。
第 3 层:外部文件(reference/ templates/ scripts/ 等)
└─ 何时加载:正文里「点名引用」且确实需要时,才按需打开。
└─ 成本:最省。不用就完全不花。
一句话总结这张图:
越靠前的层,被加载得越频繁、越要省;越靠后的层,越能放大块细节。
三、这套机制解决了什么矛盾
技能设计上有个天然矛盾:
- 你希望技能能力强(懂很多细节、能处理复杂情况)。
- 你又希望它省上下文(别每次都吞掉海量 token)。
渐进式披露就是解药:把又多又细、但不常用的内容沉到第 3 层,平时不加载、不花钱;只有真用到那个细节时,才花那一次的成本。这样技能既能很「厚」,日常开销又很「薄」。
这就是为什么前面几章反复念叨:
- 第 04 章:frontmatter 要短(因为它在第 1 层,常驻)。
- 第 03 章:又长又少用的内容拆到
reference/(把它沉到第 3 层)。
四、「什么内容放哪一层」决策表
这是本章最实用的产出,照着摆就不会错:
| 内容类型 | 放哪一层 | 为什么 |
|---|---|---|
| 技能名、触发场景 | 第 1 层 frontmatter | 要被频繁扫描,必须极短 |
| 核心流程、关键步骤、输出格式 | 第 2 层 正文 | 每次干活都要用,但只在触发后加载 |
| 一两个关键示例 | 第 2 层 正文 | 示例对产出质量帮助大,值得常驻正文 |
| 详尽的 API/参数文档 | 第 3 层 reference/ | 又长又偶尔查,沉下去 |
| 大段模板、样板文件 | 第 3 层 templates/ | 用时复制,不必占正文 |
| 完整的规范、风格手册 | 第 3 层 reference/ | 篇幅大、查阅频率低 |
| 确定性的处理逻辑 | 第 3 层 scripts/ | 交给代码执行(第 08 章详解) |
一个判断口诀:
「每次都用」→ 留正文;「偶尔才查」→ 沉到外部文件。
五、实例对比:一个臃肿技能的瘦身
改造前(全塞正文,每次触发烧 3000+ token):
---
name: api-helper
description: ...
---
# API 助手
## 完整 API 列表(200 个接口,每个含参数、返回值、示例)
GET /users ...(此处省略 2000 行)
## 错误码大全(150 个)
...
改造后(正文瘦身,细节外置):
---
name: api-helper
description: ...
---
# API 助手
按用户需求,帮其调用正确的接口并组装参数。
## 流程
1. 判断用户要做什么操作。
2. 在 reference/api-list.md 中查到对应接口和参数。
3. 错误码含义见 reference/error-codes.md。
api-helper/
├── SKILL.md # 瘦身后,约 20 行
└── reference/
├── api-list.md # 2000 行,用到才加载
└── error-codes.md # 150 个错误码,用到才查
效果:日常触发只加载那 20 行正文;只有真要查某个接口时,才加载 api-list.md。能力没减,开销骤降。
六、常见错误
- ❌ 把所有东西都堆进正文:技能是变强了,但每次触发都付高昂的上下文税。
- ❌ 该外置的细节没外置:2000 行文档塞在正文,典型反模式。
- ❌ 外置了却忘了在正文「指路」:第 3 层文件没被点名,永远不会被加载(见第 03 章)。
- ❌ 过度拆分:明明 10 行的小技能,非要拆成五个文件,徒增复杂度。简单技能就该单文件。
七、最佳实践
- 默认从单文件起步,正文写「核心流程 + 关键示例」。
- 正文里只要发现「这段又长又不常用」,就往第 3 层挪,并在原处留一句「详见 xxx」。
- frontmatter 永远只放必填的 name + description,把第 1 层压到最薄。
- 拆分服务于「省」和「清晰」,不是为拆而拆——拆了反而更乱就别拆。
八、动手实践:06 章 Demo · 同一技能的「臃肿版 vs 瘦身版」
渐进式披露最好的体会方式,是看同一个技能的两个版本:一个把什么都塞进正文,一个把细节沉到第 3 层。
8.1 文件
07-渐进式披露-demo/
├── README.md
├── before-臃肿版/
│ └── SKILL.md # 所有内容都堆在正文,又长又烧 token
└── after-瘦身版/
├── SKILL.md # 正文只留核心流程,约 20 行
└── reference/
├── api-list.md # 长文档,沉到第 3 层
└── error-codes.md # 错误码表,沉到第 3 层
8.2 怎么对比
- 打开
before-臃肿版/SKILL.md,感受一下正文有多长——每次技能被触发,这一整坨都要加载。 - 打开
after-瘦身版/SKILL.md,看它多干净——正文只讲流程,长内容用「详见 reference/xxx」指路。 - 看
after的reference/里两个文件:它们平时完全不加载,只有 Claude 真要查某个接口/错误码时才打开。
8.3 关键观察
- 两个版本能力一样(都能查接口、查错误码)。
- 但
after版的日常开销小得多——这就是渐进式披露的价值:能力不减,开销骤降。 - 注意
after版正文里那句「见 reference/api-list.md」——正是这句「指路」让第 3 层文件能被按需加载。删掉它,参考文件就失联了。
8.4 你会收获什么
- 把「三层加载」从抽象概念变成看得见的文件差异。
- 拿到一个可直接套用的「瘦身」改造范式。
8.5 配套实践材料
以下材料已并入正文,便于阅读时直接对照和练习。
after-瘦身版/reference/api-list.md
# 接口列表(第 3 层参考文件,按需加载)
> 这份文档又长又只在「真要调接口」时才查,所以放在 reference/,平时不加载。
## 用户相关
### GET /users
- 说明:返回用户列表
- 参数:page(页码,默认1)、size(每页条数,默认20)、sort(排序字段)
- 返回:id、name、email、created_at、status
### GET /users/{id}
- 说明:返回单个用户详情
- 路径参数:id
- 返回:id、name、email、phone、address、created_at、roles
### POST /users
- 说明:创建用户
- 请求体:name(必填)、email(必填)、phone、address
### PUT /users/{id}
- 说明:更新用户
- 请求体:name、email、phone、address(均可选)
### DELETE /users/{id}
- 说明:删除用户
- 路径参数:id
(真实项目里这份文件可能有几百个接口,全放这层,正文完全不受影响。)
after-瘦身版/reference/error-codes.md
# 错误码对照表(第 3 层参考文件,按需加载)
> 出错时才查的内容,典型的「偶尔用」,放第 3 层最合适。
| 错误码 | 含义 | 排查建议 |
|--------|------|----------|
| 1001 | 参数缺失 | 检查必填参数是否都传了 |
| 1002 | 参数格式错误 | 核对参数类型,如日期格式、数字范围 |
| 1003 | 用户不存在 | 确认 id 是否正确、用户是否已被删除 |
| 1004 | 权限不足 | 检查当前 token 对应的角色权限 |
| 1005 | token 过期 | 重新登录获取新 token |
| 1006 | 请求频率超限 | 降低调用频率,稍后重试 |
(真实项目里可能有上百个错误码,全放这里,不影响正文体积。)
after-瘦身版/SKILL.md
---
name: api-helper
description: 当用户需要调用项目 API、查询接口参数或排查错误码时使用。
---
# API 助手(瘦身版 —— 推荐)
根据用户需求,帮其调用正确的接口、组装参数,并在出错时给出排查建议。
## 流程
1. 判断用户要做的操作(增删改查哪类)。
2. 在 `reference/api-list.md` 中查到对应接口的路径、参数和返回字段。
3. 组装请求,处理返回。
4. 若遇到错误码,在 `reference/error-codes.md` 中查含义并给出建议。
## 注意
- 必填参数缺失时,主动向用户追问,不要瞎填。
- 不要凭记忆编造接口,一律以 reference 文件为准。
before-臃肿版/SKILL.md
---
name: api-helper
description: 当用户需要调用项目 API、查询接口参数或排查错误码时使用。
---
# API 助手(臃肿版 —— 反面教材)
> ⚠️ 这是反面教材:把所有细节都堆在正文,技能一被触发就全量加载,浪费上下文。
## 完整接口列表
### GET /users
返回用户列表。参数:page(页码,默认1)、size(每页条数,默认20)、sort(排序字段)。返回字段:id、name、email、created_at、status……
### GET /users/{id}
返回单个用户详情。路径参数 id。返回字段:id、name、email、phone、address、created_at、updated_at、roles、permissions……
### POST /users
创建用户。请求体:name(必填)、email(必填)、phone、address……
### PUT /users/{id}
更新用户。请求体同上,均为可选……
### DELETE /users/{id}
删除用户……
(……此处假设还有 196 个接口,每个都这样详细罗列,正文长达 2000+ 行……)
## 错误码大全
- 1001:参数缺失
- 1002:参数格式错误
- 1003:用户不存在
- 1004:权限不足
- 1005:token 过期
- (……此处假设还有 145 个错误码……)
## 调用流程
判断用户操作 → 找到对应接口 → 组装参数 → 处理返回 → 遇错查错误码。
九、总结
- 这套机制解决了什么矛盾:渐进式披露就是解药:把又多又细、但不常用的内容沉到第 3 层,平时不加载、不花钱;
- 「什么内容放哪一层」决策表:| 技能名、触发场景 | 第 1 层 frontmatter | 要被频繁扫描,必须极短 |
- 常见错误:❌ 把所有东西都堆进正文:技能是变强了,但每次触发都付高昂的上下文税。
- 最佳实践:拆分服务于「省」和「清晰」,不是为拆而拆——拆了反而更乱就别拆。
学完自测
选择所有正确答案;提交后逐项核对判断依据。