コンテキスト設計 — context window の配分 — 結局どうすればいいか

20本の原典が同じ制約を別の角度から言っている。「context は有限の予算であり、多く入れるほど良いわけではない」。 ここではその制約から実際の手順を導く。


1. 前提: 大きいほど良くはない

1M トークンの window があっても、埋めれば性能が落ちる。

more context isn’t automatically better. As token count grows, accuracy and recall degrade, a phenomenon known as context rot. — context-windows

context は多いほど自動的に良くなるわけではない。トークン数が増えるにつれて正確性と再現率は劣化する —— context rot として知られる現象である。

The context window is a public good — agent-skills-best-practices

context window は公共財である。

したがって設計上の問いは「どれだけ入るか」ではなく「何を入れないか」になる。

注意すべき非対称性: 入れるのは一瞬だが、出すのは難しい。/clear 以外の方法(compaction、context editing)は何が消えるかを完全には制御できない。だから入れる前に判断するほうが安い。


2. まず測る。手当てはその後

原典が繰り返し言うのは「どこにトークンが消えているかを特定してから手を選べ」ということ。

測る手段分かること
/context(Claude Code)カテゴリ別の消費と最適化の提案。どの CLAUDE.md と auto memory がロードされたかも出る
/usage(Claude Code)skill / subagent / plugin / MCP サーバ別の内訳。10%以上を占める振る舞いにフラグが立つ
/mcpMCP サーバごとのトークンコスト
usage フィールド(API)input_tokens / cache_read_input_tokens / cache_creation_input_tokens の内訳
count_tokens + context_managementcontext editing を適用した場合の削減量を送信前に見積もる

測らずに手を打つと、効かない場所を最適化する。 programmatic-tool-calling は「効くのは fan-out 型だけで、逐次型では 8% 高くつく」と明記している。


3. 5つの手。層をなす

制約から出てくる手は、文書をまたいで同じ5つに収束する。排他ではなく重ねる。

① 使うまでロードしない(progressive disclosure)

最も費用対効果が高い。 「あるが読まれていない」状態を作る。

機構ロードのされ方
skill起動時は name と description(約100トークン)だけ。本体は使うとき。参照ファイルは読むまでゼロ
MCP tool searchツール名だけ。スキーマは必要時。既定で有効
.claude/rules/ の paths:マッチするファイルを読む・書く・編集するときだけ
skill の paths:同上

なぜこれが効くか: agent-skills-overview の数字が明快。Level 1 が約100トークン、Level 2 が 5k 未満、Level 3 は読むまでゼロ。だから「skill をいくつ入れても context のペナルティがない」。

設計上の含意: 同梱するコンテンツの量に実質的な上限がない。 API ドキュメント全文でも、大きなデータセットでも、使わなければコストはゼロ。むしろ「本体を痩せさせて参照に逃がす」ことが正しい。

作者はコアを痩せさせておき、「フォームを埋めるときにだけ Claude が forms.md を読む」ことを信頼する — equipping-agents-for-the-real-world-with-agent-skills

② 別の context に追い出す

要約だけを返させる。

機構返ってくるもの
subagent最終テキストと小さなメタデータのみ。実測で 6,100トークン読んで 420トークン返す
workflow中間結果はスクリプト変数に留まり、Claude の context には最終回答だけ
programmatic tool calling中間の tool_result が一切 context に入らない
code execution with MCP同上。150,000 → 2,000 トークン(98.7%減)

共通する構造: 「大量に読む主体」と「結果を受け取る主体」を分離する。

③ context の外に状態を置く

セッションを跨ぐには、context 以外の場所が要る。

置き場誰が書くかロード
CLAUDE.md自分毎セッション全文
auto memoryClaude毎セッション(MEMORY.md の先頭200行 or 25KB)
memory tool(API)Claude(実行は自分のアプリ)必要時に読む
progress.txt + feature_list.json + gitエージェント毎セッション冒頭に自分で読ませる

重要な帰結: effective-harnesses-for-long-running-agents の harness は、この③だけで「記憶を持たないエージェントが毎回同じ場所から立ち上がる」を実現している。context を増やすのではなく、context の外に状態を置いた。

④ 要らなくなったら捨てる

手段何が起きるか制御できるか
/clear全部捨てる。コストゼロ完全に制御できる
compaction(自動)古いツール出力を先に捨て、次に会話を要約部分的。焦点は指定できる
/compact <focus>焦点を指定して要約部分的
context editing(API)古い tool_result / thinking を要約せず落とす細かく制御できる(keep / exclude_tools / clear_at_least)
compaction(API・閾値)サーバ側で要約し、ブロックより前を全部捨てるinstructions で要約方針だけ(compaction-threshold)
compaction(API・要求時)要約だけを取りに行き、返ったブロックで要約範囲を置き換えるいつ・どこまで要約するかを決められる。API は送ったメッセージを全部要約し、要約を頼んだ後に進んだターンはブロックの後ろにそのまま続く(compaction-on-demand)。使えるならこちら(compaction)。残したターンの thinking を有効に保つには3条件が要る。破っても compact は成功し、検査が強制される環境で残した thinking を送る最初のリクエストが既定で 400 になる(drop_block や Batches ではエラーにならず黙って捨てられるので、input_transformations を見る。compaction-thinking-blocks)

/compact と /clear のコストが違うことは見落とされやすい。

/compact は要約対象の会話を読むので、それ自体が大きなリクエスト。継続が要らないなら /clear はコストゼロ — costs

⑤ そもそも入れない

手段効き方
Read deny ルールビルド成果物・生成コード・vendored 依存を開かせない
claudeMdExcludes触らないパッケージの CLAUDE.md をロードしない
MCP より CLI(gh、aws、gcloud)ツール一覧に載らないぶん、MCP より context 効率が良い
hook で前処理1万行のログを grep して該当行だけ返す。数万トークン → 数百トークン
code intelligence プラグイン「定義へジャンプ」1回が grep + 複数ファイル読みを置き換える

削っても落ちなかった

Claude Code は Opus 5 / Fable 5 向けの system prompt を8割以上削っても、コーディングの評価が測れるほど落ちなかった(new-rules-of-context-engineering)。原因は過剰な制約で、system prompt・skill・ユーザーの依頼が1つのリクエストの中で矛盾していた。規則より判断、例より道具の設計、全部前置きより段階的な開示、繰り返しより簡潔なツール説明。CLAUDE.md は軽く保ち、トークンの大半をコードベースの落とし穴に使う。

費用の側からも同じ結論になる —— CLAUDE.md は毎ターン送り直され、context が大きいほど1ターンが高い(what-a-task-costs-on-opus-5-5)。


4. compaction で何が消えるか(最も間違えやすい点)

「CLAUDE.md に書いたから残る」は半分しか正しくない。

機構compaction 後
system prompt / output styleどちらも引き続き効く
プロジェクトルートの CLAUDE.md、paths なしの ruleディスクから再注入される
auto memoryディスクから再注入される
paths: を持つ rule失われる。該当ファイルを再度読むまで戻らない
サブディレクトリのネストした CLAUDE.md失われる。同上
起動した skill の本体再注入されるが 1本 5,000 / 合計 25,000 トークンで打ち切り。古い順に落ちる
skill の description 一覧再注入されない。実際に起動した skill だけ残る

ここから出てくる3つの実務ルール:

  1. compaction を跨いで確実に残したいルールは、paths: を外してプロジェクトルートの CLAUDE.md に置く
  2. SKILL.md は重要な指示を先頭に置く(切り詰めは先頭を残す)
  3. 長いセッションで計画を守りたいなら、計画をファイルに保存する(会話履歴は要約される)

長いセッションは途中で compaction されるが、保存した計画は会話履歴が消えても残る — large-codebases


5. キャッシュを壊さない

context を減らす手がキャッシュを壊すことがある。両立させるための規則。

キャッシュの階層は tools → system → messages。ある段の変更はその段以降を全部無効化する。

操作キャッシュへの影響
ツール定義の変更全キャッシュが飛ぶ。ただし inline-tools-2026-09-15 beta で会話途中の system メッセージの tool_addition ブロックとして足すなら、tools を編集しないので接頭辞は一致したまま(prompt-caching)
effort の変更messages が必ず飛ぶ(effort はプロンプトにレンダリングされる)
thinking 設定の変更同上
tool_choice の変更messages のみ
tool result clearingキャッシュを壊す
thinking block clearing(keep: "all")保つ(むしろヒットを最大化する)
defer_loading(tool search)保つ(prefix に触らない設計)

運用ルール:

  • 会話ごとに thinking 設定と effort を決めて固定する(既定値を明示的に書くのは省略と同じで壊さない。per-message effort に対応したモデルなら、role: "system" メッセージで運ぶ変更も壊さない)
  • 会話の途中で system 指示を足すなら、トップレベルの system を編集せず {"role": "system"} メッセージを messages に足す(対応モデルなら system も messages も飛ばない。Sonnet 5 は非対応)
  • ターン単位で思考量を調整したいなら、パラメータではなく per-message prompting で(最新の user メッセージへの追記は前方の breakpoint を壊さない)
  • breakpoint は「リクエスト間で内容が同一である最後のブロック」に置く。タイムスタンプなど変わるものに置くとハッシュが一致しない

使われ方の変化が費用の重心を動かした

集計で、Claude Code の1リクエストの context は2.6倍、入力と出力の比は 189:1 → 324:1 になった(opus-5-5-for-longer-coding-sessions)。費用の大半は送り直す context のキャッシュ読み取りになり、渡す context が本当に必要か、そのできるだけ多くがキャッシュから読まれているかが効く。守り方は「モデルはセッションの初めに決める」「compact は席を離れる前に」「API キーかクラウドプロバイダなら長いセッションで1時間キャッシュ」。

memory を外に置くときは、エージェントが既に使う道具の上に置く —— Managed Agents の memory はファイルシステムに載り、Claude は bash とコード実行でそれを扱う(managed-agents-memory)。


6. 長いセッションで利用が跳ねる理由

「たいして使っていないのに上限に当たる」の原因は5つある。 どれも context のサイズに起因する。

原因中身
long context全会話が毎リクエスト送られる。一日開けたセッションでの一言の質問も、会話全体分の利用量を消費する
cache missキャッシュ寿命を超えた中断の後、最初のメッセージが全 context を再処理する
scheduled tasksidle でも間隔ごとに全 context を送る
cross-session messages他セッションからのメッセージが新ターンとして配送され、毎回全 context を送る
compaction 自体要約対象を読むので大きなリクエストになる

→ 対処は「context を小さく保つ」の一点に集約される。


7. 手順にまとめる

API でエージェントを組むとき

  1. 測る —— count_tokens / usage の内訳。compaction を使うならトップレベルの usage は要約の分を含まないので、usage.iterations を合計する(compaction-threshold)
  2. prompt caching —— 初日から。ツール定義が安定しているなら常に
  3. ツールが 20個超 —— tool search(defer_loading)
  4. fan-out がある —— programmatic tool calling(逐次型なら入れない)
  5. 会話が長引く —— compaction(server-side)。使えるなら要求時方式(いつ要約するかを自分で決め、裏でも走らせられる。Bedrock では閾値方式)。要約せず古いツール結果を消すだけなら context editing
  6. セッションを跨ぐ —— memory tool。context の外に状態を置く
  7. effort と thinking —— 会話ごとに固定。ターン単位は per-message prompting

Claude Code を使うとき

  1. 測る —— /context と /usage
  2. CLAUDE.md を 200行以内に —— 超えたら skill か path-scoped rule へ
  3. 無関係な作業に移る —— /clear(コストゼロ。/compact より安い)
  4. 調査が重い —— subagent に委譲
  5. 読ませたくないものがある —— Read の deny ルール、claudeMdExcludes
  6. 冗長な出力 —— hook で前処理して絞る
  7. MCP より CLI —— gh / aws / gcloud が使えるならそちら
  8. 型付き言語 —— code intelligence プラグイン

8. 判断に迷ったときの原則

この3つは原典が繰り返し言っている。

  1. 入れる前に判断する。 出すのは難しく、何が消えるかを完全には制御できない
  2. 「あるが読まれていない」を作る。 progressive disclosure が最も費用対効果が高い
  3. 読む主体と受け取る主体を分ける。 subagent / workflow / code execution はすべてこの形

そして、やりすぎの兆候も原典が指摘している。

Too much can fill up your context window, but it can also add noise that makes Claude less effective; skills may not trigger correctly, or Claude may lose track of your conventions — features-overview

多すぎれば context window を埋めるだけでなく、Claude の性能を落とすノイズにもなる。skill が正しく起動しなかったり、Claude が規約を見失ったりする。

context を減らす工夫そのものが増えすぎると、今度は選択の精度が落ちる。 測ってから足す。