Q5. コンテキストウィンドウの調整
トークン上限に近づいたとき、会話履歴や参考情報をどう削ったり優先順位をつけたりしていますか? 実際に使っている切り詰め方や要約の工夫を教えてください。
出典: @voidwarriorchan の投稿(2026-08-25)
- コンテキストウィンドウ(=モデルが一度に参照できる情報量の上限)が、なぜ「大きければ安心」ではないのか
- 上限に近づいた・超えたときにAPIが実際にどう振る舞うか(Anthropic / OpenAI)
- 「先頭から消す・ツール結果だけ消す・要約する・外部に逃がす」という削り方の4つの型と、それぞれの公式機能の名前・既定値
- 面接で「使ったことがある」と「仕組みを理解して使い分けている」を見分けるポイント
この質問は何を聞いているのか
「トークン」は、モデルが文章を扱う最小単位(日本語ならおおむね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通りの結末があることは、実務で切り分けを問われる基本知識になる。
stop_reason: "model_context_window_exceeded"として打ち切る。OpenAI(入力が上限を超え、truncation: "auto"のとき)は古い項目を先頭から捨てて続行する。何を残し、何を捨てるか — 4つの型としきい値
公式ドキュメントに現れる対策は、大きく4つの型に整理できる。A. 先頭から古い順に捨てる(FIFO)は、古いメッセージを丸ごと消す最も単純な方法で、claude.aiのようなチャットUIやOpenAIのtruncation: "auto"がこれにあたる。B. ツール結果だけ消すは、会話本文は残したまま、古いツールの実行結果だけをプレースホルダ(=「ここは削除済み」という短い代替文)に置き換える方法である。C. 要約に置き換える(圧縮/compaction)は、古い履歴をモデル自身に要約させ、その要約から会話を続行する方法。D. 外部に逃がすは、コンテキストの外(ファイルなど)に情報を書き出し、必要になったときだけ読み戻す方法である。
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側が無視するため、クライアントは会話全体を持ち続けたままでよい。
instructionsで完全に差し替えられ、pause_after_compactionを使えば要約直後に一度止めて直近メッセージを原文のまま挿し直すこともできる。要約は情報を捨てる作業でもある。「要約プロンプトの技巧は、何を残し何を捨てるかの選び方にある。過度に強く圧縮すると、後になって初めて重要だと分かる細かい文脈が失われかねない」とAnthropicはエンジニアリングブログで注意している。会話の途中でツールを呼び出した結果を、それより後で改めて生の中身のまま参照する必要はほとんどないため、ツール結果を消すだけの対策(B型)は「最も安全で軽い圧縮の一つ」として位置づけられている。要約が発生すると会話のプレフィックス(キャッシュされていた先頭部分)が作り直されるため、Anthropicはシステムプロンプトの末尾にキャッシュの区切り(cache_control)を置き、圧縮後もシステムプロンプト部分のキャッシュが再利用され要約分だけ新規書き込みになるよう設計することを推奨している。
「何を残すか」の優先順位づけには、履歴として壊れない形を保つという制約が働く。LangChain(=LLMアプリを組み立てるための代表的なフレームワーク〈部品集〉)のメッセージ切り詰め機能は、切り詰め後の履歴が満たすべき条件として、直近のメッセージから残すこと、ツールの実行結果はそのツールを呼び出したメッセージとセットで扱うこと、そしてシステムプロンプトは元の履歴にあったなら残すこと、の3点を挙げている。B型のツール結果クリアも、既定では直近3組(呼び出しと結果のペア)を残し、それより古いものから時系列順に消していく。
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時点)が明記されている。しきい値を設計するときは、実際に使うモデルで数え直す必要がある。
回答を見極めるポイント
- 上限を超えたときに実際に何が起きるかをAPI仕様として説明できる(Anthropicは入力超過で400エラー、一部モデルは生成中の超過で
model_context_window_exceeded。OpenAIはtruncationが既定disabledなら400、autoなら先頭から削除して継続) - ウィンドウが大きくても「詰め込めば安心」ではないと理解している(コンテキストロットを踏まえ、削る作業の必要性を語れる)
- 「先頭から消す」「ツール結果だけ消す」「要約する」「外部に逃がす」を区別し、それぞれの公式機能名を挙げられる
- 何を残すかの理由を、履歴として壊れない形にする視点(システムプロンプトは残す、直近のやり取りは残す、ツール呼び出しと結果は対で扱う)で説明できる
- 要約や消去に伴う副作用(情報欠落・キャッシュ無効化・追加コスト)と、その対策(要約プロンプトのカスタマイズ、直近ターンの保持、キャッシュ境界の設計)をセットで語れる
- しきい値や保持件数を具体的な数値で言える(例: 入力150,000トークンで圧縮が発火する、直近3組は残す、など)
- 「古いメッセージを消せばいい」で終わり、履歴として壊れない形(システムプロンプトやツールの対応関係)を意識していない
- 「要約すれば情報は失われない」と言い切る
- 「コンテキストウィンドウが大きいモデルを使っているから気にしなくていい」と言う
- しきい値や保持件数を一切具体的に言えず、「適当に古いのを削っている」で終わる
深掘り質問の例
- 古いツール結果だけを消す方法と、会話全体を要約する方法、どちらを先に検討しますか。その理由は?
- 要約のプロンプトをカスタマイズしたことはありますか。何を残すよう指示しましたか?
- 削ったあとの履歴が、モデルにとって壊れた形(対応関係が崩れた状態)にならないよう、どう気をつけていますか?
つまずきポイント
「プロンプトキャッシュを使えばコンテキストウィンドウの消費も減る」と思っていた。実際はキャッシュが変えるのは課金対象であって、コンテキストウィンドウのカウント対象からは外れない。
「要約すれば会話の中身は全部保たれる」と思っていた。要約は情報の取捨選択であり、後になって初めて重要だと分かる細かい文脈は失われうる、と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のエンジニアリングブログはこれを「最も安全で軽い圧縮の一つ」と位置づけている。
まとめ
- コンテキストウィンドウは「有限で、埋まるほど精度が落ちる」資源である
- 上限に近づいた・超えたときの挙動はAPIによって異なる(Anthropicは400エラーまたは生成打ち切り、OpenAIは
truncationの設定次第) - 削り方には「先頭から捨てる」「ツール結果だけ消す」「要約する」「外部に逃がす」の4つの型があり、いずれも公式機能として実装が用意されている
- 要約(圧縮)は長時間タスクの主戦略として推奨される一方、情報欠落・キャッシュ無効化・追加コストという副作用を伴う
- しきい値や保持件数を具体的な数値で語れるかどうかが、実務経験の有無を見分ける手がかりになる
次章(第5章)では、「応答が遅い」と指摘されたときに、読み込み段階(prefill)と書き出し段階(decode)のどちらが原因かを切り分ける方法を見ていく。
参考リンク
- Anthropic — Context windows
- Anthropic — Compaction
- Anthropic — Context editing
- Anthropic — Manage tool context
- Anthropic — Token counting
- Anthropic Engineering — Effective context engineering for AI agents
- OpenAI — Compaction guide
- OpenAI — Responses: create
- LangChain — Add and manage memory
- LangChain — trim_messages reference
- Claude Code — Context window
- Claude Code — Model configuration