🐎 第3章 授人以渔:Skills 工程实践
📄 一句话概括

技能分三级加载:元数据(一行描述)常驻,正文触发时读,参考文件被点名才读。 三级的意义是把付费点往后推—— 没被用到的东西,一分钱不花。代价是每一次判断都发生在只有一行描述的情况下。

📝 本章和前面几章的关系

上一节把技能拆成头、正文、refs 三块,这一节说清这三块各自什么时候进上下文。 这一节也是整章最该算清楚的一节:算完就知道技能数量为什么不能随便加。

一、图书馆模型

想象一座图书馆。门口有一张索引卡,写着每个书架上放什么。 你进门先看索引,找到可能要的那一排,再走过去抽出书,翻到某一页。 三级披露就是这个结构:索引卡是 description,书架是正文,某一页是 refs 里的文件。 好处显而易见:你不需要把整座图书馆搬回家,只需要每次带走要读的那几页。

坏处也同样明显:你必须只靠索引卡就判断出该拿哪本书。索引卡写歪了,后面两级再精致也没用。 所以这三级里,最该花时间打磨的是最便宜的那一级——它决定了后面两级会不会被打开。

二、三级各在什么时候付钱

第一级是元数据:名字加描述。它每次会话都要读,而且是全部技能的元数据一起读。 第二级是正文。它只在技能被触发时读,而且只读命中的那一个。 第三级是 refs。它只在正文里点了名、并且执行到那一步时才读。

三级的付费时机完全不同:第一级按会话付,第二级按触发付,第三级按步骤付。 演示里按一个中等技能估:描述五十五 token、正文八百、refs 三千。 做二十个,全量是七万七,全量常驻显然不现实。 三级之后,一次会话用两个技能,常驻一千三、读取一千六,合计两千九。差二十六倍。

三、description 的预算机制

关键在第一级的付费方式:它按个数付,不按内容多少付。二十个技能,就是二十条描述一起读。 所以技能数量的上限,等于「窗口里愿意留给描述的那部分」除以「单条描述的长度」。 演示里算了这个税:单条描述三十字符,二十个常驻八百 token;涨到一百四十字符,常驻三千。 字数翻四倍多,常驻也翻近四倍。

这就是为什么描述要写准,不能写长。它是一份每个技能都要交的税,税率由字数决定。 实践中常见的折中是:描述写到「够判定」为止就停,把细节往正文里放。正文不常驻,写长不心疼。 反过来说,正文可以尽情写细,但也不该无限长——它是触发时要读的,长到五千行,触发一次就吃掉半个窗口。 这条在 3.5 节讲。

四、二十个是不是太多了

二十个技能,光描述就一千三百 token。窗口按一万算,占百分之十三。 百分之十三不算致命,但它是一份「每次会话都交、不管用不用」的固定开销。 再加上 CLAUDE.md、系统提示、工具定义,常驻部分很容易就吃掉三成。 所以技能不是越多越好。真实项目里比较稳的结构是:主力十个以内,再加几个只在特定任务里用的。

判断一个技能该不该留,看它一周被触发几次。 一个月都没触发过的,删掉——它一直在收那份税,却从没干过活。 这和 3.1 节那条判据是同一个:成本是频率乘长度。 技能的成本是「个数乘描述长度」,只不过这里的频率被固定成了「每次会话」。

五、第三种做法为什么不可取

演示里还有一行:描述也靠检索。常驻只剩两百 token,总账一千九百,看着最省。 但它把「判断该用哪个」这件事交给了检索,而检索靠的是描述,描述又不常驻——这一步在真机上代价更高。 更实际的问题是:检索会漏。漏了就没有候选,模型只能凭记忆猜,或者干脆不用技能硬做。

所以省钱的顺序是:先把内容分级(常驻/按需/检索),再压描述长度,最后才考虑把描述也搬出去。 倒着来会先把可用性搞没。 一句话收这一节:渐进式披露不是「少读」,是「晚读」。晚读的前提是「早读的那一点足够判断」。

六、动手 Demo:二十个技能,三级加载各要付多少

按一个中等大小的技能估:name 十 token、description 五十五、正文八百、refs 三千。 做二十个,一次会话里用到两个。 比较三种做法:全塞进常驻文件、只常驻描述、连描述也靠检索。再算描述写长之后要多交多少税。 token 按字符数估,中文按一个字符一个 token 算——这是粗估,量级对得上就够用。

SK_NAME, SK_DESC, SK_BODY, SK_REF = 10, 55, 800, 3000
SK_N, USE = 20, 2        # 二十个技能,一次会话用到两个

allin  = SK_N * (SK_NAME + SK_DESC + SK_BODY + SK_REF)   # 全塞常驻
lazy   = SK_N * (SK_NAME + SK_DESC) + USE * SK_BODY       # 只常驻描述
far    = SK_N * SK_NAME + USE * (SK_DESC + SK_BODY)       # 描述也检索

实跑输出:

--------------------------------------------------------------------
二十个技能,三级加载各要付多少
--------------------------------------------------------------------

  按一个中等大小的技能估:name 10 token、description 55、正文 800、参考文件 3000。做二十个。
  单个全量是 3865 token,二十个全量是 77300。

  ① 三种做法,一次会话用两个技能
  --------------------------------------------------------------------
| 做法 | 常驻 | 本次读取 | 合计 |
|---|---:|---:|---:|
| 全塞进 CLAUDE.md | 77300 | — | 77300 |
| 只常驻描述 | 1300 | 1600 | 2900 |
| 描述也靠检索 | 200 | 1710 | 1910 |

  第一种是第二种的 26.7 倍,是第三种 40.5 倍。
  第三种看着最省,但它把「判断该用哪个」这件事交给了检索,而检索靠的是描述,
  描述又不常驻——这一步在真机上代价更高。

  ② 三级各在哪一级付钱
  --------------------------------------------------------------------
| 级别 | 单个大小 | 什么时候付 |
|---|---:|---|
| 第一级 元数据 | 65 | 每次会话,全部 20 个 |
| 第二级 正文 | 800 | 触发时,只读命中的那个 |
| 第三级 参考文件 | 3000 | 正文点名的文件被执行到才读 |

  ! 关键在第一级:它按【个数】付,不按大小付。
  所以技能数量的上限,由「描述写多长」乘「有多少个」决定——这就是 description 的预算机制。

  ③ 描述写长一点,会贵多少
  --------------------------------------------------------------------
| 单条描述 | 二十个的常驻 |
|---|---:|
| 30 字符 | 800 |
| 55 字符 | 1300 |
| 90 字符 | 2000 |
| 140 字符 | 3000 |

  描述从 30 字符涨到 140 字符,常驻从 800 涨到 3000,接近四倍。
  ! 这就是为什么描述要写准,不能写长。它是一份【每个技能都要交的税】,税率由字数定。
  写到能判定的最短长度,就停。

  ④ 二十个是不是太多了
  --------------------------------------------------------------------
  二十个技能,光描述就 1300 token。如果会话窗口是一万,占 13%。
  所以技能不是越多越好。
  真实项目里常见的做法是:主力技能十个以内,再加几个按插件装进来的、只在特定任务里用的。
  判断一个技能该不该留,看它一周被触发几次。
  一个月都没触发过的,删掉——它一直在收那份税,却从没干过活。

①三种做法的账:七万七、两千九、一千九。第一种是第二种的二十六点七倍。 第二种是这套机制的标准形态:常驻只有描述,正文触发才读。 第三种看着最省,但它把「判断该用哪个」交给了检索,而检索靠的正是描述——描述不常驻,判断就没依据。 ②三级各自什么时候付钱,是这一节最该记住的一张表。第一级按个数付:二十个技能就是二十条描述一起读。 第二级只读命中的那一个,所以用几个付几个。第三级更晚,正文执行到那一步才读。 ③描述写长要多交多少税:三十字符八百、一百四十字符三千,接近四倍。而技能数量不变、功能不变。 所以描述是「每个技能都要交的税」,税率由字数定。 写到能判定的最短长度就停,剩下的细节往正文放——正文不常驻。 ④最后算了一句总量:二十个技能光描述一千三,窗口一万的话占百分之十三。 这不是不能接受,但它是一份无论用不用都要交的固定开销。 判断留不留的标准是触发次数。一个月没触发过的技能,一直在收税却没干活,删掉最划算。

30 秒实验

  1. 把技能数从二十改成五个,重跑第 ① 步。三种做法的倍数关系变了吗?为什么?
  2. 把「一次会话用两个」改成用五个,第二、三种做法的账各涨多少? 这说明什么场景下「描述也检索」才划算?
  3. 把单条描述从五十五字符压到三十五,二十个的常驻降到多少?压缩的代价可能是什么?

常见误区

  1. 以为技能「不占上下文」。它占——占的是那一行描述,而且是每个技能都占、每次会话都占。
  2. 把 refs 当成「会自动加载的资料库」。refs 不会自动读,正文点名到具体文件才会读。
  3. 描述写得越长越详细越好。描述是常驻的,写长等于给每次会话加税;细节应该放正文。
  4. 靠「描述也检索」来省常驻预算。省下的那点钱,换来的是判断依据缺失、候选漏召回。
  5. 舍不得删技能。一个从没被触发的技能不是「备用能力」,是「一直在收费的空房间」。
自测三问(点开对答案) 1. 三级披露分别是什么,各自什么时候进上下文? —— 元数据(名字加描述)每次会话都进;正文在技能被触发时进,只进命中的那个; refs 在正文点名且执行到那一步时进。 2. 为什么说 description 是「按个数付」的? —— 因为每次会话要把所有技能的描述一起读进来,二十个技能就是二十条。所以总量等于个数乘单条长度。 3. 「描述也靠检索」这种最省的做法,代价是什么? —— 判断该用哪个技能的依据(描述)不在上下文里了。 检索会漏,漏了就没有候选,模型只能猜或者不用技能。

知道了三级怎么付钱,下一节看那个最关键的判断:模型凭什么选中某一个技能。

相关笔记