“Context compression timed out before it could commit”表示 Hermes 的摘要模型——auxiliary.compression 下的模型,而不是你的主模型——在 Hermes 的压缩预算耗尽前没有取得进展,因此回合停止,主调用没有发送。这取决于版本:我们在 Hermes Agent v0.21.3 上复现了它的两条消息,并通过让摘要器响应后在同一会话中重试来恢复;而在 v0.21.5 上,同样的停滞表现为长时间等待,而不是错误。测试于 2026 年 10 月 1 日进行,针对的是两个模型的录制替身,而非真实提供商。
如果你是在为 Hermes 配置自己的端点,而不是调试它,请从使用自定义 API 的 Hermes Agent开始。
两条消息,以及每条消息告诉你的信息
| 你看到的情况 | 出现时间 | 是否发送了主调用? |
|---|---|---|
| “上下文压缩在提交结果前超时,此时请求仍约为 83,485 个 token。提供商调用未发送。运行 /compress 并等待其完成,然后重试。” | v0.21.3,摘要器无响应,请求(约 83,485 个 token)大于模型的 64,000-token 窗口 | 否 |
| “上下文压缩超时,未能缩减此对话。没有丢弃任何消息。使用 /new 开启新会话,或在重试 /compress 前检查 auxiliary.compression。” | v0.21.3,摘要器无响应,请求(约 57,489 个 token)超过 54,400-token 压缩触发值,但仍在窗口内 | 否 |
第一条消息中的 token 数字是 Hermes 对其本来会发送的请求的估计值。两个回合最终都在日志中显示为 reason=context_compression_timeout,并带有 api_calls=0,此前出现了类似“Context compression made no progress for 5.0s”的警告——之所以是五秒,是因为测试将 compression.context_timeout_seconds: 5 设得很短,以便缩短运行时间;默认值为 120。
你使用的版本决定了会发生什么
| 摘要器状态 | v0.21.3(9 月 14 日) | v0.21.5(9 月 24 日) |
|---|---|---|
| 无响应,请求在窗口内 | 回合停止——上面的第二条消息 | 等待其完成(等待 30 秒和 90 秒),将 9 条消息压缩为 5 条,并发送请求 |
| 无响应,请求超过窗口 | 回合停止——上面的第一条消息 | 未使用无响应的摘要器运行;文档通过一个非活动预算和确定性的后备摘要限定了此情况 |
| 响应错误(404) | 两次尝试,跳过压缩,发送请求(在窗口内测试) | 相同;也发送了一个超出窗口的请求,真实提供商会拒绝该请求 |
| 响应正常 | 已压缩并发送 | 已压缩并发送 |
边界条件就在源代码中。在 v0.21.4(标签 v2026.9.21)中,超时压缩后停止回合的函数被缩小为仅针对超过模型窗口的请求,并引用了 issue #113646 和 #114594;v0.21.3 会停止所有请求。随后,v0.21.5 的配置文档补充说明,压缩等待时间“被限制为 auxiliary compression request 自身的超时(auxiliary.compression.timeout,最小 300s)”——这就是为什么我们的五秒设置在那里不起作用。因此,在当前构建中,缓慢的摘要器让你等待数分钟,而不是产生错误;完全失效的摘要器则会被跳过。
最简诊断
- 检查版本:使用
hermes --version。在 v0.21.3 或更早版本中,上面的两条消息是摘要器停滞时的预期行为。 - 在
~/.hermes/logs/agent.log中找到摘要器:形如“Auxiliary compression: using <provider> (<model>) at <url>”的行会列出超时的模型和端点。如果没有auxiliary.compression块,它会继承你的主模型。 - 读取触发器行:“Pre-API compression: ~N request tokens >= T threshold (context=W)”。如果 N 大于 W,该回合在任何版本中都无法在不压缩的情况下发出。
- 检查摘要器的窗口。 Hermes 文档要求它至少与主模型一样大,因为它会收到对话的整个中间部分。
已验证的恢复方法
在上面每个 v0.21.3 案例中,使用能够响应的摘要器重启替身,并在同一会话中再发送一个回合(--resume),都会产生正常回复,且对话保持完整。实际操作中,你可以:将 auxiliary.compression 指向一个可访问的快速模型;修复它所指向的端点;或者如果摘要器运行缓慢但状态正常,则提高 compression.context_timeout_seconds——例如使用本地模型。然后在同一会话中重试。
# ~/.hermes/config.yaml — the summariser is its own model, with its own budget
auxiliary:
compression:
base_url: https://api.kunavo.com/v1 # overrides provider; any OpenAI-compatible endpoint
api_key: sk-kn-...
model: claude-haiku-4-5 # fast, and a context window >= your main model's
timeout: 300
compression:
context_timeout_seconds: 120 # inactivity budget for the summary (default)
context_total_ceiling_seconds: 600有两点未测试:Hermes Desktop 和 messaging-gateway 界面,它们有自己的卫生压缩和不同预算;以及真实提供商拒绝超出窗口的请求。运行均为一次性的 hermes chat -Q 回合。
费用
停止的回合不会发送主模型请求,因此主模型不会为此收费。摘要请求已经发送——这些运行中的提示约有 19,000 个字符——如果最终完成,提供商会对此收费。随后重试会支付一次摘要调用和一次主调用。小型、快速的摘要器可以同时降低等待时间和这部分开销;在 Kunavo 上,Claude Haiku 4.5 的价格为输入每百万 token $0.70,输出每百万 token $3.50,从预付余额中按 token 计费。Kunavo 没有人使用其端点运行过 Hermes;这里的运行使用的是本地替身。
常见问题
Hermes 中的“Context compression timed out before it could commit”是什么意思?
Hermes 在发送你的回合前尝试缩小对话;它所使用的摘要模型在其时间预算内没有取得进展,而请求过大,无法在不压缩的情况下发送——因此 Hermes 停止了该回合,完全没有调用你的主模型。在 Hermes Agent v0.21.3 中使用停滞的摘要器,并针对 64,000-token 窗口发送 83,485-token 请求时复现;该回合的日志行是 api_calls=0。问题不在你的主模型或其 API 超时设置,而在摘要器:config.yaml 中 auxiliary.compression 下的模型。
如何修复 Hermes 上下文压缩超时?
让摘要器作出响应,然后在同一会话中重试。在复现测试中,将 auxiliary.compression 指向响应正常的模型,并在同一会话中发送下一回合,在 v0.21.3 上每次都能成功,历史记录保持完整——消息本身说明没有丢弃任何消息。升级也会改变情况:从 v0.21.4 起,如果请求仍适合模型的窗口,超时的压缩不再停止请求;在 v0.21.5 中,摘要等待时间至少会被限制为摘要器请求自身的超时,且至少为 300 秒。使用 /new 开启新会话也有效,但会失去对话上下文。
Hermes 的压缩超时修复了吗?
部分修复了,而且表现形式发生了变化。在 v0.21.3(2026 年 9 月 14 日)及更早版本中,任何超时的预检压缩都会停止回合。v0.21.4(9 月 21 日)只会停止超过模型上下文窗口的请求。在 v0.21.5(9 月 24 日)中,停滞的摘要器分别等待 30 秒和 90 秒时都没有停止回合:Hermes 等待、完成压缩并发送了请求——因此在当前版本中,摘要器缓慢的表现是长时间暂停,而不是此错误。摘要器完全失效而非缓慢时则不同:它会重试,然后被跳过,回合会在未压缩的情况下继续。
提高 HERMES_API_TIMEOUT 有帮助吗?
没有。该变量控制主模型调用,默认值为 1,800 秒。压缩在 config.yaml 中有自己的预算:compression.context_timeout_seconds(非活动预算,默认 120 秒)、compression.context_total_ceiling_seconds(默认 600 秒)以及用于摘要请求本身的 auxiliary.compression.timeout。Hermes 文档还增加了一项与速度同样重要的要求:摘要模型的上下文窗口必须至少与主模型一样大,因为它会接收对话的整个中间部分。
超时的回合产生费用了吗?
Not on the main model: the turn ended before the main call was sent. The summary request was sent, though, and a summariser that eventually finishes is billed by its provider like any other call — in the runs here the summary prompt was about 19,000 characters. The retry then pays for one summary and one main call. That is why pointing compression at a small, fast model is cheaper as well as quicker: on Kunavo, Claude Haiku 4.5 lists at $0.70 per million input tokens.
2026 年 10 月 1 日复现,使用从各自发布源安装的 Hermes Agent v0.21.3(标签 v2026.9.14)和 v0.21.5(标签 v2026.9.24),并针对同时充当主模型和摘要模型的本地记录用替身运行(通过暂不返回响应来模拟停滞的摘要器,通过返回 404 来模拟失效的摘要器),上下文窗口为 64,000 个 token,测试回合前有四个恢复执行的填充回合。版本边界来自 v2026.9.14、v2026.9.21 和 v2026.9.24 标签中的 agent/turn_context.py;预算来自每个标签的配置文档。该替身不是模型或提供商:它接受任意大小的请求,因此没有复现提供商侧的上下文错误。