上一节讲了 MEMORY.md 的容量满了之后 Hermes 怎么腾空间。但除了记忆文件,还有一个地方会满——对话本身的上下文窗口。这一节讲的就是:上下文快满了会发生什么,怎么压缩,以及怎么让压缩后的效果更好。
3.1 上下文窗口是什么
每次跟 Hermes 对话,所有的内容——系统提示词、MEMORY.md、历史消息、工具调用的结果——都会一起发送给大模型。这些内容加在一起,就是"上下文"。
大模型能接受的上下文是有上限的。这个上限因模型而异,从 8K 到 1M Token 不等。用 /usage 可以看到当前的占用情况:
Current context: 17,701 / 1,000,000 (2%)
刚开始聊的时候占比很小。但随着对话越来越长,这个数字会持续增长。等到上下文快满的时候,Hermes 的响应会变慢,有时候还会「忘记」前面说过的话——不是真的忘了,而是早期的内容被挤到了上下文边缘,模型注意力顾不到那里。
3.2 压缩是怎么回事
Hermes 有一套压缩机制来解决这个问题。核心思路很简单:把早期的对话内容交给一个模型做摘要,用一段精炼的总结替代原来的逐字记录,腾出空间给新的对话。
压缩之后,上下文的结构大致是这样的:
系统提示词(SOUL.md、MEMORY.md 等) ← 始终完整保留
压缩摘要(早期对话的精华) ← 替代了原来的几十轮对话
最近几轮对话(原文) ← 逐字保留,不动
系统消息永远不压缩,最近的对话也原样保留。被压缩的只有中间那段——已经聊过、做过、结果都出来了的部分。
3.3 两种压缩方式
自动压缩
Hermes 默认开启了自动压缩。在 ~/.hermes/config.yaml 里可以看到相关配置:
compression:
enabled: true
threshold: 0.50
summary_model: "google/gemini-3-flash-preview"
threshold 是触发阈值。0.50 表示上下文用到 50% 的时候,Hermes 会自动启动压缩。summary_model 指定用哪个模型来做摘要——通常会选一个便宜又快的小模型,因为摘要任务不需要太强的推理能力。
自动压缩不需要任何操作,Hermes 自己会处理。用 /usage 可以看到 Compressions 字段,记录的是会话期间自动压缩发生的次数。
手动压缩
有时候不想等到 50% 才压缩。比如上下文里有一大段工具输出的日志,看完就不需要了,但自动压缩还没触发。这时候可以主动压缩:
> /compress
/compress 会立刻把当前上下文做一次摘要。效果跟自动压缩一样,只是时机由自己控制。
一个常见的用法是:做完一件大事(比如重构了一整个模块),趁结果还热乎,/compress 一下。这样摘要里会清楚地记录"做了什么、结果如何",而不是等到上下文快满了才被动压缩,那时候摘要可能会丢掉一些细节。
3.4 怎么让压缩效果更好
压缩的本质是让小模型读一遍对话历史,写一份摘要。摘要的质量直接决定了压缩之后 Hermes 还能"记住"多少。以下几个做法可以让摘要更有料:
一个会话专注一件事。 如果在同一个会话里既讨论了数据库选型、又写了前端页面、还修了一个 bug,压缩的时候摘要会把这三件事混在一起,每件事都只能分到一两句话。反过来,如果会话主题集中,摘要就能把来龙去脉讲得更完整。
关键结论主动说一遍。 压缩时小模型会优先捕捉"有结论性"的内容。如果在对话过程中明确说过「最终决定用 PostgreSQL,因为……」,这句话大概率会出现在摘要里。但如果结论只是隐含在对话里、没有明确说出来,就可能被丢掉。
压缩前清理一下上下文。 如果会话里有大段的工具输出(比如一个几百行的日志),而这些内容后续不再需要,可以在压缩前先告诉 Hermes:「刚才的日志不需要保留了。」这样压缩时模型会把注意力集中在真正重要的对话上,而不是浪费摘要空间去概括一段日志。
长任务分会话做。 如果一个任务确实很大、需要很长时间,与其在一个会话里从头做到尾(中间可能压缩好几次,每次都有信息损失),不如分成几个阶段,每个阶段一个会话。会话之间通过 MEMORY.md 传递关键信息——上一节讲过,MEMORY.md 是持久化的,不受会话压缩影响。
3.5 压缩与记忆的关系
到这里可以发现,Hermes 应对"容量不够"的策略是分层的:
| 什么满了 | 怎么处理 | 信息去向 |
|---|---|---|
| MEMORY.md 满了 | 合并、删除旧条目 | 信息被精简后仍留在 MEMORY.md |
| 上下文窗口满了 | 压缩早期对话为摘要 | 摘要留在当前会话,原文丢弃 |
| 需要找回原文 | session_search 搜历史会话 | 完整对话记录存在 SQLite 里 |
三层各管各的事。MEMORY.md 保证最重要的信息跨会话存活;压缩保证当前会话能继续跑;session_search 保证即使被压缩掉了,原始对话也找得回来。
一个值得注意的点:压缩产生的摘要只存在于当前会话的上下文里,不会写入 MEMORY.md,也不会存到 session_search 的数据库中。它是一次性的——服务于当前会话的延续性,会话结束后就消失了。如果压缩摘要里有特别重要的内容,需要在会话结束前让 Hermes 记到 MEMORY.md 里。
3.6 ■ 学点英语
| 中文 | English | 音标 | 说明 |
|---|---|---|---|
| 上下文压缩 | Context Compression | /ˈkɑːntekst kəmˈpreʃən/ | 把长对话压缩成更短但保留关键信息的摘要 |
| Token 预算 | Token Budget | /ˈtoʊkən ˈbʌdʒɪt/ | 一次对话中可用于输入和输出的 token 限额 |
| 摘要压缩 | Summary Compression | /ˈsʌməri kəmˈpreʃən/ | 把长对话压缩成保留关键内容的摘要 |
| 信息保真 | Information Fidelity | /ˌɪnfərˈmeɪʃən fɪˈdeləti/ | 压缩后仍然保留原始关键信息的程度 |