我把一份线上 SKILL.md 拿 tiktoken 量了一遍:正文 14,147 token,摘要只要 157
2026/8/25 15:38:02 网站建设 项目流程

写 Agent skill 的人很多,真去量过一份 skill 有多大的人很少。

我量了。样本是一份线上生产环境正在跑的SKILL.md,不是玩具 demo。结果比我预估的严重 17 倍——我原先拍脑袋估的是 800 token。

先摆数字:

字符 o200k cl100k SKILL.md 24,624 14,147 18,018 references/*.md(3 份) 6,672 2,870 3,254 摘要那一条(name + description + location + XML 包装): 263 157 212

摘要 / 正文 = 157 / 14,147 = 1.1%。

那么我们如何做测量呢?


一、怎么量:三行代码,你可以拿自己的 skill 复现

importtiktoken,pathlib enc=tiktoken.get_encoding("o200k_base")# cl100k_base 是老口径,见下p=pathlib.Path("path/to/SKILL.md")print(len(p.read_text()),len(enc.encode(p.read_text())))

两个口径都给,是因为它们能差 27%(14,147 vs 18,018)。中文占比高的 skill 差得更多。报数字的时候不写口径,等于没报——这是我踩过的第一个坑:一开始拿 cl100k 量、拿 o200k 的窗口算,白紧张了一轮。

"摘要那一条"指的是 skill 没被激活时,常驻在 system prompt 里的那部分:name+description+ 文件位置 + 外面那层 XML 包装。263 个字符,157 token。


二、渐进披露不是优化,是可行性前提

很多人把"skill 按需加载"理解成一个省钱的优化项——能省就省,不省也能跑

算一笔账就知道不是。

假设你有 10 个这种规模的 skill(对一个正经系统来说,10 个不多):

全塞正文 141,470 token 每轮付 ← 直接爆窗口,一轮都跑不起来 只放摘要 1,570 token 每轮付 真读一个 +14,147 token 一次性

14 万 token 每轮。这不是贵不贵的问题,是一轮都跑不起来

所以"只放摘要、用到才读正文"这件事,在 skill 数量上到两位数之后,是能不能跑的前提,不是省不省钱的选择。渐进披露省掉的那 98.9%,是你的系统能存在的理由。

反过来说也成立:如果你只有两三个 skill,你确实感觉不到差别——这就是为什么很多人做到一半、形状建了一半就停了。下一节就是这样一个例子。


三、references/建了,一次都没被引用过

这份 skill 是有references/目录的。三个文件,写得也不差:

references/commands.md 1,154 token references/errors.md 1,083 token references/params.md 633 token ──────────── 2,870 token

然后我全目录 grep 了这三个文件名和references这个词:

→ 零命中

没有任何一个地方引用它们。SKILL.md 正文里没提,代码里没提,索引里没提。这 2,870 token 写下来了,模型永远读不到

这不是谁偷懒。渐进披露的目录形状建了,线没接上——建目录这个动作有很强的"我做完了"的错觉,而"正文里真的有一句话告诉模型什么时候去读它"这一步,没有任何东西会提醒你漏了

所以结论是一条闸,不是一句提醒:

加一个 CI 检查:skill 目录里每一个存在的引用文件,都必须在正文里被真的引用过。写了没接线,判红。

形状不等于机制。靠自觉维持的东西,扛不过第二个往里写代码的人。


四、62.8% 的 token 压在一个小节里

把 SKILL.md 按二级标题拆开量:

主流程小节 8,890 token 62.8% 调用方式 1,290 9.1% 错误处理 649 4.6% 其余 13 个小节 3,318 23.5% ────────────────── 14,147 100%

一个小节吃掉六成。而这个小节内部,是线性的 Step 0–6

Step 0 1,645 Step 3 1,033 Step 4 836 Step 4.5 2,529 ← 最大的一块 Step 5 1,080

关键的一句话:

一次对话里,模型不可能同时处于 Step 2 和 Step 5。

链路还停在前半段的时候,Step 4.5 那 2,529 token 是纯浪费——它不只是费钱,它还在稀释当前这一步真正重要的约束。模型手上多拿着 2,500 token 跟眼下无关的规则,判断只会更差,不会更好。

所以正确的形状不是一个 14k 的文件:

SKILL.md ~2k 总原则 + 错误铁律 + 流程骨架(每步一行) steps/step0.md 1.6k 走到哪步读哪步 steps/step4_5.md 2.5k ... 14k → 常驻 2k + 按需 1–2.5k

这里有一层很多人没走到的区分:

  • 第一层渐进披露:description 常驻、正文按需读。——这层,我量的这份 skill做对了
  • 第二层渐进披露:skill 内部按 step 拆,走到哪步读哪步。——这层没做,一激活就是整份 14k。

第二层才是大头。第一层省的是"没用到的 skill",第二层省的是"用到了、但这一步用不上的那 80%"。


五、一个没人提的坑:自动压缩会把你的口径悄悄摘要掉

这条我觉得最值得单拎出来,因为它不报错

skill 正文一旦被读进来,它就是对话历史里的一条 message。而现在的 agent 框架基本都带自动压缩(context 超阈值就摘要折叠)。

那下一次压缩,就会把你的口径摘要掉。

想想这意味着什么。假设你的口径里有一条明确的禁止性约束:

模型不会跟你说"我忘了那条禁令"。
它只会开始做那件你禁止过的事。

约束丢失是静默的。你不会在日志里看到任何异常,你只会在某一天看到一个不该发生的输出。

两条路:

做法代价
A把 skill 正文标成压缩时保留保留的都是原文,压缩基本省不下东西
B ✓正文不进历史,每轮按当前 step 重放每轮付 1–2.5k,但约束永远是原文

选 B。每轮 1–2.5k 比一次性读 14k 还便宜;更要紧的是——

不可撤回的动作所依赖的约束,不能靠摘要传递。

如果你的 skill 只管"回答得好不好",摘要掉了顶多效果差一点。如果它管的是能不能执行、执行了收不回来的那一类动作,那它就不能活在会被摘要的那一层。

配套的闸很直接:压缩发生之后,断言当前 step 的口径原文仍逐字节在上下文里——不是"还在",是"是原文"。


六、顺带纠一个流传很广的前提:长 prompt 不是延迟的主因

我一开始也是奔着"太长了会慢"去量的。量完发现动机错了。

prefill 是并行的,通常不是瓶颈。真正的耗时是 decode 和多轮 tool 往返。

对延迟来说:减少轮数 ≫ 缩短 prompt。

这有个很实际的推论——如果链路上有些判断根本不需要模型,把它们从 prompt 里拿掉,收益是双份的:prompt 短了,而且少了一整轮往返

我这份样本上,能拿掉的比想象中多。按性质分,只有最后一类真的需要模型

判断的性质要模型吗为什么
数值比较、阈值判断不要一次整数比较的事
状态查重、时间窗口不要查一下、算一下的事
格式硬校验不要拦截点应该在执行前,不是在模型脑子里
需要理解语义的判断这才是模型的活
需要生成自然语言的同上

五类判断三类是规则。拿掉之后 prompt 短一半,而且结果更稳定——同一条输入今天判 A 明天判 B,调用方会疯。

判据一句话:

把模型拔掉,这条链还能不能跑?能跑,就说明它压根不需要模型。


七、什么该进 skill,什么该进代码

上面那条推到底,会撞上一个真实的矛盾:

流程放进代码 =改流程要发版,而外置 skill 的初衷恰恰是"改一句话术不用发版"。

这两条是打架的。所以分界线必须写出来,不能靠感觉:

什么放哪为什么
话术 · 口径 · 语气skill改得频繁;改错了是效果问题,不是事故
流程顺序 · 能不能进下一步 · 什么时候允许执行代码改得少;走错一步是不可撤回的事故

判据一句话:

改错了会不会造成不可撤回的后果?会 → 进代码;不会 → 进 skill。

顺带一个反直觉的观察:我量的这份 skill 用的是"prose 状态机"——那 8,890 token 的 Step 0–6 全靠模型读散文自律,代码一步都不拦。而它没做错。

因为在人在环、逐轮推进的链路里,四条前提都成立:每一步都有外部输入当天然分界;模型从历史里一眼能看出走到哪了;走错了会被当场纠正;真正不可撤回的点只有一个。

但换成无人值守、批量并发的链路——同一批任务并行跑、没有外部输入当分界、历史里分不清哪条是哪条、每一条的输出都不可撤回——上面四条全反。prose 状态机在那边一条都不成立。

同一个做法,一边对一边错。判据不是做法本身,是那四条前提。


八、三条可以直接抄走的闸

如果这篇你只带走一样东西,带这三条。它们全是脚本判的,不靠人自觉:

  1. 任何单个SKILL.md≤ 3,000 token(tiktoken 实测,写明口径)。超了必须拆进steps/
  2. skill 目录里每一个引用文件,都必须真的被引用过。写了没接线判红——防的就是那 2,870 token 的死内容。
  3. 压缩发生之后,当前 step 的口径原文仍逐字节在上下文里。不是"还在",是"是原文"。

第 3 条最容易被跳过,因为没有它系统照常跑——它只会在某一天,让模型做出一件你明确禁止过的事。


最后

这篇里没有一个数字是估的,全是拿一份真在线上跑的 skill 量出来的。你可以拿自己的 skill 复现——我猜大部分人量完的表情会跟我一样

我最大的收获不是那些数字,是量完之后意识到的这件事:

skill 不是"给模型的说明书",它是一份要付每轮成本的常驻资产。

按说明书写,你会写出一份完整、自洽、24,624 字符的文档。
按资产写,你只会问一个问题:这一刻,模型手上必须有哪一段?

那份 14k 的文件,是照第一种写法写出来的。它写得很好——问题在于,它是一份好说明书。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询