プログラミング
Show HN: Claude-thermos – あなたのClaudeセッションを暖かく保ちます
Show HN: Claude-thermos – keeps your Claude session warm for you (github.com)
要約
Claude-thermosは、AnthropicのClaude Codeセッションにおけるプロンプトキャッシュの無駄な再エンコードを防ぐためのツールです。Claude Codeでは、5分間アイドル状態が続くとキャッシュが失われ、長いセッションやサブエージェントの利用時に高額な再エンコード料金が発生します。Claude-thermosはこのキャッシュをバックグラウンドで定期的に「ウォームアップ」することで、キャッシュの有効期限切れを防ぎ、コストを約20%削減します。
全文翻訳
claude-thermos Claude Codeのキャッシュ再構築に料金を支払うのをやめましょう。メインエージェントがサブエージェントを5分以上待機すると、プロンプトキャッシュはサイレントに期限切れになり、次のターンで会話全体を書き直す代わりに安価に読み込むのではなく、書き直すことになります。多くのサブエージェントを伴う長いセッションでは、これは請求額の約20%に相当します。claude-thermosはキャッシュをウォームに保つため、その税金を支払う必要がなくなります。uvx: uvx claude-thermos を使用して、通常通りClaude Codeを実行してください。# 代わりに: uvx claude claude-thermos -p "バグを修正" # 任意のclaude引数はそのまま渡されます Python 3.11+ とPATH上のclaude CLIが必要です。それだけです。ウォームアップはバックグラウンドで自動的に実行されます。コマンドを変更せずに実行を無効にするには、CLAUDE_WARMER_DISABLE=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万トークンを書き直します。約185のローカルセッションで測定したところ、これらの再構築は総請求額の約22%を占め、数分前にすでにキャッシュされていたコンテンツを再エンコードするために費やされたお金でした。仕組み claude-thermosは、小さなローカルリバースプロキシの背後でClaude Codeを起動します(ANTHROPIC_BASE_URLをループバックポートに向けます。すべてのトラフィックは引き続き実際のAnthropic APIに送信されます)。観察します。プロキシは /v1/messages トラフィックを監視し、セッションとリネージにグループ化します。リネージとは、モデル + ツールセット + システムテキストでキー付けされた1つのキャッシュプレフィックスです。最初のツール搭載リネージがメインエージェントであり、残りはサブエージェントです。危険なウィンドウを検出します。メインリネージがアイドル状態になり、サブエージェントがアクティブに実行されている場合、メインプレフィックスは期限切れのリスクにさらされます。ウォームアップします。5分間のTTLの下で、間隔をおいて、ウォームリクエストとしてメインエージェントの最後の実際のリクエストを再生します。これは、キャッシュ可能なプレフィックスは同一ですが、max_tokens: 1 でストリーミングはありません。単一のトークンは破棄されます。ポイントはプリフィルであり、完全なキャッシュされたプレフィックスを読み取り、リフレッシュすることです。ウォームリクエストはプロキシを経由せず、直接APIに送信されるため、実際のトラフィックを妨害することはありません。結果。サブエージェントが終了すると、メインエージェントのキャッシュはまだウォームです。それは完全な書き直しではなく、安価な読み込みを支払います。各ウォームはキャッシュ読み込み(0.1倍)を必要とし、それを防いだ各書き直しは、はるかに大きなプレフィックスで書き込み(1.25倍)を必要としたため、この取引はあなたに大きく有利です。イベントログと節約額 各セッションは以下に書き込みます: ~/.claude-thermos/logs/<session_id>/ ├── events.jsonl # 追記のみの構造化イベントストリーム └── summary.json # セッション終了時に書き込まれるロールアップ合計 events.jsonl は、各リクエスト/レスポンスのトークン使用量と、ウォームアップの決定(warm_fired, warm_result, cap_reached, resume_detected など)を記録します。summary.json は、通常読み取るロールアップです: フィールド 意味 warms_fired 送信されたウォームリクエスト cache_read_total それらのウォームによって読み込まれたトークン episodes_idle_with_subagent 成功した再開(実際に回避された書き直し)で終了したアイドルサブエージェントエピソード rewrite_avoided_tokens 書き直されたであろうトークン、エピソード全体で合計 warm_cost ウォームアップにかかった費用:0.1 × cache_read_total rewrite_avoided_cost それが節約した費用:1.25 × rewrite_avoided_tokens net_savings rewrite_avoided_cost − warm_cost すべての3つの費用は、ベース入力トークン単位(トークン数はすでにキャッシュ乗数で重み付けされています)です。net_savings をドルに変換するには、モデルの入力トークンあたりの価格を掛けます: 節約されたドル ≈ net_savings × (入力トークン単価) 例えば、入力価格が100万トークンあたり3ドルの場合、1,200,000のnet_savingsは約1,200,000 × 3ドル / 1,000,000 = 3.60ドルの節約になります。