コンテキスト設計 — 結局どうすればいいか

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


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

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

more context isn’t automatically better. As token count grows, accuracy and recall degrade — context rotcontext-windows **context は多いほど自動的に良くなるわけではない。**トークン数が増えるにつれ、正確性と再現率は劣化する(context rot)。

The context window is a public goodagent-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起動時は namedescription約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 で要約方針だけ

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

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

⑤ そもそも入れない

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

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

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

機構compaction 後
system prompt / output style変わらない(メッセージ履歴の一部ではない)
プロジェクトルートの CLAUDE.mdpaths なしの 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 を減らす手がキャッシュを壊すことがある。両立させるための規則。

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

操作キャッシュへの影響
ツール定義の変更全キャッシュが飛ぶ
effort の変更messages が必ず飛ぶ(effort はプロンプトにレンダリングされる)
thinking 設定の変更同上
tool_choice の変更messages のみ
tool result clearingキャッシュを壊す
thinking block clearingkeep: "all"保つ(むしろヒットを最大化する)
defer_loading(tool search)保つ(prefix に触らない設計)

運用ルール:

  • 会話ごとに thinking 設定と effort を決めて固定する
  • ターン単位で思考量を調整したいなら、パラメータではなく per-message prompting で(最新の user メッセージへの追記は前方の breakpoint を壊さない)
  • breakpoint は「リクエスト間で内容が同一である最後のブロック」に置く。タイムスタンプなど変わるものに置くとハッシュが一致しない

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

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

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

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


7. 手順にまとめる

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

1. 測る                count_tokens / usage の内訳
2. prompt caching       初日から。ツール定義が安定しているなら常に
3. ツールが 20個超       tool search(defer_loading)
4. fan-out がある        programmatic tool calling(逐次型なら入れない)
5. 会話が長引く          compaction(server-side)。細かく制御したいなら 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 を減らす工夫そのものが増えすぎると、今度は選択の精度が落ちる。 測ってから足す。