「AI 開発してます」を見極める 10 の質問 — 素人のための解説|2026-08 版
第 4 章Q5

Q5 コンテキストウィンドウの調整

上限に近づいたとき、何を捨て、何を要約し、何を残すか

Q5. コンテキストウィンドウの調整

トークン上限に近づいたとき、会話履歴や参考情報をどう削ったり優先順位をつけたりしていますか? 実際に使っている切り詰め方や要約の工夫を教えてください。

出典: @voidwarriorchan の投稿(2026-08-25)
この章で分かること

この質問は何を聞いているのか

「トークン」は、モデルが文章を扱う最小単位(日本語ならおおむね1〜2文字程度)である。「トークン上限」は、モデルが一度の応答生成で参照できる情報量の上限——コンテキストウィンドウのことを指す。「会話履歴」はそれまでのやり取り、「参考情報」はモデルが必要に応じて呼び出すツール(=検索や計算などの外部の機能。呼び出しの指示と、その実行結果の2つがコンテキストに載る)の実行結果や外部データなど、会話本文以外にコンテキストへ載っている情報を指す。

つまりこの質問は、「コンテキストウィンドウが埋まってきたときに、何を残し何を先に捨てるかを設計して運用した経験があるか」を聞いている。トークン上限を超えたときにAPIがどう振る舞うかという仕様理解と、「消す」「要約する」「外部に逃がす」といった手段を公式機能の名前・設定値のレベルで語れるかの両方を、同時に確認できる質問になっている。

なぜ「削る」作業が必要なのか

コンテキストウィンドウは、モデルが応答を生成する際に参照できるテキスト全体の上限で、モデル自身が生成した出力も含まれる。学習データとは別物の「作業記憶」だとAnthropicは説明している。システムプロンプト(=開発者がモデルに最初に渡す、役割や禁止事項などの固定の指示文)、会話履歴、ツールの実行結果、ツールの定義、そしてモデルの出力(内部思考のトークンも含む)が、すべてこの上限にカウントされる。

プロンプトキャッシュ(同じ内容を毎回計算し直さず再利用してコストと待ち時間を削る仕組み)を使っていても、コンテキストウィンドウの消費量は減らない。Anthropicは「キャッシュされたプレフィックス(=プロンプト先頭の、毎回同じ部分)も、コンテキストウィンドウは占有し続ける。キャッシュが変えるのは課金対象であって、カウント対象ではない」と明記している。「キャッシュしているから上限は気にしなくていい」は成り立たない。

さらに、上限に達していなくても性能は落ちていく。トークン数が増えるほど、モデルが情報を正確に思い出す精度が下がる現象は「コンテキストロット(context rot)」と呼ばれる。Transformerというモデルの構造上、コンテキスト中のすべてのトークンどうしが互いに関係し合う計算が発生し、トークン数が増えるほどこの関係を捉える力が薄まっていく。これは崖のように急に壊れるのではなく、なだらかな劣化として現れる。Anthropicはこの資源を「限界効用が逓減する有限資源」(=使えば使うほど1トークンあたりの効き目が薄くなる、限りある資源)とし、モデルには使うたびに減っていく「注意予算(attention budget)」があると表現している。「窓が大きいモデルを使っているから何も削らなくていい」は、この点で誤りになる。

では上限そのものを超えるとどうなるか。Anthropicでは、入力だけで上限を超える場合は全モデルで400エラー(プロンプトが長すぎるというエラー)になる。入力とモデルの出力上限(max_tokens)の合計が上限を超える場合は、Claude 4.5以降のモデルではリクエストを受け付け、生成が上限に達した時点でstop_reason: "model_context_window_exceeded"という理由付きで打ち切る(2026-08時点)。一方OpenAIのResponses APIはtruncationというパラメータで挙動を選べる。既定値の"disabled"では上限超過時に400エラーになり、"auto"にすると会話の先頭(古い方)から項目を落として上限内に収めたうえで生成を続ける。同じ「上限超過」でも、エラーで止まる/生成を途中で打ち切る/古い情報を捨てて続ける、の3通りの結末があることは、実務で切り分けを問われる基本知識になる。

ターン1 ターン2 ターン3 ターン4 ターン5 コンテキストウィンドウの上限 生成中に上限へ到達 入力が上限を超えた Anthropic 入力だけで超過 → 400エラー(プロンプトが長すぎる) 生成中に上限へ到達 → 打ち切り stop_reason: model_context_window_exceeded (Claude 4.5以降のモデル) OpenAI 先頭から古い項目を削除 (truncationがautoの場合)
図 4-1 ターンを重ねるごとにコンテキストの使用量は積み上がる。上限を超えたときの結末はAPIによって異なり、Anthropicは入力だけで超過すると400エラー、入力は上限内でも生成が上限へ達した場合はClaude 4.5以降でstop_reason: "model_context_window_exceeded"として打ち切る。OpenAI(入力が上限を超え、truncation: "auto"のとき)は古い項目を先頭から捨てて続行する。

何を残し、何を捨てるか — 4つの型としきい値

公式ドキュメントに現れる対策は、大きく4つの型に整理できる。A. 先頭から古い順に捨てる(FIFO)は、古いメッセージを丸ごと消す最も単純な方法で、claude.aiのようなチャットUIやOpenAIのtruncation: "auto"がこれにあたる。B. ツール結果だけ消すは、会話本文は残したまま、古いツールの実行結果だけをプレースホルダ(=「ここは削除済み」という短い代替文)に置き換える方法である。C. 要約に置き換える(圧縮/compaction)は、古い履歴をモデル自身に要約させ、その要約から会話を続行する方法。D. 外部に逃がすは、コンテキストの外(ファイルなど)に情報を書き出し、必要になったときだけ読み戻す方法である。

上からシステムプロンプト/古い履歴/直近メッセージ A先頭から削除 B結果だけ消去 C要約する D外部へ退避 システムプロンプト※ システムプロンプト システムプロンプト システムプロンプト 削除(古い順) 呼び出しは保持 [cleared]に置換 要約して1つに置換 古い履歴を書き出す 直近メッセージ 直近メッセージ ※pause時のみ保持 直近メッセージ メモリファイル (コンテキストの外) 書き出し 読み戻し
図 4-2 4つの型は古い履歴の扱いだけが異なる。システムプロンプトはmessagesの外にあるため、C(Anthropicの圧縮)とDでは残る。Aは実装依存で(図のA列の点線はこの実装依存を示す)、LangChain(=アプリ側フレームワーク)のtrim_messagesはinclude_system=Trueを指定した場合のみ残る。直近メッセージを残すのはA(strategy="last")・B(keep既定3組)とLangChainのSummarizationMiddleware(keep既定20件)で、Anthropicのサーバーサイド圧縮は既定でcompactionブロック以前をすべて捨て、pause_after_compactionを使って挿し直したときだけ残る(図のC列の点線とD列の外部メモリはこの違いを示す)。

この4つの型のうち、長い会話やエージェント処理(=モデルがツールを何度も呼びながら自律的に作業を進める使い方)における主戦略として公式に推奨されているのはCの要約(圧縮)である。Anthropicのサーバーサイド圧縮(compact_20260112、2026-08時点はベータ機能)は、入力トークンが既定のしきい値(trigger、既定150,000トークン、下限は50,000トークンまで指定可能)に達すると、現在の会話を要約してcompactionブロックを作り、その要約から応答を続ける。次回以降のリクエストでは、このcompactionブロックより前の内容はAPI側が無視するため、クライアントは会話全体を持ち続けたままでよい。

クライアント API:しきい値判定 要約して圧縮ブロックを作る 本応答を返す (続きはブロック以降) リクエスト送信 150,000トークンで発火(既定) 要約を含めて返す 次回リクエストのmessagesに追記
図 4-3 サーバーサイド圧縮の流れ。要約プロンプトはinstructionsで完全に差し替えられ、pause_after_compactionを使えば要約直後に一度止めて直近メッセージを原文のまま挿し直すこともできる。

要約は情報を捨てる作業でもある。「要約プロンプトの技巧は、何を残し何を捨てるかの選び方にある。過度に強く圧縮すると、後になって初めて重要だと分かる細かい文脈が失われかねない」とAnthropicはエンジニアリングブログで注意している。会話の途中でツールを呼び出した結果を、それより後で改めて生の中身のまま参照する必要はほとんどないため、ツール結果を消すだけの対策(B型)は「最も安全で軽い圧縮の一つ」として位置づけられている。要約が発生すると会話のプレフィックス(キャッシュされていた先頭部分)が作り直されるため、Anthropicはシステムプロンプトの末尾にキャッシュの区切り(cache_control)を置き、圧縮後もシステムプロンプト部分のキャッシュが再利用され要約分だけ新規書き込みになるよう設計することを推奨している。

「何を残すか」の優先順位づけには、履歴として壊れない形を保つという制約が働く。LangChain(=LLMアプリを組み立てるための代表的なフレームワーク〈部品集〉)のメッセージ切り詰め機能は、切り詰め後の履歴が満たすべき条件として、直近のメッセージから残すこと、ツールの実行結果はそのツールを呼び出したメッセージとセットで扱うこと、そしてシステムプロンプトは元の履歴にあったなら残すこと、の3点を挙げている。B型のツール結果クリアも、既定では直近3組(呼び出しと結果のペア)を残し、それより古いものから時系列順に消していく。

到達前(全6組が残っている) ペア1 ペア2 ペア3 ペア4 ペア5 ペア6 消去 消去 消去 ペア4 ペア5 ペア6 既定100,000トークン超で発火 直近3組は保持
図 4-4 Anthropicのツール結果クリアは、入力が既定100,000トークンを超えると古いペアから順に消え、keepパラメータ(既定3)の分だけ直近のペアが原文のまま残る。

実務では何をするのか

実務での手段は、APIプロバイダが用意するサーバーサイド機能、アプリ側フレームワーク(=アプリを組み立てるための部品集)の機能、そしてClaude Code(Anthropicが提供する、ターミナルで動くコーディング用エージェント製品)のようなエージェント製品が自動でやってくれる機能の3層に分かれる。どの層の経験を聞いているのかを意識すると、回答の解像度が上がる。

型何をするか公式機能の例(2026-08時点)
A. 先頭から捨てる(FIFO)古いメッセージを丸ごと消すOpenAI truncation: "auto" / LangChain trim_messages(strategy="last")
B. ツール結果だけ消す本文は残し、古いツール結果だけプレースホルダに置換Anthropic clear_tool_uses_20250919 / LangChain ClearToolUsesEdit
C. 要約に置き換える古い履歴を要約させ、そこから続行するAnthropic compact_20260112 / OpenAI context_management / LangChain SummarizationMiddleware / Claude Codeの/compact
D. 外部に逃がすコンテキスト外に書き出し、必要時に読み戻すAnthropicのmemory tool / Claude CodeのCLAUDE.md再注入

Anthropicは、ツール由来のコンテキスト肥大への対策として導入順まで示している。まずツール定義にプロンプトキャッシュを効かせ、ツールセットが20個を超えたあたりでツール検索(必要なツール定義だけを都度読み込む仕組み)を足し、会話が長く続いて古い結果が不要になってきたらコンテキスト編集(B型)を足し、同じような小さなツール呼び出しの連鎖が多いなら複数の呼び出しを1回のスクリプトにまとめる、という順序である。この4段階はツール由来の肥大に限った導入順であり、会話全体を要約する圧縮(compaction)とは別の話である。

要約(圧縮)そのものは、2026-08時点ではベータ機能のためリクエストにベータヘッダーcompact-2026-01-12を付けたうえで、Anthropicのcontext_managementパラメータに次のようにedits配列に1件だけ渡せば有効化できる(triggerを省くと既定150,000トークンになる。例えば"trigger": {"type": "input_tokens", "value": 100000}を追加すると100,000トークンで発火する〈指定できる最小値は50,000〉)。

{
  "edits": [
    { "type": "compact_20260112" }
  ]
}

OpenAIのResponses APIでも同種の機能があり、context_managementにcompact_thresholdを指定すると、指定したトークン数を超えた時点でサーバー側が自動的に圧縮する。ただしAnthropicの圧縮ブロックが平文の要約テキストなのに対し、OpenAIの圧縮結果は暗号化された不透明なデータとして返る点が異なる。人間には読めないが、次のリクエストにそのまま渡せば会話は継続する。単発で会話全体を圧縮したい場合向けに、状態を持たない/responses/compactという専用エンドポイントも用意されている。クライアント側で履歴を管理する場合は、OpenAI Agents SDK(=OpenAIがエージェント開発向けに提供するプログラム部品集)のSessionsで直近N件だけを取得する上限を設定したり、履歴の並べ替え・間引きを、用意した処理を自動で呼んでもらう仕組み(コールバック)で行ったりもできる。

フレームワーク層では、LangChain / LangGraphがA〜Cすべてに相当する部品を提供している。trim_messagesは古い順にメッセージを切り詰め、RemoveMessageで状態から永続的に削除し、SummarizationMiddlewareは指定したしきい値(トークン数・メッセージ数・上限に対する割合のいずれか)に達すると自動で要約する。Anthropicの圧縮が要約に使うモデルを主モデル固定にしているのに対し、このミドルウェア(=モデル呼び出しの前後に自動で挟まる処理)は要約専用に別の(より安価な)モデルを指定できる点が異なる。

製品として実際にこれらを組み合わせている例が、Claude Codeである。既定では会話がモデルのコンテキスト上限に達したときに自動的に圧縮が走る(クラウド版セッションは上限に近づいた時点で発火する。Anthropic API 上で 1M ウィンドウを使う Sonnet 5 は既定で約967,000トークンで発火し、環境変数 CLAUDE_CODE_AUTO_COMPACT_WINDOW で変更できる。2026-08時点)。フォーカスを添えて手動で圧縮する、巻き戻して途中から要約し直す、無関係な作業に移るときは会話ごと消す、といった操作をコマンドで使い分けられる。圧縮しても、プロジェクトのCLAUDE.md(恒久的な指示を書くファイル)や直近に読み書きしたファイルはディスクから再注入されるため、会話の中だけで与えた指示は消えても、ファイルに書いた指示は生き残る、という設計になっている。

どの層でも共通して必要になるのが計測である。Anthropicは/v1/messages/count_tokensという無料のトークン数見積もりAPIを提供しており、これはあくまで推定値であること、Claude 4.7以降のモデルはトークナイザ(=文章をトークンに切り分ける部品)が変わり同じ文章でもトークン数がおよそ30%増えること(2026-08時点)が明記されている。しきい値を設計するときは、実際に使うモデルで数え直す必要がある。

回答を見極めるポイント

良い回答に含まれる要素
弱い回答のサイン

深掘り質問の例

つまずきポイント

「プロンプトキャッシュを使えばコンテキストウィンドウの消費も減る」と思っていた。実際はキャッシュが変えるのは課金対象であって、コンテキストウィンドウのカウント対象からは外れない。

「要約すれば会話の中身は全部保たれる」と思っていた。要約は情報の取捨選択であり、後になって初めて重要だと分かる細かい文脈は失われうる、とAnthropic自身が注意点として明記している。

「コンテキストウィンドウが大きいモデルなら、削る作業は不要」と思っていた。上限に達していなくても、トークン数が増えるほど精度が落ちるコンテキストロットは起きる。大きな窓は猶予を与えるだけで、劣化そのものを消してはくれない。

理解度チェック

Q1. プロンプトキャッシュを使うと、コンテキストウィンドウの消費量は減りますか?

減らない。キャッシュされたプレフィックスも引き続きコンテキストウィンドウを占有するとAnthropicは明記している。キャッシュが変えるのは料金の計算方法であって、カウント対象ではない。

Q2. Anthropicのサーバーサイド圧縮(compaction)が既定で発火するのは、入力トークンがいくつに達したときですか?

既定は150,000トークン(2026-08時点)。この値は最小50,000トークンまで下げて指定できる。

Q3. OpenAIのResponses APIで、truncationパラメータの既定値である"disabled"のとき、入力がコンテキストウィンドウを超えるとどうなりますか?

400エラーになる。"auto"に変えると、会話の先頭から古い項目を落として上限内に収めたうえで生成を続ける。

Q4. Anthropicのツール結果クリア(clear_tool_uses_20250919)は、既定でいくつの「直近のツール呼び出しと結果の組」を残しますか?

既定は3組(keep=3)。古いものから時系列順に消され、直近3組は原文のまま残る。

Q5. 「ツール結果だけを消す」方法が、会話全体を要約する方法より軽い対策とされているのはなぜですか?

すでに履歴の中で深く古くなったツールの実行結果は、モデルが後で生の中身を再び必要とすることがほとんど無いため、消しても実質的な情報損失が小さいから。Anthropicのエンジニアリングブログはこれを「最も安全で軽い圧縮の一つ」と位置づけている。

まとめ

次章(第5章)では、「応答が遅い」と指摘されたときに、読み込み段階(prefill)と書き出し段階(decode)のどちらが原因かを切り分ける方法を見ていく。

参考リンク