このブログの作業に使っているClaude Codeの会話ログを、1か月分集計しました。モデルに送ったトークンの96.85%は、キャッシュからの読み取りでした。ところが公式の単価で金額にすると、読み取りは費用の38%にすぎません。いちばん大きかったのは、キャッシュへの書き込みで42%でした。
OpenAIとAnthropicはこの数か月でAPI料金を大きく下げ、特にキャッシュ読み取りの単価を削ってきました。その結果、Claude Codeのようなエージェントの費用を左右するのは、読み取りより書き込みのほうになっています。APIキーで使うなら、キャッシュの保持時間(TTL)とモデルの選び方で、同じ作業でも費用が2割以上変わります。
以下、ログの数字、5分TTLだった場合の試算、モデルごとの比較を順に示します。最後に、自分のログで同じことを確かめるスクリプトを載せました。
値下げの中心は、キャッシュ読み取りの単価だった
Max Woolf氏は、10月25日のエッセイで、両社が数か月で料金を最大80%下げた経緯をたどっています。そのうえで、エージェントでのコーディングではトークンへの支出の96〜99%がキャッシュ読み取りであり、読み取り単価の引き下げこそが効いていると論じました。ただし、この比率をどう測ったかは書かれていません。
確かに、読み取りの単価は大きく下がっています。Claudeの料金表では、Opus 5の読み取りは100万トークンあたり0.50ドル(入力単価の0.1倍)でした。Opus 5.5では0.20ドルと、入力単価の0.05倍です。Fable 5.1は入力単価10ドルと高価ですが、読み取りは0.025倍の0.25ドルで、Opus 5.5とほとんど変わりません。
一方で、書き込みの倍率は変わっていません。5分TTLの書き込みは入力単価の1.25倍、1時間TTLは2倍です。Opus 5.5なら1時間の書き込みは100万トークンあたり8ドルで、読み取り0.20ドルの40倍です。書き込み1トークンが、読み取り40トークンと同じ値段になります。
1か月分のログでは、トークンの97%が読み取り、費用の最大は書き込み
集計したのは、私のMacに残っていたClaude Codeの会話ログです。期間は9月24日〜10月25日、95の会話系列で7,361リクエスト、モデルはOpus 5.5です(別モデルの1件は除外)。用途は、このブログの調査・執筆・投稿とスクリプトの保守です。読んだのは各リクエストのトークン数の欄だけで、会話の中身は見ていません。
私はサブスクリプションで使っているので、この金額を実際に払ったわけではありません。同じトークンをAPIの定価で払った場合の換算です。
| 区分 | トークンの割合 | 金額(Opus 5.5単価) | 費用の割合 |
|---|---|---|---|
| キャッシュ読み取り | 96.85% | 320.10ドル | 38.3% |
| 1時間キャッシュ書き込み | 2.63% | 348.09ドル | 41.7% |
| 出力 | 0.50% | 165.07ドル | 19.8% |
| 5分キャッシュ書き込み・通常入力 | 0.02% | 1.50ドル | 0.2% |
| 合計 | 16.5億トークン | 834.77ドル | 100% |
トークンの比率は、Woolf氏の言う96〜99%の範囲に収まりました。キャッシュに当たった割合も97.3%です。違うのは金額のほうで、トークンでは2.63%しかない1時間の書き込みが、費用ではいちばん大きくなりました。
同じ趣旨の集計は、Qiitaにも9月の1か月分などがあり、そちらでは読み取りが費用の55%前後を占めています。私の数字と違うのは、使った単価の違いでほぼ説明できます。私の同じトークン列にOpus 5の単価を当てはめると、読み取りは55.4%、合計は1,443.59ドルになりました。Opus 5.5にすると合計は42.2%下がります。下がり幅のほとんどは読み取りで、その分、書き込みの比重が上がったわけです。
同じ使い方で5分TTLにすると、24.5%高くなる計算
私の書き込みのほとんどが1時間TTLなのは、Claude Codeの既定によるものです。Claude Codeの公式説明によると、サブスクリプションの範囲内で使う場合は、会話本体に1時間TTLを使います。APIキー、クラウド経由、サブスクリプションの利用クレジットでは5分です。サブエージェントは、サブスクリプションでも5分です。
では、私の使い方が5分TTLだったら、いくらになっていたか。同じ会話のなかで前のリクエストから5分以上あいた回数を数えると、351回ありました。調べ物を読んだり、原稿を見直したりしている間に5分は簡単に過ぎます。5分を超えた回は、キャッシュが切れて会話全体を書き込み直したとみなして計算しました。
- 記録どおり(ほぼ1時間TTL):834.77ドル
- 5分TTLと仮定:1,039.57ドル(24.5%増)
5分TTLでは書き込み単価が1.25倍に下がりますが、351回の書き直しで約7,000万トークンが読み取りから書き込みに移り、差し引きで高くなりました。逆に、手を止めずに5分以内で次々と指示を出す使い方なら、5分TTLのほうが安くなります。どちらが得かは、休止の頻度で決まります。
APIキーで使っていて、作業の合間に手を止めることが多い人は、settings.jsonで会話本体のTTLを1時間に変えられます(Claude Code v2.1.242以降)。
{
"promptCacheTtl": "1h"
}
サブエージェント側はsubagentPromptCacheTtlで別に指定します。この試算は、5分を超えたら会話全体を書き直すという単純な前提によるもので、実際のClaude Codeの細かい動き(休止中の自動要約など)は反映していません。
モデルは、読み取りと書き込みの単価で比べる
同じトークン列に、ほかのモデルの公式単価を当てはめるとこうなります。Claudeは記録どおりのTTL、GPT-6.1 SolはOpenAIの既定である30分TTL(書き込みは入力単価の1.25倍)として計算しました。
- Fable 5.1:1,686.80ドル(Opus 5.5の2.02倍)
- Opus 5.5:834.77ドル
- Sonnet 5.5:417.39ドル(Opus 5.5のちょうど半分)
- GPT-6.1 Sol:372.33ドル
Fable 5.1は、入力・出力の定価がOpus 5.5の2.5倍です。それでもこの使い方では2.02倍に収まりました。読み取りの単価がほぼ同じだからです。会話が長く、読み取りの比重が大きい作業ほど差は縮み、出力の多い作業ほど2.5倍に近づきます。
GPT-6.1 Solは、OpenAIの料金表で入力2ドル・読み取り0.10ドル・出力10ドルと、定価はSonnet 5.5と同じです。それでも安く出たのは、30分TTLのおかげです。30分を超える休止は138回で5分超の半分以下になり、書き込みも1.25倍で済みます。
この比較は、どのモデルでも同じトークン数・同じ出力量になると仮定した、単価だけの比較です。実際には、モデルによって出力の量が違い、OpenAIはトークンの数え方も違います。品質の比較でもありません。それでも、料金表を見るときは入力と出力の単価より、読み取りと書き込みの単価、そして既定のTTLを先に見るべきだと私は考えています。
自分のログで割合を確かめるスクリプト
Claude Codeの会話ログは、ホームフォルダの.claude/projectsにJSONL形式で残っています。次のPythonスクリプトは、その中のトークン数の欄だけを集計し、Opus 5.5の単価で金額の内訳と、5分・1時間を超えた休止の回数を表示します。追加のパッケージは不要です。
import json
from datetime import datetime
from pathlib import Path
PRICE = {"input": 4, "write_5m": 5, "write_1h": 8, "read": 0.20, "output": 20} # Opus 5.5、米ドル/100万トークン
total = dict.fromkeys(PRICE, 0)
times, seen = {}, set()
for path in (Path.home() / ".claude" / "projects").rglob("*.jsonl"):
for line in path.open(encoding="utf-8", errors="ignore"):
try:
d = json.loads(line)
except json.JSONDecodeError:
continue
u = (d.get("message") or {}).get("usage")
if not u or d.get("requestId") in seen:
continue
seen.add(d.get("requestId"))
cc = u.get("cache_creation") or {}
total["input"] += u.get("input_tokens", 0)
total["write_5m"] += cc.get("ephemeral_5m_input_tokens", 0)
total["write_1h"] += cc.get("ephemeral_1h_input_tokens", 0)
total["read"] += u.get("cache_read_input_tokens", 0)
total["output"] += u.get("output_tokens", 0)
times.setdefault(d.get("sessionId"), []).append(datetime.fromisoformat(d["timestamp"].replace("Z", "+00:00")))
cost = {k: total[k] * PRICE[k] / 1_000_000 for k in PRICE}
tokens, dollars = sum(total.values()), sum(cost.values())
for k in PRICE:
print(f"{k:9} {total[k]:>14,} tok {total[k] / tokens:6.1%} ${cost[k]:>9,.2f} {cost[k] / dollars:6.1%}")
gaps = [(b - a).total_seconds() for ts in times.values() for a, b in zip(sorted(ts), sorted(ts)[1:])]
print(f"requests {len(seen):,} 5分超の間隔 {sum(g > 300 for g in gaps)}回 1時間超 {sum(g > 3600 for g in gaps)}回")
私の環境で10月26日に実行すると、1時間の書き込みが41.8%、読み取りが38.3%、5分を超えた休止が354回と出ました。期間をそろえた上の表とは少しずれますが、傾向は同じです。Sonnet 5.5で使っているなら、PRICEの数字を料金表の値に書き換えてください。
ログは既定で30日たつと消えるので、集計できるのは最近1か月ほどです。今の会話だけなら、Claude Codeで/usageを開くと「Prompt cache (main)」の行に、キャッシュから読んだ割合と、キャッシュが切れた回数が出ます(v2.1.251以降)。
書き込みが増えるのは、キャッシュが切れたとき
書き込みは、新しく足した部分だけなら小さく済みます。大きくなるのは、キャッシュが切れて会話全体を書き直すときです。5分TTLの試算で費用が増えたのも、休止のたびにこの書き直しが起きるためでした。
休止のほかにも、キャッシュが切れる操作があります。公式の説明では、会話の途中でモデルを切り替える、fast modeを切り替える、会話を要約する(compact)、Claude Codeを更新して起動し直す、といった操作です。モデルは会話の最初に決めて途中で替えない、要約は作業の区切りで行う。この2つだけでも書き込みは減らせます。
値下げのニュースは入力と出力の単価で語られがちですが、エージェントの費用を決めるのは、読み取りと書き込みの単価、そしてTTLです。モデルを比べるときの考え方は、Kimi K3.1 ProとClaude Sonnet 5.5の比較でも、1タスクあたりの実費で整理しています。まずは上のスクリプトで、自分の費用のうち書き込みが何割かを見てみてください。4割を超えていて、5分を超える休止が多いなら、TTLを見直す価値があります。

コメント