给 Hermes 上下文减负:官方出品的四层省钱方案


一个跨 20 个文件的 bug,一场拖了一下午的数据迁移,一次没完没了的重构——长任务跑到第三个小时,你开始察觉不对劲:每条消息的响应越来越慢,打开服务商后台一看,这个会话烧掉的 token 比这个月其他所有会话加起来还多。这不是错觉。每一轮对话,模型都要把整段对话从头重读一遍,包括两小时前就过期了的工具输出和中间步骤。这堆东西越大,你每说一句话就越贵。Hermes 把这件事的解法叫作“上下文减负”,而自从 8 月初 v0.20 发布以来,官方的减负工具已经悄悄变得非常好用了。这篇文章把所有可验证的减负手段串成一条线:升级白得哪些、哪些旋钮值得自己拧、平时靠哪些斜杠命令保持会话身材。

为什么每轮都在重复付钱

先建立一个直观的心智模型:LLM 本身没有记忆。你每发一条消息,它收到的都是完整上下文——系统提示、已加载的技能、工具定义、你的记忆文件、对话历史、每一个工具输出——然后从头读一遍。“Token”就是这段文本的计量单位,而你发送的每一个 token,每一轮都要付费。

所以一个会话的总成本大致等于上下文大小 × 轮数。这两个数只要砍掉一个,账单立刻缩水。上下文减负的全部意义就在于此:保留能提升回答质量的信息,丢掉重复的、过期的、无关的内容——同时不让 Agent 变笨。

第一层:自动压缩,开箱即用

Hermes 内置了一套双层压缩系统,不需要任何配置就自动工作:

  • Agent 层压缩器(ContextCompressor)——主力系统,跑在 Agent 的工具循环里,用的是 API 上报的真实 token 数。会话超过模型上下文窗口的 50%(可配置)时触发。
  • 网关卫生层(Gateway Session Hygiene)——85% 阈值的安全网,在每轮处理之前运行。专门接住那些在轮次之间悄悄涨爆的会话(比如 Telegram、Discord 里隔夜积压的消息),避免 API 因请求过大直接报错。

压缩触发后分四步走:

  1. 剪掉旧工具输出——先丢最老的工具结果。这一步完全免费:不调用任何模型。
  2. 对齐边界——压缩器会往回找,绝不让一组“工具调用 → 工具结果”被拦腰截断。
  3. 生成结构化摘要——把对话中段交给一个辅助模型,让它写出包含目标、决策、进度、下一步的结构化摘要。摘要预算随内容缩放(约 20%),下限 2,000 token,上限为上下文窗口的 5%。
  4. 重组——压缩后的会话 = 头部(系统提示 + 早期上下文)+ 摘要 + 最近的原文尾部。

官方文档给了一个完整例子:一个 45 条消息、约 95K token 的会话,压缩后变成 25 条消息、约 45K token——大约省掉 53%,摘要加最近尾部保证了连贯性。

第二层:升级,v0.20 大改造自动生效

v0.20.0(8 月 3 日)对压缩做了一次深度翻新,官方原话叫“Compression that respects your conversation”(尊重你对话的压缩)。几个头条变化都合并进了上游,release notes 可查:

  • 每轮微压缩(per-turn micro-compaction)——不再是一次卡顿很久的大压缩,而是把成本摊到每一轮,小步快跑。
  • N 条用户消息兜底——compression.min_tail_user_messages(默认 1)保证最近的真实用户消息永远活下来。你真正问过的话,一条都不会丢。
  • 主动裁剪工具结果——大窗口模型在阈值到达之前就会清理过期的工具结果,从源头防止堆积。
  • Ghost-skill 防御——会话中途删掉的技能再也不能阴魂不散地留在上下文里([SKILL_PRUNED] 标记让清理变成确定性行为)。
  • 按模型阈值 + 绝对 token 阈值——可以为不同模型设置不同的触发百分比,或者直接用固定 token 数触发(compression.threshold_tokens)。当你的模型窗口大小差异很大时,这个特别有用。

最新的一块是 8 月 26 日合并的 lean tail 模式PR #87326)。旧压缩公式按窗口大小等比保留原文尾部——在 1M 上下文的模型上,每次压缩后要囤积 17 万 token 的原始历史,让 /compress 形同虚设,而且每轮都要把这 17 万重新发给模型。Lean 模式把尾部夹紧到窗口的 2.5%(10K–25K token),把连贯性交给升级版摘要(内容摘要 + 锚点索引 + 恢复指针)。改一个默认值,每轮省下十几万 token。如果 hermes config get compression.tail_mode 还显示 legacy,跑一下 hermes update——新默认就是 lean

第三层:值得自己拧的旋钮

压缩的默认值很合理,但稍微调一调,收益立竿见影。先看看你现在的配置:

hermes config get compression.enabled             # true
hermes config get compression.threshold           # 0.50(上下文用到 50% 时触发)
hermes config get compression.target_ratio        # 0.20
hermes config get compression.tail_mode           # 最新版为 lean
hermes config get compression.protect_last_n      # 20(尾部最少保留条数)
hermes config get compression.min_tail_user_messages  # 1

三个最值得动的调整:

1. 大窗口模型提前触发。 如果你用的是 200K+ 的模型,等到 50% 意味着每轮已经要发约 10 万 token。把 compression.threshold 调到 0.4,或者直接用固定阈值:

compression:
  enabled: true
  threshold_tokens: 80000    # 会话超过 80K token 就压缩

2. 按模型设置不同阈值。 不同模型窗口不同、价格不同:

compression:
  model_thresholds:
    "claude-sonnet": 0.35
    "glm-5.2": 0.40

3. 让摘要更便宜。 写摘要也是一次 LLM 调用——默认用自动检测的模型,但你可以把它指向一个便宜快速的模型,把贵的旗舰模型留给真正的干活:

auxiliary:
  compression:
    model: <一个便宜快速的模型>

压缩摘要不是烧钱的地方,别把最贵的模型用在上面。

第四层:日常保持身材

四个斜杠命令,让你随时知道发生了什么、以及能做什么:

命令 作用
/context 拆解上下文窗口里到底塞了什么——技能、工具、记忆、历史、文件
/usage 查看会话的 token 用量和费用(hermes insights 还能看最近 30 天)
/compress 感觉变慢时手动触发一次压缩
/focus 精简输出视图,隐藏嘈杂的工具行,需要时还能找回来

除了命令,几个习惯能砍掉每轮都跟着跑的固定开销:

  • 关掉不用的技能。 每个启用的技能都会把它的头部信息注入每轮上下文。hermes skills list 看一眼,hermes skills disable <名称> 关掉从来不用的。
  • tool_search 设为 auto 工具按需加载,而不是每轮把所有工具定义全发一遍。
  • 保持记忆和 AGENTS.md 精简。 注入的记忆和项目说明里每个字符都会在每条消息里重发。存持久事实,别存任务进度。
  • 会话中途别换模型。 大多数服务商都会缓存 prompt 前缀——系统提示保持稳定,后续消息命中缓存,费用大幅降低。中途换模型会废掉缓存。
  • 学会委托和批量。 耗时的调研用 delegate_task 丢给子代理、批量文件操作写一个 execute_code 脚本一次跑完,让庞大的中间输出留在主对话之外。

串起来看

以上所有手段都不牺牲能力。官方示例里,一个典型长会话 95K → 45K;在大窗口模型上,lean tail 一项就砍掉每轮十几万纯开销的 token。自动压缩负责历史,v0.20 大改造让它更温和更便宜,几行配置适配你的模型,日常习惯从源头防止堆积。

两个提醒。第一,阈值别调得太激进——每次摘要都是一次小型 LLM 调用,短会话反复压缩,钱全烧在摘要上而不是答案上。第二,减负针对的是重复、过期、无关的内容;如果会话真的又长又全都用得上,更该考虑无限 max_turns会话导出,而不是硬压压缩。

想知道 lean tail 新默认值背后的完整故事和大窗口模型的真实数字,看这篇。如果账单暴涨是因为上下文窗口被设得比服务商公布值还大,看这篇。想把上下文预算的每个字段都搞清楚,长任务配置指南值得收藏。