大きなリポジトリを Claude Code に丸ごと渡して、「これで全部読んでくれる」と安心した数十分後。使用量の画面を開いて、手が止まりました。
一度のセッションで、いつもの数倍のトークンを消費していたのです。処理そのものは正しく終わっていました。ただ、その仕事に、その窓の大きさは要らなかった 。分割して必要な範囲だけ読ませれば、同じ結果をずっと安く得られたはずでした。
2026年6月30日に Claude Sonnet 5 が全プランの既定モデルになり、Claude Code はネイティブで100万トークンのコンテキストを扱えるようになりました。以前の1Mはベータ扱いで、対象モデルも限られていました。いまは既定で手が届きます。だからこそ、「広いから全部入れる」という発想は、静かに費用を溶かします。
個人開発で複数のサイトの更新を無人で回している私自身、この掛け算に何度も足をすくわれてきました。ここからは、大きな窓をいつ使い、いつ使わないか を、感覚ではなく式で決められるようにしていきます。自分の料金表とリポジトリで見積もれるコードも添えます。
大きな窓は「速さ」ではなく「費用」を変える
まず誤解を解いておきたいことがあります。コンテキストを広げても、モデルが賢くなるわけでも、必ず速くなるわけでもありません。変わるのは、一度に何を見せられるか と、そのために毎ターンいくら払うか です。
Claude Code は会話が進むほど、それまでのやり取りを繰り返し入力として送ります。窓に載せた分は、応答のたびに入力トークンとして課金され続けます。ここが要点です。1万トークンのファイルを窓に置いたまま20ターン往復すれば、その1万トークンは(キャッシュが効かない範囲では)20回ぶん課金され得ます。
つまり大きな窓の費用は「載せた量 × 触った回数」で効いてきます。同じ1万トークンでも、20往復すればキャッシュが効かない範囲では実質20回ぶん、しかも長コンテキスト帯では通常単価の約2倍で課金され得ます。一度きりの読み取りなら誤差ですが、長い探索や反復リファクタでは、この掛け算が効いてきます。なお Sonnet 5 の導入価格は入出力とも Opus 4.8 比でおよそ40%低く、常時回す用途ほどこの差が効きます。
見積もりの式 ― 「窓に全部」対「分割」
判断を式にします。記号を決めます。
記号 意味
T_ctx 窓に常駐させるトークン数(例: リポ全体)
T_q 1回の質問・指示のトークン数
T_out 1回の応答トークン数
N そのセッションでの往復回数
p_in / p_out 入力 / 出力の単価(百万トークンあたり)
s_in / s_out 長コンテキスト帯の割増係数(例: 入力×2 など)
c プロンプトキャッシュのヒット率(0〜1)
窓に全部載せる場合 の入力費用は、毎ターン T_ctx を送り続けるぶんが支配的になります。キャッシュが効く割合 c はキャッシュ読み取りの安い単価で計算されるため、実効の入力費用はおおよそ次のようになります。
入力費用(常駐) ≒ N × T_ctx × p_in × s_in × (1 - c + c × r_cache)
ここで r_cache はキャッシュ読み取り単価と通常入力単価の比(多くの環境で 0.1 前後、つまり約1/10)です。c が高いほど常駐は安くなる ことが、この式から読み取れます。
分割して必要な範囲だけ読ませる場合 は、常駐 T_ctx を送らず、各ターンで必要なファイル片 T_slice(i) だけを送ります。
入力費用(分割) ≒ Σ_i ( T_slice(i) × p_in × s_in' )
s_in' は、載せる総量が長コンテキスト帯を下回るなら割増なしの係数(1.0)になり得ます。ここが分割の効きどころです。200Kトークンの帯を超えるかどうか で割増が変わる料金体系が一般的なので、分割で帯を下回れば係数そのものが下がります。
式にすると当たり前に見えますが、実務で効くのは「N が大きく、c が低く、T_ctx が帯をまたぐ」ときに常駐が急に高くつく、という一点です。
見積もりを動くコードにする
上の式をそのまま関数にします。単価と割増は必ず最新の料金表で確認し、引数として渡してください(ここでは Sonnet 5 の導入価格を例に、長コンテキスト割増は上位帯の目安として変数化しています。実際の係数は公式の料金ページで確認してください)。
from dataclasses import dataclass
@dataclass
class Pricing :
p_in: float # 入力 $/1M tokens
p_out: float # 出力 $/1M tokens
long_threshold: int # この token 数を超えると長コンテキスト帯
s_in_long: float # 長帯の入力割増係数
s_out_long: float # 長帯の出力割増係数
r_cache: float # キャッシュ読取単価 / 通常入力単価
def _mult (total_ctx_tokens: int , pr: Pricing):
"""常駐量が長帯を超えるなら割増係数を返す。"""
if total_ctx_tokens > pr.long_threshold:
return pr.s_in_long, pr.s_out_long
return 1.0 , 1.0
def cost_resident (T_ctx, T_q, T_out, N, pr: Pricing, cache_hit = 0.0 ):
"""窓に T_ctx を常駐させて N 往復した場合の概算コスト($)。"""
s_in, s_out = _mult(T_ctx + T_q, pr)
# 常駐分: キャッシュ非ヒットは通常単価、ヒットは r_cache 倍
resident_factor = ( 1 - cache_hit) + cache_hit * pr.r_cache
in_resident = N * T_ctx * pr.p_in * s_in * resident_factor
in_query = N * T_q * pr.p_in * s_in
out_cost = N * T_out * pr.p_out * s_out
return (in_resident + in_query + out_cost) / 1_000_000
def cost_sliced (slices, T_q, T_out, N, pr: Pricing):
"""各往復で slices[i] だけを送る場合の概算コスト($)。
slices は長さ N のリスト(各ターンで送る関連トークン数)。"""
total = 0.0
for t_slice in slices:
s_in, s_out = _mult(t_slice + T_q, pr)
total += (t_slice + T_q) * pr.p_in * s_in
total += T_out * pr.p_out * s_out
return total / 1_000_000
# --- Sonnet 5 導入価格を例にした試算(単価は必ず最新を確認) ---
pr = Pricing( p_in = 2.0 , p_out = 10.0 ,
long_threshold = 200_000 ,
s_in_long = 2.0 , s_out_long = 1.5 , # 上位帯の目安。要確認
r_cache = 0.1 )
T_ctx = 260_000 # リポ全体を窓に載せる
slices = [ 30_000 ] * 12 # 分割なら毎回3万tokenだけ関連範囲を送る
args = dict ( T_q = 1_500 , T_out = 1_200 , N = 12 )
resident = cost_resident(T_ctx, pr = pr, cache_hit = 0.0 , ** args)
sliced = cost_sliced(slices, pr = pr, ** args)
print ( f "常駐(キャッシュ無): $ { resident :.2f } " )
print ( f "分割: $ { sliced :.2f } " )
resident_cached = cost_resident(T_ctx, pr = pr, cache_hit = 0.8 , ** args)
print ( f "常駐(キャッシュ80%): $ { resident_cached :.2f } " )
手元で走らせると、キャッシュが効かない常駐は分割よりかなり高く、キャッシュが8割効くと常駐が一気に現実的な水準まで下がる、という関係が数字で見えます。「1Mを使うべきか」は、ほぼ「キャッシュが効くか」と同義 だと、この試算は教えてくれます。
使うか使わないかを機械的に決める
見積もりができたら、判断も関数にしてしまいます。毎回コスト比較を回すのは重いので、実務では先に安い判定条件で振り分け、境界だけ精密に見積もる二段構えが軽くて済みます。
def should_use_large_context (T_ctx, N, cache_expected, pr: Pricing,
slice_ratio = 0.12 ) -> tuple[ bool , str ]:
"""1M級の常駐を使うべきかを判定して理由を返す。"""
# 1) そもそも帯を超えないなら常駐でよい(割増が付かない)
if T_ctx <= pr.long_threshold:
return True , "帯を超えないため常駐が無難(割増なし)"
# 2) 一度きりの読み取りは常駐が単純で安全
if N <= 2 :
return True , "往復が少なく再送コストが小さい"
# 3) 反復が多くキャッシュも期待できないなら分割
if N >= 6 and cache_expected < 0.5 :
return False , "再訪多・低キャッシュで常駐の再送が高くつく"
# 4) 関連範囲が全体のごく一部なら分割が効く
if slice_ratio <= 0.2 and cache_expected < 0.8 :
return False , "毎ターンの関連範囲が狭く分割で帯を下回れる"
# 5) それ以外はキャッシュ次第。境界は実測で
return (cache_expected >= 0.6 ,
"境界域。キャッシュ実測で常駐/分割を最終判断" )
for scenario in [
( 260_000 , 12 , 0.0 ),
( 260_000 , 12 , 0.85 ),
( 260_000 , 2 , 0.0 ),
( 150_000 , 20 , 0.0 ),
]:
ok, why = should_use_large_context( * scenario, pr = pr)
print (scenario, "->" , "常駐" if ok else "分割" , "/" , why)
閾値には根拠があります。往復2回以下では再送の掛け算が効きません(条件2)。逆に6往復以上でキャッシュ5割未満だと、常駐の再送費用が分割を上回りやすくなります(条件3)。関連範囲がリポ全体の2割以下なら、分割で長コンテキスト帯そのものを回避できます(条件4)。数字は自分の実測で微調整してください。私の場合は、往復が6回を超える探索では分割を既定にし、並べ順を固定してキャッシュを確保できるときだけ常駐へ切り替える運用を推奨します。ここで大事なのは、「なんとなく広げる」から「条件で決める」へ運用を移すこと です。
キャッシュを効かせる並べ方
判断が「キャッシュ次第」に落ちる場面が多いので、キャッシュの効かせ方も押さえます。プロンプトキャッシュは、先頭から一致する連続領域 にしか効きません。だから、変わらないもの(リポの安定した土台、規約、型定義)を前に、変わるもの(今の質問、直近の差分)を後ろに置きます。
順序が毎ターン揺れると、キャッシュはほぼ無効になります。Claude Code に大きな文脈を持たせるときは、「動かさない塊」を固定して先頭に置く。これだけで、上の試算の cache_hit が 0 から 0.7、0.8 へと動き、常駐の費用が現実的になります。
具体的には、セッションの早い段階で土台を読み込ませてから作業に入る、途中でファイル群の提示順を組み替えない、無関係な大きな出力を挟まない、という運用が効きます。
効かない・膨らむの典型と回避
大きな窓を有効化したのに期待どおりにならない失敗には、型があります。
第一に、窓は広いのに関連範囲が散らばっていて、モデルが必要な断片を毎回探し直す ケース。窓に入れれば読む、わけではありません。関連ファイルには明示的に触れさせ、探索の当てをこちらで与えると安定します。
第二に、キャッシュが毎ターン壊れていて、常駐がフルプライスで再送される ケース。使用量が往復数にきれいに比例して増えていたら、これを疑います。並べ順の固定で止まります。
第三に、一度きりの読み取りに1Mを持ち出す ケース。単発の要約や単一ファイルの修正なら、窓を広げる意味はほぼありません。分割の判定関数が「常駐でよい」を返すのは、むしろ帯を超えない小さな仕事のときだ、という非対称に注意してください。
いずれも、使用量の画面を「往復数」と「一往復あたりの入力トークン」に分解して眺めると、原因の当たりが早くつきます。私はセッション後にこの2軸だけを記録するようにしてから、見積もりと実測のズレがかなり小さくなりました。
次の一歩
まず、自分がよく回す作業を3つ挙げて、それぞれの T_ctx・N・想定キャッシュを紙に書き出してみてください。上の判定関数に入れるだけで、「これは常駐、これは分割」と機械的に振り分けられます。
そのうえで、境界に落ちた作業だけ、実際の使用量で cache_hit を測る。判断を式に預けられると、モデルが変わっても料金が改定されても、単価を差し替えるだけで方針が更新できます。導入価格には期限があり、長コンテキストの割増も変わり得ます。だからこそ、数字を引数にして、判断そのものは動かない形にしておくのが、長く回すうえでいちばん楽な備えになります。
同じ費用の掛け算に足をすくわれた経験が、どこかで誰かの見積もりの助けになればと願っています。最後までお付き合いくださり、ありがとうございました。