🐸 青蛙编程网
首页 / AI / 技能 Skills / 3. 渐进式披露

3. 渐进式披露

这是什么:渐进式披露(progressive disclosure) = 技能分三次交付:启动时只给「名字 + 简介」,选中后给正文,引用到才给附件。

为什么用:一个 Agent 装几十个技能很常见,但每次对话都用得上几十个吗?全量塞进上下文,光技能目录就能吃掉几千 token,还挤掉了真正重要的任务信息。

如何用:本章把三层各自的成本摊开算,重点讲第一层——description 是一次检索,模型只靠它挑技能。

3.1 三层的账本

规范给的成本基线是这么写的:

层级 内容 成本基线 加载时机
L1 元数据 name + description 约 100 token / 个 会话启动时,全部加载
L2 说明书 SKILL.md 正文 建议 < 5000 token 技能被激活时
L3 资源 scripts/ references/ assets/ 不定 正文引用到时

做个粗算:装 40 个技能,光 L1 就是 40 × 100 ≈ 4000 token,一个技能正文都还没读就已经花掉了。这就是为什么 L1 必须短。

3.2 L1:description 是一次「检索」,不是「介绍」

模型在会话启动时看到的是这样一坨东西(opencode 的真实格式):

<available_skills>
  <skill>
    <name>git-release</name>
    <description>Create consistent releases and changelogs</description>
  </skill>
</available_skills>

注意这里只有名字和简介,没有正文。模型拿着这段目录做判断:现在这个任务,要不要调 skill({ name: "git-release" }) 把正文拉下来?

所以 description 的读者是模型,不是人。它的任务不是「介绍这个技能」,而是「让模型在正确的时刻认出来」。写 description: 一个很好用的周报技能 等于没写。

不同工具的 L1 呈现方式略有差别:

工具 L1 长什么样
opencode <available_skills> 列表,模型调 skill 工具加载正文
Claude Code 命令菜单 + 自动匹配;description(含 when_to_use)在列表里截断到 1536 字符
Hermes skills_list() 只返回名字和摘要(整体约 3k token)

Hermes 那套更直白——它的三个层级就是:

Level 0: skills_list()          → 只有名字和简介(约 3k token)
Level 1: skill_view(name)       → 任务真匹配了,才读全文
Level 2: skill_view(name, path) → 连参考文件也按需读

同一套渐进式披露,换了个产品还是这个套路。

3.3 description 的写法公式

一个能用的 description 通常包含三块:

<动词短语:做什么>。<场景:什么时候用>。<关键词:用户会怎么问>

照着这个写:

description: 汇总本周 Git 提交与 Issue,生成周报(三段式:做了什么/风险/下周计划)。用户提到「周报」「本周总结」「这周干了啥」时使用。

四个要点:

要点 说明
动词开头 「提取」「汇总」「检查」,别用「用于……的辅助工具」
写清触发场景 「用户提到 X 时使用」——模型靠这句话对齐用户的说法
塞关键词 用户嘴里的词(周报、发布、回滚)比规范术语(changelog、deployment)管用
别写实现 「调用 GitHub API 拉取 PR」是实现细节,不影响选择,可以省

反例对照:

❌ 差 为什么差
description: 周报技能 没说什么时候用,模型无从判断
description: 本技能通过分析 git log 生成结构化周报报告文档 全是实现细节,用户说的是「出周报」不是「分析 git log」
description: A helpful skill for generating weekly reports 英文泛泛而谈,中文提问命中不了

3.4 L2:正文是「激活后」的常驻成本

技能被加载后,正文会一直留在上下文里(Claude Code 的官方说明里明确写了这点),直到会话结束。

这意味着正文应该写成操作清单,而不是说明书:

# ✅ 这样写
1. 跑 `git log --since="7 days ago" --oneline`
2. 按「做了什么 / 风险 / 下周计划」三段输出
3. 写到 `reports/YYYY-WW.md`

# ❌ 别这样写
因为团队每周都需要一份清晰的总结来对齐进度,所以本技能会先去收集本周的
提交记录,这一步非常关键,能够保证周报内容完整、不遗漏任何重要改动……

后者的信息量是零,token 成本却按字数一直付到会话结束。理由写给 review 的人看,步骤写给 Agent 看。

正文该有的三块内容(规范推荐):

  1. 分步骤指令——怎么做
  2. 输入输出示例——做成什么样算对
  3. 常见边界情况——什么时候别这么干

3.5 L3:资源按需拉取

第三层是 scripts/、references/、assets/。它们不占常驻上下文,只在 Agent 真的去读的时候才进来。

这给了一个非常实用的策略:把「可能用不到但很长的内容」全部下沉到 references。比如一份 800 行的接口文档,塞进正文就是每轮都在付钱;放进 references/api.md,则是用的时候才付。

weekly-report/
├── SKILL.md                    # 简短:只有步骤和输出格式
└── references/
    ├── report-template.md      # 周报模板:需要时才读
    └── issue-classification.md # Issue 分类规则:需要时才读

注意 L3 的规矩:引用只做一层,路径相对于技能根目录。

3.6 上下文预算怎么估

给一个新技能估成本,可以这么算:

常驻成本 ≈ L1 总和(元数据 × 技能数)
激活成本 ≈ L2(这个技能正文的 token 数)× 该技能活跃的轮数
偶发成本 ≈ L3(被引用到的资源大小)

实践中的三条经验:

  1. 技能数量控制在几十个以内。上百个技能时,光 L1 目录就会让模型的注意力被稀释,命中率跟着掉
  2. 同类技能合并。十个「日报类」技能不如一个「日报类」技能带三段说明——描述写清楚适用范围,模型自己会分
  3. 正文控制在几百 token。真需要长的,把细节下沉到 references/

🤝 记忆口诀:描述是检索词,正文是操作单,附件是抽屉。

动手改

  1. 拿你写过的一个技能,把 description 改成「动词 + 场景 + 用户关键词」三段式,然后故意用一个不含任何原关键词的说法去试它,看模型还能不能选中
  2. 把技能正文里所有「因为…所以…」的解释性段落删掉,只留步骤,对比删前删后正文长度
  3. 给技能加一个 references/notes.md(至少 50 行内容),在正文里引用它,观察它只在被需要时加载

小结

  • 三层账本:L1 元数据 ≈100 token/个常驻,L2 正文 <5000 token 激活后加载,L3 资源按需
  • L1 是唯一的检索依据,description 要写「做什么 + 何时用 + 用户关键词」
  • 正文一旦加载就常驻到会话结束,写操作清单,不写解释性长文
  • 细节下沉到 references/,按需拉取,引用只做一层
  • 技能别装太多,同类合并;把 L1 当目录页来经营

下一章:编写实战,三个可选目录到底该放什么、怎么拆 🐸

📥 下载本章代码

ZIP 内含本章全部代码文件与说明,解压即用,与教程内容同步生成。