仕上げは AI との協働でやっています。事実と表現は著者本人が確認しています。
Claude Codeを使っていると、APIの利用明細に cache_creation_input_tokens と cache_read_input_tokens という見慣れない項目が出てくる。「なんとなく高い気がする」と思いつつも、何が何トークン消費されているのか分からないまま使っている人は多いのではないだろうか。
この記事では、VSCode拡張・VSCode内ターミナルCLI・subagentという3つの環境で実際に計測し、それぞれの挙動の違いと、コスト構造の実態を整理する。
まず:cache_createとcache_readとは何か
Claude Codeは起動のたびに、システムプロンプト(CLAUDE.md・フックの注入内容など)をAnthropicのサーバーに送信する。このとき:
- cache_create:サーバーにまだキャッシュされていない内容を新規作成するコスト
- cache_read:既にキャッシュ済みの内容を読み出すコスト(通常inputの約1/10の料金)
つまり cache_read が大きいほど「安く済んでいる」状態だ。
計測方法
Claude CodeはセッションのJSONLログを ~/.claude/projects/<プロジェクトパス>/ に保存している。各ターンのusageが記録されているため、以下のスクリプトで計測できる。
#!/usr/bin/env python3
import json, os
from pathlib import Path
project_key = os.getcwd().replace("/", "-")
project_dir = Path.home() / ".claude/projects" / project_key
jsonl_files = sorted(project_dir.glob("*.jsonl"), key=lambda f: f.stat().st_mtime, reverse=True)
jsonl_path = jsonl_files[0]
turn = 0
for line in jsonl_path.read_text().splitlines():
try:
e = json.loads(line)
usage = e.get("message", {}).get("usage", {})
role = e.get("message", {}).get("role", "")
if usage and role == "assistant":
turn += 1
print(f"turn {turn}: input={usage.get('input_tokens',0)} cache_create={usage.get('cache_creation_input_tokens',0)} cache_read={usage.get('cache_read_input_tokens',0)}")
if turn >= 2:
break
except Exception:
pass
これを計測したいディレクトリで実行する。
発見1:VSCodeとCLI(VSCode外)でキャッシュ挙動が根本的に違う
計測環境はすべて ~/Desktop/baseline-test/(CLAUDE.mdなし・フックなし・スキルなし)。
| 起動方法 | cache_create | cache_read |
|---|---|---|
| VSCode拡張(チャットパネル) | 39,054 | 10,270 |
| VSCode内ターミナルからCLI | 39,054 | 10,270 |
| VSCode外ターミナル(iTerm2等)からCLI | 50,985 | 0 |
VSCode外ターミナルは cache_read=0。毎回全量のcache_createが走る。VSCode経由(拡張もターミナルも)は cache_read≈10,270 が常時命中する。
これはAnthropicサーバー側のPrompt Cacheの仕組みによるものだ。VSCode拡張経由で起動したセッションはサーバー側の共有キャッシュキーに乗るが、純粋なCLIはそのキャッシュに乗らない。
コスト換算(claude-sonnet-4-6の場合)
cache_read はinputの約1/10の料金。10,270トークンのcache_readは、cache_createとして払う場合の約1/10で済む。
VSCode外CLIは毎回 cache_create=50,985(≒$0.19/1k sessions)を払い続けるが、VSCode経由は cache_create=39,054 + cache_read=10,270×0.1 で済む。長期的にはVSCode経由の方が安い。
発見2:subagentはキャッシュを引き継がない(ただし同じ共有キャッシュには乗る)
Claude CodeのAgentツールでsubagentを起動するとき、「親セッションのキャッシュをsubagentが引き継ぐのでは」と思いたくなる。これは誤りだ。
計測結果:
| 起動元 | subagent cache_create | subagent cache_read |
|---|---|---|
| VSCode拡張から起動 | 39,054 | 10,270 |
| baseline-test VSCodeから起動 | 39,054 | 10,270 |
subagentは毎回独立してcache_createが走る。親セッションのコンテキストは引き継がれない。
ただし、VSCode経由で起動したsubagentはVSCode共有キャッシュに乗るため、cache_read=10,270 が命中する。これは「親のキャッシュを引き継いでいる」のではなく、**「VSCode経由という起動経路が同じ共有キャッシュキーを使っている」**だけだ。
subagentを並列展開するときのコスト計算
並列subagent N本のcache_createコスト
= 1セッション分のcache_create × N
例えば現在の設定(最適化済みのCLAUDE.md群あり)で cache_create≈46,367 の環境なら、10本並列 = 463,670トークンのcache_createが走る。Layer Aの削減(CLAUDE.mdの軽量化)はsubagentの並列数倍で効いてくる。
発見3:cache_createの内訳を層別に分解できる
ベースライン計測を繰り返すことで、cache_create の内訳が特定できた。
| 構成 | cache_create | 差分の正体 |
|---|---|---|
| 何もなし(ベースライン) | 39,054 | Claude Code本体固定(制御不可) |
| + ユーザースキル85個 | 41,999 | +2,886 = スキル一覧 |
| + CLAUDE.md群 + Sessionフック | 46,367 | +4,368 = Layer A+B |
| 最適化前 | 68,097 | +26,098 = 旧Layer A+B |
ユーザーが制御できる範囲は全体の約15%(46,367 - 39,054 = 7,313トークン)にすぎない。Claude Code本体固定分39,054トークンは削れない。
逆に言えば、「CLAUDE.mdを削ればコストが激減する」という期待は現実的ではない。本体固定分が支配的だからだ。ただし、CLAUDE.mdのon-demand化(必要なときだけ注入する仕組み)は、subagentを並列展開する場合に効果が出やすい。
まとめ
| 知見 | 実測による結論 |
|---|---|
| VSCode vs CLI外 | VSCode経由は共有キャッシュが命中してcache_readが安い |
| subagentのキャッシュ | 引き継がない。毎回独立してcache_createが走る |
| cache_createの内訳 | 約85%がClaude Code本体固定。ユーザー制御可能は約15% |
| CLAUDE.md削減の効果 | 単体セッションでは小さい。並列subagentほど効果が出る |
測定スクリプトを試してみる
冒頭のスクリプトを measure-cache-creation.py として保存し、任意のディレクトリで実行すれば自分の環境のcache_create/cache_readを確認できる。
turn 1のcache_readが0か≈10,270かを見るだけで、自分がVSCode外CLIで起動しているかVSCode経由かが分かる。
計測環境: Claude Code v2.1.126 / claude-sonnet-4-6 / macOS 25.4.0 / 2026-05-03