背景
Hermes 默认加载全部技能(不是技能索引)。刚装完系统,一条消息发过去,系统提示里就塞满了所有技能的定义。
直觉告诉我这很浪费。但浪费多少?哪些优化手段真的有效?
实测:各模块占用 token 数
用 Hermes 内置的统计功能实测各模块的 token 占用:
| 模块 | token 数 | 占比 |
|---|---|---|
| 技能(121 个全加载) | 12,000 - 15,000 | ~63% |
| MCP 工具定义 | 8,000 - 10,000 | ~33% |
| 系统提示(核心) | 3,000 - 4,000 | ~13% |
| 记忆 | 1,000 - 2,000 | ~5% |
| 总计 | 24,000 - 31,000 | 100% |
技能占了大头。注意这只是系统提示的初始占用,还没算对话历史。
哪些优化有用
真正有效的
| 优化手段 | 节省 token | 说明 |
|---|---|---|
--skills 白名单 | ~10,000+ | 只加载需要的 2-3 个技能,砍掉 90%+ |
| 禁用 MCP 服务器 | 8,000 - 10,000 | 不需要的 MCP 服务器关掉 |
| 记忆只加载最近 | 500 - 1,000 | 限制记忆加载条数 |
没什么用的
| 手段 | 结果 |
|---|---|
disabled_toolsets | 只隐藏了技能分组,技能描述仍然加载 |
| 砍技能索引 | 索引只占几百 token,砍了没意义 |
| 缩短技能名称 | 命名字段很短,省不了几个 token |
disabled_toolsets 的误区
很多人(包括我)一开始以为关闭工具集就能减少上下文占用。但翻 Hermes 源码后发现:
disabled_toolsets 只是不显示这些技能分组,并不阻止加载技能描述。121 个技能的描述文本早就在系统提示里了,disabled_toolsets 只控制界面层面的可见性。
真正能减少技能描述加载的只有一个方案:--skills 启动参数。
--skills 白名单方案
启动 Hermes 时指定只加载需要的技能:
hermes chat --skills shell,web_search,memory
这样系统提示里只有 3 个技能的定义,而不是 121 个。
效果对比:
| 模式 | 技能占用 | 节省 |
|---|---|---|
| 默认(121 技能) | ~13,000 tokens | - |
--skills shell,web_search,memory | ~500 tokens | ~12,500 |
节省出来的 12K tokens 可以放更多对话历史,或者降低压缩频率。
上下文优化策略
按 ROI 排序:
--skills白名单:投入最小、收益最大,一句话省 10K+- 关闭不需要的 MCP 服务器:禁用不用的 server 省 8-10K
- 调整记忆加载量:max_memories 从 10 降到 3,省几百到 1K
- 压缩参数调优:调整 threshold 控制压缩时机
- 删技能定义文件:不推荐,破坏系统完整性
优化前后的系统提示对比
优化前(默认):~30K tokens
[系统提示]
[核心指令] 3-4K
[121 个技能] 12-15K
[MCP 工具] 8-10K
[记忆] 1-2K
优化后(--skills + 关 MCP):~7K tokens
[系统提示]
[核心指令] 3-4K
[3 个技能] ~500
[记忆] 1-2K
省出来 20K+ tokens,对话可以持续更久才触发压缩,Agent 的「记忆力」显著提升。
关键教训
- 不要靠猜测做优化。测一下 token 实际占用,你会发现和直觉不一样。
--skills是最优方案。它不是完美的(每次启动要手动指定),但收益横跨所有使用场景。- 源码暴露真相。当文档和行为不一致时,源码是最好的参考。
- 优先砍最大项。技能 12K >> MCP 8K >> 系统提示 3K,先砍最大的。