レッスン4: コンパクションとノート: 長時間タスクのコンテキスト管理
学習目標:
- コンパクションとは何か、どう実装されるかを述べる: 会話がウィンドウの上限に近づいたら、メッセージ履歴をモデルに渡して要約させ、その要約から新しいウィンドウを再初期化する
- 「アーキテクチャ上の決定と未解決のバグは残し、冗長なツール出力は捨てる」というルールに従って、1回のコンパクションの要約指示と keep/drop リストを書く
- コンパクションと構造化ノートの役割を区別し、長時間タスクのエージェント向けに書きながら残すノート方式を設計する
前提: 本コースのレッスン1から3を修了し、本シリーズのコース7「Agent Harness Fundamentals: Loops and Control」のハーネスループを自力で書けること | 前: レッスン3 << | 次: レッスン5 >>
1つのウィンドウに収まらないタスク
まずは、遠からず出会う場面から始めましょう。本シリーズのコース7「Agent Harness Fundamentals: Loops and Control」で自分の手で書いたハーネスを、デバッグタスクに向けます。並行実行時にだけ現れる競合状態の修正です。エージェントはファイルを読み、テストを走らせ、コードを編集し、またテストを走らせる。40 ターンあまり経ってもタスクは終わらず、メッセージ履歴は 10 万トークンを超えて膨らみ、ウィンドウは埋まりかけています。
コース7の4つの制御バルブ(最大ターン数、予算、アイドル空転検知、承認バルブ)はここでは役に立ちません。それらが司るのは「ループを暴走させない」ことですが、ループの挙動自体は正常です。タスクそのものが単に長いだけなのです。これは事故ではなく、ループの本性です。"An agent running in a loop generates more and more data that could be relevant for the next turn of inference"1 — ツール出力、途中の結論、失敗した試行が、すべてメッセージ履歴に積み上がっていきます。
そしてウィンドウはタダではありません。大量のコンテキストを解析するモデルは "attention budget" から引き出しており、"Every new token introduced depletes this budget by some amount."1 トークンが積み上がるほど、モデルの正確な想起能力は落ちます。"as the number of tokens in the context window increases, the model's ability to accurately recall information from that context decreases"1 — 崖ではなく緩やかな下り坂ですが、下り坂であることに変わりはありません。だからこそ "context, therefore, must be treated as a finite resource with diminishing marginal returns."1 Claude Code のベストプラクティス文書はもっと率直です。"Claude's context window fills up fast, and performance degrades as it fills"、そして "The context window is the most important resource to manage."2
1つのウィンドウに収まりきらないほどタスクが長くなったとき、武器は2つあります。コンパクションと構造化ノートです。このレッスンでは両方を通しで扱います。
コンパクション: 要約して、新しいウィンドウを開く
コンパクションは名前のとおりです。"taking a conversation nearing the context window limit, summarizing its contents, and reinitiating a new context window."1 最後の部分に注目してください。要約を古い会話に押し戻して詰め込み続けるのではありません。再初期化するのです。古いウィンドウは丸ごと捨てられ、新しいウィンドウはシステムプロンプトとサマリーだけを携えて身軽に出発します。
実装は聞こえほど大げさではありません。"passing the message history to the model to summarize and compress the most critical details."1 つまりコンパクションそれ自体が、追加のモデル呼び出し1回です。コードにするとおおよそ次のようになります(formatHistory はメッセージ配列を読める平文に連結するだけで、実装は省略します)。
これをコース7のループに継ぎ足すのに必要な発想は1つだけです。各ターンの先頭でメッセージ履歴のトークン使用量を確認し、上限に近づいたら compact() を呼んで messages 配列を戻り値で丸ごと置き換えます。実際にこれをハーネスへ組み込む方法 — トリガー閾値をどう決めるか、コンパクションが失敗したらどうするか — はレッスン6の実践材料です。ここでは仕組みを押さえておけば十分です。
コンパクションの勘所: 何を残し、何を捨てるか
コンパクションで難しいのは「どう要約するか」ではなく「何を残し、何を捨てるか」です。方向自体ははっきりしています。"preserves architectural decisions, unresolved bugs, and implementation details while discarding redundant tool outputs."1
なぜこのトレードオフなのでしょうか。エージェントが新しいウィンドウで「目を覚ます」場面を想像してください。そのサマリーがエージェントの記憶のすべてです。圧縮の方向を間違えたときのコストは具体的です。たとえば要約指示に「会話内容を簡潔に要約してください」としか書かなかったとします。モデルは「orders/service.js に未完了の競合状態がある」を何気なく落としてしまう。エージェントは「完了」と記された記録だけを見て目を覚まし、仕事は終わったと宣言するか、すでに直した箇所をつつき回すかのどちらかになります。たった1回のコンパクションで、40 ターン分の作業が脱線するのです。
逆向きに見れば、冗長なツール出力こそ最も太い削り代です。1回の grep が 200 行のマッチを返しても、有用なシグナルは次のステップの結論「updateStatus 関数に絞り込んだ」にすでに取り込まれています。生の 200 行が残り続けても、アテンション予算を燃やすだけで、次の一手の判断価値はほとんど増えません。1
実務的なセルフチェックがあります。要約指示を書いたら、実際の長い会話を1回コンパクションにかけ、サマリーだけを見て3つの質問に答えてみてください。「次に何をすべきか」「どの決定が確定しているか」「どの穴がまだ埋まっていないか」。3つとも澄んだ答えが出れば、その指示の keep/drop ルールは合格です。どれか1つでも空白になるなら、その keep ルールを書き足しに戻ってください。
製品でのコンパクション: 自動コンパクションと /clear
毎日使っているツールに、出来合いの参照実装があります。Claude Code は "automatically compacts conversation history when you approach context limits, which preserves important code and decisions while freeing space"2 — 上で手書きした compact() と同じ仕組みで、発動条件と keep/drop ルールを製品側が用意してくれているだけです。
ただしコンパクションだけが選択肢ではありません。無関係な新しいタスクに切り替えるなら、古いコンテキストは役に立たないどころか有害です。"Long sessions with irrelevant context can reduce performance."2 そういうときドキュメントはこう言います。"Run /clear between unrelated tasks to reset the context window entirely"2 — 要約もせず、保存もせず、まるごとリセットです。理屈は単純で、コンパクションはモデル呼び出しを1回消費し、keep/drop の判断を誤るリスクを抱えます。無関係なタスクなら、いっそクリアするほうが安上がりで綺麗です。コンパクションが受け持つのは「同じタスクがまだ終わっていない」、/clear が受け持つのは「これから別のことをする」です。
この文書にはもう1行、手元に置く価値のある一文があります。"A clean session with a better prompt almost always outperforms a long session with accumulated corrections."2 言い換えれば、セッションの履歴が「違う、やり直して」「まだ間違っている」で主に埋まっているとき、その履歴が次の一手にもたらす価値はおそらく負です。セッションを開き直し、学んだことを新しいプロンプトに直接焼き込むほうが、荷物をすべて引きずり続けるより勝ることが多いのです。
構造化ノート: 重要な状態をウィンドウの外に書く
コンパクションには生まれつきの弱点が1つあります。受け身であることです。ウィンドウが埋まりかけるまで待ってから振り返って要約するので、何が生き残るかはその瞬間の判断にすべてかかっており、判断は失敗しうるものです。情報が新鮮なうちに残しておく方法はないのでしょうか。
あります。しかも単純です。"the agent regularly writes notes persisted to memory outside of the context window."1 "Like Claude Code creating a to-do list, or your custom agent maintaining a NOTES.md file."1 冒頭の競合状態のタスクをもう一度取り上げると、合格点のノートはおおよそこうなります。
配線の仕方はコース7で学んだとおりです。エージェントにファイル書き込みツールを与え、システムプロンプトに要件を1つ足します。「重要な決定を下したとき、新しい問題を見つけたとき、1つの段階を終えたときは、まず NOTES.md を更新してから続行すること」。これ以降、ウィンドウ内の重要な状態は、ウィンドウの外に控えの写しを持ちます。ウィンドウがどうコンパクションされようと再起動されようと、ノートはディスクに残り、新しいウィンドウが最初にすることはそれを読み戻すことです。
この手はコーディングタスク専用ではありません。"Claude playing Pokémon demonstrates how memory transforms agent capabilities in non-coding domains."1 Anthropic のマルチエージェントリサーチシステムも、長時間タスクに同じことをしています。"agents summarize completed work phases and store essential information in external memory."3
役割分担: コンパクションは保険、ノートは日常
2つの武器を並べると、役割分担がはっきりします。コンパクションは受動的です。ウィンドウが上限に近づいたときに発動し、そのタイミングは選べず、しかも損失をともないます。何が生き残るかはその瞬間の keep/drop 判断次第です。ノートは能動的です。重要な状態が生まれたその場で書き、内容は無損失で、コストは毎回数行のファイル書き込みだけです。一言でいえば、ノートは日常業務、コンパクションは保険です。
2つは衝突しません。互いを補強します。ノートを丁寧に書くほど、コンパクションが何かを落としたときの被害は軽くなります。サマリーが細部を取りこぼしても、ノートにはまだ残っています。逆向きに見れば、コンパクションという保険があるからこそ、ノートは網羅的である必要がなく、「新しいウィンドウで目を覚ましたエージェントが必ず知っておくべき」いくつかの区分だけで済みます。
分量の感覚も大事です。すべてのタスクがこの仕掛けに見合うわけではありません。Anthropic の指針は "you should consider adding complexity only when it demonstrably improves outcomes."4 動詞に注目してください。consider(検討する)です。禁止ではなく、天秤にかける姿勢です。10 ターンで終わるタスクにとって、コンパクションもノートも余った部品です。最も単純なループから始め、実際に天井にぶつかってから足してください。
最後に境界を2つ。このレッスンが扱わない答えを探して時間を無駄にしないために。
- ノートファイルのセッションをまたぐ永続化 — どう整理するか、新しいセッションでどう復元するか、長期的にどう保守するか — は本シリーズのコース5「エージェントメモリと状態」の主題です。このレッスンが気にするのは、1つの長時間タスクの中でノートがウィンドウの負荷をどう軽くするか、それだけです。
- 長時間タスクの扱いには、実は3手あります。"compaction, structured note-taking, and multi-agent architectures,"1 いずれもエージェントに "maintain coherence, context, and goal-directed behavior over sequences of actions"1 させることを狙ったものです。最初の2つは終わりました。3つ目 — きれいなウィンドウを持つサブエージェントにタスクを分割する — はレッスン5です。
まとめ
- コンパクション = 会話がウィンドウの上限に近づいたときに "passing the message history to the model to summarize and compress the most critical details"1 し、そのサマリーから "reinitiating a new context window"1 すること。古い会話への追記ではなく、再初期化です
- コンパクションの勘所は残すか捨てるかの選択にあります。"preserves architectural decisions, unresolved bugs, and implementation details while discarding redundant tool outputs"1。圧縮の方向を間違えると、エージェントは自分が何をしていたか忘れて目を覚まします
- Claude Code は "automatically compacts conversation history when you approach context limits, which preserves important code and decisions"2。無関係なタスクの間では
/clearで丸ごとリセットします。"A clean session with a better prompt almost always outperforms a long session with accumulated corrections"2 - 構造化ノート: "the agent regularly writes notes persisted to memory outside of the context window"(to-do リスト、
NOTES.md)1。コンパクションは受動的な保険で損失をともない、ノートは能動的な外部化で書きながら残します - 長時間タスクの3手は "compaction, structured note-taking, and multi-agent architectures"1。最初の2つは手中にあり、3つ目はレッスン5です。ノートのセッションをまたぐ永続化は本シリーズのコース5「エージェントメモリと状態」の主題です
Footnotes
-
Effective context engineering for AI agents — Anthropic Engineering — https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 ↩17 ↩18
-
Best practices for Claude Code — Claude Code Docs — https://code.claude.com/docs/en/best-practices ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7
-
How we built our multi-agent research system — Anthropic Engineering — https://www.anthropic.com/engineering/multi-agent-research-system ↩
-
Building Effective AI Agents — Anthropic Engineering — https://www.anthropic.com/engineering/building-effective-agents ↩
練習
ある人がハーネス用にこの「コンパクション」関数を書き、ウィンドウが満杯に近づいたときに呼び出しました。
レベル2: 「コンパクション後の記憶喪失」を診断する組み込んだあと、エージェントはターン45でコンパクションを発動しました。そこであなたは2つの症状を観察します。1つ目、ターン47で「テストフレームワークは node:test か vitest か」という、ターン3で vitest と決着済みの問題を蒸し返し始めたこと。2つ目、ターン5に記録された未解決の競合バグに一度も触れず、数ターン後にタスク完了を宣言したこと。両方の症状の原因を説明し、2層の修正を示してください。