一、先说我量到了什么
Hermes Agent 的 issue 区有人贴过一组数:243 个技能,每次调用多 10 到 15K tokens;130 个,大概 4K。
我不太信,就把自己机器扫了一遍。
结果:磁盘上躺着 570 个 SKILL.md,去重之后是 402 个技能 。只算每个技能的 name 和 description,92,006 个字符,折合约 45,634 tokens。
注意,这不是技能的正文。正文是"按需加载"的,你不用它就不进上下文。我量的这 4.5 万,是目录------那本告诉你"我这里有什么"的册子。
而册子是每一轮对话都要摊开在桌上的。
(口径:中文按约 1 字/token、英文按约 3.8 字符/token 折算,不含 tokenizer 的边界误差。我用的是字符数,这个可复现。)
二、4.5 万 token 是什么概念
拿几个参照物。
- 一篇 2000 字的中文文章,大概 3000 tokens。4.5 万,等于十几篇。
- 一本 3 万字的小册子。
- 放到 200K 的上下文窗口里,占 23%。放到 128K 的窗口里,占 36%。
我装这些技能用了一年多:办公的、剪辑的、设计的、1688 的、SOLIDWORKS 的,还有一堆"看起来以后可能用得上"的。装的时候每一个都很小,加起来是另一回事。
三、但真正的成本不是钱
这里要先纠正一个流传很广的说法:技能占用上下文 = 花钱。
不完全对。
现在的平台基本都做了 prompt caching。缓存命中的价格能差到 20 倍------腾讯混元 Hy4 的定价是每百万 tokens 缓存命中 0.3 元、输入 6 元、输出 18 元。同一个 token,走缓存和走全价不是一个量级。
所以钱这一块,其实被压下去了。
但缓存省的是钱,不省窗口,也不省模型读这一遍。 这 402 条描述依然占着位置,模型依然要在里面做一次选择。你付的是一次注意力,不是一次账单。
这才是"技能税"真正收的地方。
四、402 条描述里挑一条,是怎么挑的
我把技能名按前缀归了一下,结果挺说明问题:
| 前缀 | 条数 | 举例 |
|---|---|---|
baoyu-* |
21 | 封面、配图、翻译、转格式、发微博...... |
deck-* |
21 | 瑞士风、技术分享、路演、安全通报...... |
wecomcli-* |
15 | 文档、表格、会议、日程、邮件...... |
workbuddy-* |
12 | Office 路由、PDF、表格生成、配置同步...... |
video-* |
9 | 剪辑、合成、配音、理解、字幕、复刻...... |
ardot-* |
7 | 幻灯片、UI、海报、画布...... |
data-* |
7 | 清洗、校验、可视化、探查、报告...... |
我说一句"帮我做个 PPT",同时躺在候选里的有:ppt-router、ppt-master、ppt-design、guizang-ppt-skill、ardot-slides,再加 21 个 deck-*。它凭什么选对?
靠描述。描述写得越具体、关键词越全,越容易被选中。
于是所有人都把描述往长里写。我机器上最长的一条 1596 个字符,折 500 多个 tokens,就为了说明一个技能。超过 500 字符的有 29 条。
这就成了一个闭环:描述越长 → 越容易被选中 → 大家把描述写更长 → 目录更胖 → 越难选。
五、减法做了三步
第一步,先看数。 不知道自己有多少,就没法减。文末有脚本。
第二步,按簇合并。 21 个 deck-* 不需要 21 条描述。做成一个路由器:只留一条"要做什么风格的 deck,进来看",里面指向那 21 个。模型看到的从 21 条变成 1 条,能力一个没少。
第三步,描述只写"什么时候用我",不写"我能干什么"。 我现在给自己定的上限是 30 个词。触发条件写清楚,能力让它自己读正文去。
最后是摘,不是删。 从启用列表里移出去,文件留着。哪天要用,再挂回来。
六、减完是多少
我把技能按使用频率排了一遍,只留最常用的 30 个:
45,634 tokens → 7,683 tokens。砍掉 83%。
能力损失?基本没有。那 372 个里,我上一次用到的是三个星期前。
七、这件事没有成本反馈,所以得自己量
装一个技能,你看到的是"多了一个能力"。你看不到的是"多了一条描述,以后每一轮都在"。
这就是它麻烦的地方------装的动作有即时快感,成本却摊在之后每一次对话里。 没有任何一个按钮会提醒你"你的目录已经 4.5 万 tokens 了"。
所以只能自己定期量一次。我给自己定的节奏是一个月一次,跟清理下载文件夹一个道理。
别把技能库当 node_modules。那里装多了只是慢,这里装多了是变笨。
附:量你机器上的技能
把下面这段存成 scan.py 跑一遍。只读 frontmatter,不读正文,几秒钟出结果。
python
import os, re, json
ROOTS = [r"~/.workbuddy/skills", r"~/.workbuddy/plugins/cache"] # 换成你的路径
CJK = re.compile(r"[\u3000-\u9fff\uff00-\uffef]")
def est(s):
c = len(CJK.findall(s))
return round(c + (len(s) - c) / 3.8) # 中文≈1字/token,英文≈3.8字符/token
rows, seen = [], set()
for root in ROOTS:
for dp, dn, fn in os.walk(os.path.expanduser(root)):
dn[:] = [d for d in dn if not d.startswith(".")]
if "SKILL.md" not in fn:
continue
head = open(os.path.join(dp, "SKILL.md"), encoding="utf-8", errors="ignore").read(6000)
m = re.match(r"^---\s*\n(.*?)\n---", head, re.S)
if not m:
continue
name = re.search(r"^name\s*:\s*(.+)$", m.group(1), re.M)
desc = re.search(r"^description\s*:\s*(.+)$", m.group(1), re.M)
if not name:
continue
k = name.group(1).strip().lower()
if k in seen:
continue
seen.add(k)
rows.append((k, est(desc.group(1)) if desc else 0))
rows.sort(key=lambda x: -x[1])
print(f"技能数:{len(rows)}")
print(f"目录开销:约 {sum(r[1] for r in rows):,} tokens")
print("最胖的 10 个:")
for n, t in rows[:10]:
print(f" {t:>5} {n}")
如果你的机器上是 Claude Code,技能在 ~/.claude/skills;Cursor 的规则文件同理,量法一样。
本文的 402 个技能、92,006 个字符、45,634 tokens、7,683 tokens 均由上述脚本在本机实测得出,可复现。Hermes Agent issue 的 243 个技能数字为二手引用,我未在自己的环境复现该仓库规模。