本文へスキップ
郭立 (leeguoo)

ステータスバーのあの cache 4m23s は、結局正確なのか?

私が Claude Code 向けに書いたステータスバーには、prompt-cache のカウントダウン行がある。それが何を基準にしているのか、式はどう立てるのか、どんなときに誤解させるのか——ソースコードと実際の transcript を一緒に掘り下げる。

このページの目次
1.まず 2 つの「cache」を{区別|くべつ}しよう。{混同|こんどう}しない2.どこを{基準|きじゅん}にしているか3.Anthropic の{実際|じっさい}の{挙動|きょどう}をちゃんとモデル{化|か}できているか4.どこが{不正確|ふせいかく}か——{証拠|しょうこ}を{出|だ}す5.1. デフォルト TTL が 5 {分|ふん}で{固定|こてい}されているが、あなたは 1 {時間|じかん}キャッシュで{動|うご}いているかもしれない6.2. アンカーは「1 ラウンドの{終了|しゅうりょう}」であって、「キャッシュが{更新|こうしん}されたその{瞬間|しゅんかん}」ではない7.3. {色|いろ}は{数値|すうち}ではなく{文字列|もじれつ}を{見|み}て{推測|すいそく}している8.それで、{正確|せいかく}なのか

私が Claude Code 向けに書いた状態じょうたいバー cs / claude-statusbar には、cache 4m23s という行ぎょうがある。緑色みどりいろで、毎秒まいびょうカウントダウンし、終おわりまで進すすむと赤色あかいろの cache COLD になる。

ある人ひとに聞きかれた。この数字すうじは結局けっきょくどう計算けいさんしているのか、正確せいかくなのか?

聞きく価値かちのある質問しつもんだ。Pro / Max の契約けいやくユーザーにとって、キャッシュがヒットしたとき、その部分ぶぶんの context は基本的きほんてきに 5h / 7d の上限じょうげんをほとんど消費しょうひしない。冷さましてしまうと、次つぎの prompt では全体ぜんたいのコンテキストを定価ていかで最初さいしょから再投入さいとうにゅうすることになる。だから「あと何分なんぷん」というこの一行いちぎょうは、「今いま、熱あついうちにもう一通いっつう送おくるべきか」を決きめるものだ。以下いかでそれを分解ぶんかいしつつ、正確せいかくなのかにも答こたえる。

急いそいでいる人ひと向けに一言ひとことでいうと、標準設定ひょうじゅんせってい、5 分ふんキャッシュでは正確せいかくだ。ただし、体系的たいけいてきに誤あやまって見みせる唯一ゆいいつのケースは、1 時間じかんキャッシュを有効ゆうこうにしているのに TTL を変更へんこうしていないとき——この場合ばあいは 55 分ふん早はやく通知つうちする。 一行いちぎょうの設定せっていで直なおせる。理由りゆうは下したで説明せつめいする。

まず 2 つの「cache」を区別くべつしよう。混同こんどうしない

このリポジトリには cache と呼よばれるものが 2 つある。「正確せいかくかどうか」を問とう前まえに、どちらのことを聞きいているのかを確認かくにんする必要ひつようがある。

  • データキャッシュ:cache.py の CACHE_MAX_AGE_S = 30。claude-monitor の出力しゅつりょくを 30 秒びょうキャッシュするものだ。これは純粋じゅんすいに、ステータスバーが毎秒まいびょう再描画さいびょうがされるたびに、毎回まいかいサブプロセスを shell で叩たたかなくてすむようにするためのもの。 「残のこり時間じかんは正確せいかくか」とは関係かんけいない。
  • prompt-cache の残のこり時間じかん:今日きょうの主役しゅやく。これは「Anthropic のプロンプトキャッシュがあとどれくらいで期限切きげんぎれになるか」を計算けいさんしている。

以下いかでは 2 つ目めだけを扱あつかう。

どこを基準きじゅんにしているか

ロジックはかなり短みじかく、関数は 1 つだけ、get_cache_age_text だ。やっていることは 3 つ。

  1. ~/.cache/claude-statusbar/last_stdin.json を読よみ、現在げんざいのセッションの transcript_path を取とる。
  2. この JSONL を後うしろから読よみ、直近ちょっきんの type == "assistant" のレコードを探さがし、その timestamp を取とる。
  3. remaining = ttl_seconds - <ruby>経過<rt>けいか</rt></ruby>した<ruby>秒数<rt>びょうすう</rt></ruby> として、カウントダウンの形かたちにフォーマットする。

2 番目ばんめは _last_assistant_age で、要点ようてんはこの 1 行ぎょうだけ。

python
if entry.get("type") != "assistant":
    continue
...
return (datetime.now(timezone.utc) - last_ts).total_seconds()

基準点きじゅんてんに注意ちゅうい:直近ちょっきんの assistant メッセージのタイムスタンプ——ユーザーメッセージでもなく、ファイルの mtime でもない。この選択せんたくは正ただしい。なぜかは次つぎの節せつで説明せつめいする。

式しきも同おなじく素直すなおだ。

python
remaining = ttl_seconds - age_s
if remaining <= 0:
    return "COLD"

ttl_seconds はデフォルトで 300。remaining <= 0、またはそもそも assistant レコードが見みつからない(age_s is None)場合ばあいは、どちらも COLD を返かえす。transcript_path すらない場合ばあいは空文字列からもじれつを返かえし、この表示ひょうじブロック全体ぜんたいが隠かくれる。

ついでに歴史れきしを少すこし:v3.2.2 のこの PR より前まえは、この行ぎょうが「どれくらい経過けいかしたか」(elapsed)を表示ひょうじしていたが、あとでカウントダウン(countdown)に変かわった。ユーザーが本当ほんとうに知しりたいのは「前回ぜんかいの回答かいとうから何分なんぷん経たったか」ではなく、「キャッシュが死しぬ前まえに、まだもう 1 通つう送おくる時間じかんがあるか」だからだ——カウントダウンなら直接ちょくせつ答こたえてくれるし、elapsed だと自分じぶんで頭あたまの中なかで引ひき算ざんしなければならない。

Anthropic の実際じっさいの挙動きょどうをちゃんとモデル化かできているか

公式こうしきドキュメント Prompt caching を見みると、方向ほうこうを決きめる文ぶんが 2 つある:

By default, the cache has a 5-minute lifetime.

The cache is refreshed for no additional cost each time the cached content is used.

つまり、TTL はスライディングウィンドウだ。ヒットするたびに 5 分ふんへリセットされる。

これは、「直近ちょっきんの 1 回かいの assistant をアンカーにする」のがなぜ正ただしいかをちょうど説明せつめいしている——1 回かい回答かいとうが増ふえるたびに、age_s はゼロから数かぞえ直なおしになり、カウントダウンは自動じどうで満まんタンまで延長えんちょうされ、サーバー側がわの「1 回かい使つかうたびに 1 回かい延長えんちょう」という挙動きょどうと一致いっちする。コード内ないのあのコメント # 5min — Anthropic's default prompt cache TTL は間違まちがっていない。この層そうでは、モデル化かはちゃんと合あっている。

どこが不正確ふせいかくか——証拠しょうこを出だす

ここからが本題ほんだい。3 つの層そうを、いちばん刺ささるものから、いちばんどうでもいいものへ並ならべる。

1. デフォルト TTL が 5 分ふんで固定こていされているが、あなたは 1 時間じかんキャッシュで動うごいているかもしれない

ここだけが、本当に人ひとをだますところ。証拠しょうこは、手元てもとの直近ちょっきん assistant レコードの usage ブロックから:

json
"cache_creation": {
  "ephemeral_1h_input_tokens": 1421,
  "ephemeral_5m_input_tokens": 0
}

全部ぜんぶ 1 時間じかんバケットに入はいっている。つまりこのマシンで実際じっさいに走はしっているのは 1h キャッシュで、本当ほんとうの生存時間せいぞんじかんは 60 分ぷん。でも cs のデフォルトは cache_ttl_seconds = 300 なので、5 分ふん後ごには cache COLD と叫さけぶ——真実しんじつより 55 分ふんも早はやい。

いちばん皮肉ひにくなのは、5m か 1h かを判定はんていする「真実しんじつのシグナル」(ephemeral_1h_input_tokens vs ephemeral_5m_input_tokens)が、ツールがすでに開ひらいている同おなじファイル、同おなじレコードの中なかに転ころがっていることだ。なのに _last_assistant_age は type と timestamp の 2 フィールドだけを読よみ、その usage ブロックをそのまま素通すどおりしている。理論上りろんじょうは transcript からどの TTL を使つかうべきか自動判定じどうはんていできるのに、今いまは手動しゅどうで cs config set cache_ttl_seconds 3600 する必要ひつようがある。これは埋うめるべき TODO だ。

2. アンカーは「1 ラウンドの終了しゅうりょう」であって、「キャッシュが更新こうしんされたその瞬間しゅんかん」ではない

assistant の timestamp は、おおむねそのラウンドを**書かき終おえた**時刻じこくだ。一方、キャッシュはリクエストが**送信そうしんされた**瞬間しゅんかんにサーバー側がわで更新こうしんされる。その間あいだには生成遅延せいせいちえんがある。実際じっさいの transcript にある、同おなじ会話かいわセグメントの assistant タイムスタンプを見みると:

text
assistant  2026-05-29T04:46:18.432Z
assistant  2026-05-29T04:46:19.653Z
assistant  2026-05-29T04:46:25.680Z

数秒すうびょうから十数秒じゅうすうびょうのオーダー。300s / 3600s の TTL と比くらべれば、無視むしできる。方向ほうこうとしてはたぶん楽観寄らっかんより(表示ひょうじされる残のこりが、実際じっさいのサーバー側がわより少すこし多おおい)だが、人ひとを噛かむほどではない。

ここは正直しょうじきに言いうと、源码ソースコードだけでは Anthropic サーバー側がわがリクエスト開始かいしから数かぞえるのか、終了しゅうりょうから数かぞえるのかは証明しょうめいできない。だから正確せいかくな言いい方かたは——**アンカーは「1 ラウンドの遅延ちえん精度せいど」の代理値だいりち**であって、キャッシュ更新こうしんの正確せいかくな瞬間しゅんかんではない。実用じつようには十分じゅうぶん。でもストップウォッチだとは思おもわないほうがいい。

3. 色いろは数値すうちではなく文字列もじれつを見みて推測すいそくしている

おもしろい工学上こうがくじょうの割わり切きり。_cache_severity は残のこり秒数びょうすうを受うけ取とらず、**すでにフォーマット済ずみの文字列もじれつ**を受うけ取とり、その中なかに m / h があるかを見みる:

python
if cache_text == "COLD":
    return theme.s_hot          # 赤
if "m" in cache_text or "h" in cache_text:
    return theme.s_ok           # 緑、快適ゾーン
return theme.s_warn             # 黄、純粋な "Ys"、1 分未満

1 分ぷん未満みまんのとき、formatter はわざと m なしの裸はだかの Ys だけを出力しゅつりょくする。colorizer が「そろそろ黄きにする時間じかんだ」と検出けんしゅつできるようにするためだ。formatter と colorizer の間あいだには暗黙あんもくの契約けいやくがある。リポジトリには、この契約けいやくを固定こていする test_cache_severity.py がわざわざあり、いつかフォーマットを変かえたときに色いろがこっそり混線こんせんしないようにしている。使つかえるが、たしかに結合けつごうではある——知しっておく価値かちはある。

もうひとつ端はしの話はなし:transcript の逆読ぎゃくよみには 320KB の上限じょうげん(10×32KB) がある。巨大きょだいな transcript で、末尾まつび 320KB に assistant が見みつからなければ、そのまま COLD 扱あつかいになる。これは性能上せいのうじょうの割わり切きりだ——ステータスバーは毎秒まいびょう再描画さいびょうがされるので、毎回まいかい 数 MB を走査そうさするわけにはいかない。日常にちじょうではまず踏ふまない。

それで、正確せいかくなのか

  • 5 分ふんキャッシュ + デフォルト設定せってい:正確せいかく。アンカーは正ただしいし、スライディングウィンドウのモデリングも正ただしい。境界きょうかいケース(時計とけいの巻まき戻もどりは 0 にクランプ、naive タイムスタンプは UTC 扱あつかい、Z 接尾辞せつびじの正規化せいきか)も処理しょりされている。
  • 1 時間じかんキャッシュ + TTL 未変更みへんこう:構造的こうぞうてきに 55 分ふん早はやく報告ほうこくする。cs config set cache_ttl_seconds 3600 の 1 行ぎょうで直なおせる。
  • 秒単位びょうたんいの精度せいど:期待きたいしないこと。アンカー自体じたいに 1 ラウンド分ぶんの遅延ちえんという代理誤差だいりごさがある。これは「あと何分なんぷん残のこっているか」級きゅうのヒントであって、計時器けいじきではない。

一言ひとことでまとめると、これは「キャッシュがまだ熱あついうちに、いまもう 1 発ぱつ投なげるべきか」に答こたえるものだ。この問といにはかなり正確せいかくに答こたえる。ストップウォッチとして使つかうなら、それは道具どうぐを間違まちがえている。

自分じぶんで見みるなら、_last_assistant_age と get_cache_age_text の 2 つの関数かんすうから入はいるといい。30 行ぎょうほどで読よみ終おわる。

同じカテゴリの記事 · AI & Agent

← 前の記事
Claude Code Workflows 詳細解析:オーケストレーションをスクリプトに書き込んだ後
次の記事 →
東京通勤圏の住宅購入候補リスト

コメント

コメントは即時公開されますが、ポリシー違反時は非表示になる場合があります。

最大 1000 文字。