Hacker News 中文摘要

RSS订阅

Show HN: Claude-thermos 为你的 Claude 会话保温 -- Show HN: Claude-thermos keeps your Claude session warm for you

文章摘要

Claude Code的提示缓存每5分钟过期,导致主代理等待子代理时需重新编码整个对话,增加约20%费用。claude-thermos工具可在后台自动保持缓存活跃,避免这笔开销。用户只需通过uvx运行该工具,无需改变原有使用方式,并可调整闲置时间、循环周期等参数。

文章总结

停止为重建Claude Code缓存付费。当主代理等待子代理超过5分钟时,其提示缓存会静默过期,下一轮交互将以写入费率重新编码整个对话历史,而非以低成本读取缓存。在涉及多个子代理的长时间会话中,这大约会占据账单的20%。claude-thermos能保持缓存活跃,让你无需支付这笔额外费用。

使用方法

像往常一样运行Claude Code,但通过uvx使用claude-thermos:

uvx claude-thermos # 替代:claude uvx claude-thermos -p "修复这个bug" # 任何claude参数都会直接传递

需要Python 3.11+,且PATH中包含claude CLI。

就这样。预热会在后台自动运行。如需在单次运行中禁用而不更改命令,可设置CLAUDEWARMERDISABLE=1。

调优参数(均为可选):

| 标志 | 默认值 | 含义 | |------|--------|------| | --idle | 270 | 主代理空闲后触发预热的等待秒数 | | --interval | 270 | 预热周期之间的间隔秒数 | | --max-cycles | 4 | 每个空闲阶段的最大预热次数(设为auto表示无限制) | | --subagent-window | 540 | 子代理被视为“仍活跃”的秒数 |

缓存为何持续过期

Claude Code的提示缓存使用5分钟TTL。只要缓存保持活跃,每轮交互中整个对话历史都会以输入价格0.1倍的费率从缓存读取,而非以全价重新发送。如果同一前缀的请求间隔超过5分钟,缓存就会过期。造成这种间隔的主要原因并非你的思考时间,而是主代理被运行超过5分钟的子代理阻塞。子代理拥有不同的系统提示和工具集,其请求使用不同的缓存前缀,因此不会刷新主代理的缓存。在子代理运行期间,主代理的缓存历史未被触及;超过5分钟后便会消失。当子代理返回时,主代理恢复执行,其历史记录字节相同且仅追加,但发现缓存已丢失,被迫以1.25倍的写入费率进行完整重新编码。

此时历史记录已相当庞大,重新编码成本高昂:单次重建需重写20万至50万个token。在约185次本地会话中测量发现,这些重建占总账单的约22%,这些费用本应用于重新编码片刻前还存在于缓存中的内容。

工作原理

claude-thermos通过小型本地反向代理启动Claude Code(它将ANTHROPICBASEURL指向回环端口;所有流量仍会发送至真实的Anthropic API)。

观察:代理监控/v1/messages流量,将其分组为会话和谱系(谱系即一个缓存前缀,由模型+工具集+系统文本标识)。首个包含工具的谱系为主代理,其余为子代理。检测危险窗口:当主谱系空闲且子代理正在运行时,主前缀面临过期风险。预热:在5分钟TTL内按间隔执行,重放主代理的最后一次真实请求作为预热请求:使用相同的可缓存前缀,但设置max_tokens: 1且不启用流式传输。单个token会被丢弃;关键在于预填充,它读取并刷新完整的缓存前缀。预热请求直接发送至API,不经过代理,因此不会干扰真实流量。结果:当子代理完成时,主代理的缓存仍保持活跃。它只需支付廉价的读取费用,而非完整的重写成本。

每次预热消耗一次缓存读取(0.1倍费率);每次它防止的重写本应消耗一次写入(1.25倍费率),且针对更大的前缀,因此这种权衡对你极为有利。

事件日志与节省

每次会话会写入:

~/.claude-thermos/logs// ├── events.jsonl # 仅追加的结构化事件流 └── summary.json # 汇总数据,会话结束时写入

events.jsonl记录每个请求/响应的token使用情况以及所有预热决策(如warmfired、warmresult、capreached、resumedetected等)。summary.json是你通常查看的汇总数据:

| 字段 | 含义 | |------|------| | warmsfired | 发送的预热请求数 | | cachereadtotal | 这些预热读取的token总数 | | episodes | 以成功恢复结束的空闲-子代理阶段(实际避免的重写次数) | | rewriteavoidedtokens | 各阶段本应重写的token总数 | | warmcost | 预热成本:0.1 × cachereadtotal | | rewriteavoidedcost | 节省的成本:1.25 × rewriteavoidedtokens | | netsavings | rewriteavoidedcost − warmcost |

所有三个成本数字均以基础输入token为单位(token数已按缓存乘数加权)。要将net_savings转换为美元,请乘以模型每输入token的价格:

节省的美元 ≈ net_savings × (输入token价格)

评论总结

根据评论内容,总结如下:

主要观点与论据:

  1. 缓存过期时间争议(核心焦点):

    • 多数用户认为缓存过期时间应为1小时,而非5分钟。评论2、12、14、15均指出官方文档显示Pro/Max计划为1小时,评论4证实当前API可自选5分钟或1小时。
    • 部分用户批评5分钟过短,如评论10认为“5分钟太低,甚至可能因选择回复而错过”,评论11表示“5分钟太慢,有时需要超过5分钟查看差异后再决定下一步”。
  2. 对缓存刷新机制的不满

    • 评论11指出“听到一个字节就刷新整个缓存”的做法过于激进,认为应允许更长的闲置时间。
    • 评论9提出代理会话(如Fable)中,长时间ML训练后返回结果时会产生昂贵缓存命中,建议自动保持主线程活跃。
  3. 成本与公平性担忧

    • 评论5质疑“我们不是为缓存输入付费吗?”,暗示缓存刷新可能增加成本。
    • 评论7担心“这会导致公地悲剧吗?”,评论8认为“这只会让其他人更贵”,主张让服务商自行优化。
  4. 对工具改进的期待

    • 评论3认为“如果能以可接受的方式管理,这是个好主意”,建议设置每日缓存延迟次数。
    • 评论6表示“很高兴这个存在,会迫使Anthropic修复有缺陷的缓存机制”。
    • 评论11希望“这种功能能内置到Claude Code中”。

平衡性总结: - 支持方:认为缓存刷新机制能推动改进(评论6),或通过自动化保持会话活跃可避免成本(评论9)。 - 反对方:批评5分钟过期时间不合理(评论10、11),担忧成本增加和公平性(评论5、7、8),并指出官方实际为1小时(评论14、15)。 - 中立建议:评论3提出折中方案(每日有限次缓存延迟),评论16建议检测当前模式(5分钟或1小时)再决定刷新策略。

关键引用(保留中英文): - “5 is just too low, you can even miss it by taking time to select a response from a question.”(评论10) - “Hearing one byte refreshes the whole thing is huge! 5min is wayy too slow...”(评论11) - “on Pro and Max plans caching lasts for one hour, not five minutes”(评论14) - “This is just making it more expensive for everyone else, right?”(评论8)