会話をやり直すか、履歴を圧縮するか?Pi がモデルのコンテキスト自動圧縮をどう解決するか
長いタスクは、モデルの「記憶力」が良いから続くわけではありません。Pi は過去を次々と次のリクエストに詰め込み、収まらなくなると、自分の作業記憶を書き直します。
- コンテキストの圧縮(Compacting context)は、以前の作業をより短い状態要約に書き換え、長いタスクのためにコンテキスト領域を確保することです。
- Pi はデフォルトで直近の約 20k トークンを保持し、次の応答のために 16384 トークンを確保します。これらの数値は Pi の実装であり、業界の一般則ではありません。
- 圧縮は損失を伴う移行です。作業の継続性は保たれますが、詳細は失われ、以前のプロンプトキャッシュは一時的に無効になります。
Pi、Claude Code、Codex にコードの修正、ログの調査、テストの実行などを連続して頼み、タスクが十分に長くなると、compacting context のような表示を目にすることがよくあります。
これはコードを圧縮しているのでも、ファイルを削除しているのでもありません。現在のセッションが、モデルが一度に読み取れる情報量の上限に近づいており、コーディングエージェントが以前の作業記録をより短いバージョンに書き換えて、タスクを続行できるようにしていることを示しています。
この限られた領域は、context window(コンテキストウィンドウ)と呼ばれます。モデルは応答のたびに、このウィンドウに入っている内容だけを参照できます。長いタスクでは、新しいメッセージ、コード、ログ、ツール呼び出し、実行結果が次々と追加され、ウィンドウはどんどん満たされていきます。compacting context が表示されるのは、エージェントが容量の上限に達する前に、今後の作業のための領域を確保する必要があるからです。
Earendil Engineering は、Pi の処理方法を詳しく説明した「How Compaction Works in Pi」という記事を公開しています。Pi はターミナルで動作するコーディングエージェントです。以下では、その具体的な実装について説明します。他のコーディングエージェントも同じ一般的な問題に直面しますが、トリガーとなるしきい値、保持量、要約方法は異なる場合があります。
モデルに記憶はなく、コンテキストを再生しているだけ
エージェントに決済障害の修正を依頼し、最初に「checkout がなぜ 502 を返すのか調べて」とだけ伝えたとします。しかし、モデルが実際に受け取るのは、その言葉だけではありません。system prompt、ツール定義、プロジェクト内のルールファイルも含まれます。ログツールを呼び出すと、そのツールの結果も履歴に追加されます。さらに情報を追加すると、次のリクエストには以前のすべての内容が再び含まれます。
エージェントが隠れた脳内領域に作業を永続的に記憶しているわけではありません。毎回のリクエストで、現在の作業現場をモデルの前に再現しているのです。
それぞれのステップは合理的ですが、累積した結果はただ一つ、履歴は一方的に増え続け、タスクはまだ完了していない可能性があります。コンテキストに収まらなくなると、エージェントは過去をそのまま持ち続けることはできず、どの内容を残す価値があるかを判断する必要があります。
会話をやり直すか、履歴を圧縮するか
現在のセッションをそのまま続行できない場合、エージェントには二つの基本的な選択肢があります。新しいセッションを開始すれば、すぐにすべての領域を確保できますが、目標、完了した作業、重要な決定、未解決の問題も一緒になくなります。あるいは、compaction(圧縮)を行うこともできます。つまり、古い履歴の一部をより短い表現に置き換えて、現在のタスクを続行します。
Pi は二番目の道を選びます。ここでの「圧縮」は、圧縮ファイルのように後で無劣化で復元できるものではありません。Pi は通常、モデルに古い履歴の要約を作成させます。領域は取捨選択によって確保されます。詳細は失われ、表現は要約され、一度だけ出現した情報は徐々に薄れていく可能性があります。
したがって、compaction のより正確な名前は損失を伴う作業状態の移行です。すべての文を保持することではなく、次回のモデルが次のことを把握できるようにすることです。目標は何か、何が行われたか、覆せない決定は何か、現在どこで行き詰まっているか、次に何をすべきか。
Pi が新旧コンテキストをどのように切り分けるか
Pi は会話全体を一度に要約するのではありません。まず最新のメッセージから遡って、切れ目となる線を引きます。現在の公式ドキュメントと固定されたソースコードのバージョンによると、contextTokens > contextWindow - reserveTokens のときに自動圧縮がトリガーされます。デフォルトでは、生成される応答のために 16,384 トークンを確保し、直近の 20,000 トークンを可能な限りそのまま保持します。
20k は予算であり、固定されたメッセージ数ではありません。直近の数ラウンドに大量のログやコードが含まれている場合、保持できるラウンド数は少なくなります。原文ではこれを大まかに5〜20ラウンドと換算していますが、これは保証ではありません。
デフォルトでは新しい応答のために 16,384 トークンを確保します。直近 20k は予算であり固定ラウンド数ではなく、どちらも Pi の設定可能な実装です。
切れ目より前の内容は抽出、シリアライズされ、要約されます。切れ目より後は、元の順序のまま新しいリクエストに含まれます。Pi は通常、一ラウンドが終了した後に自動圧縮をチェックします。モデルがラウンドの途中で制限超過エラーを返した場合のみ、その場で圧縮して再試行することがあります。
ユーザーは /compact [instructions] を実行して、必要なときに早期に圧縮し、追加の指示で要約者に特定の情報を保持するよう促すこともできます。このエントリポイントはタイミングと重点を変えることができますが、それでも損失を伴う要約を無限の記憶に変えることはできません。
要約は作業の引き継ぎ
通常の要約は「何について話したか」に関心があります。作業の引き継ぎが関心を持つのは、次の担当者がすぐに作業を開始できるかどうかです。
Pi は独立したモデルリクエストを開始し、ロールを context summarization assistant に変更し、現在の会話を続行するのではなく、構造化されたチェックポイントを出力するよう要求します。現在のプロンプトでは、六つのカテゴリの情報を保持するよう要求しています。
- Goal:ユーザーが最終的に達成したいこと。
- Constraints & Preferences:違反できない制約と好み。
- Progress:完了済み、進行中、妨げられている項目。
- Key Decisions:重要な選択とその理由。
- Next Steps:次にどの順序で進めるか。
- Critical Context:パス、関数、エラーメッセージ、その他の正確な情報。
生成された結果は、プレーンテキストの CompactionEntry としてセッションに書き戻されます。新しいリクエストは次のようになります。
[system] [tools] [summary] [recent turns] [new user]
プレーンテキストの利点はシンプルです。人間は要約に重要な決定が漏れていないか確認でき、Pi もモデルを切り替えた後もそれを使用し続けることができます。移行されるのは可視の作業状態であり、特定のモデル内部の検査できない記憶ではありません。
ただし、この引き継ぎ書は要約者が認識できたものだけを保持できます。重要な制約が非常に早い段階で一度だけ出現した場合、繰り返しの圧縮によって薄れる可能性があります。本当に失いたくないプロジェクトのルールは、AGENTS.md、タスクの状態、コード、その他の永続的な記録に書き込むのが最善です。
プレフィックスが変わると、古いキャッシュは無効になる
Compaction は領域を確保する一方で、毎回のリクエストで最も敏感な部分であるプレフィックス(前置部分)も変更します。
モデルプロバイダーのプロンプトキャッシュは通常、正確なプレフィックス一致に依存しています。圧縮前は、次のリクエストはほとんどの場合、古い履歴にそのまま追記されるだけです。圧縮後は、古い履歴が新しい要約に置き換えられます。直近の数ラウンドが一字も変わっていなくても、それらの前にある内容が異なるため、古いキャッシュは元の位置から再利用できません。
無効化は一時的です。圧縮後の構造が新しいプレフィックスになり、後続のリクエストはその上にキャッシュを再構築できます。
これはキャッシュを永久に失うことを意味するわけではありません。圧縮後の構造が新しい安定したプレフィックスになり、後続のリクエストはその上にキャッシュを蓄積し続けることができます。これはまた、Pi が可能な限りラウンド終了後に圧縮する理由も説明しています。まずこのラウンドの連続するリクエストが古いプレフィックスのキャッシュの利点を享受してから、コンテキストを書き換えるのです。
圧縮後、すぐに作業を開始できるか
Pi のトレードオフはこれで完全になります。すべての履歴を保持するとコンテキストの上限に達し、履歴を圧縮すると詳細が失われ、キャッシュの再計算というコストが発生します。完全に新しいセッションを開始すると、作業の継続性も放棄することになります。
compaction が良いかどうかを判断するには、四つの質問をするとよいでしょう。直近の作業はどのくらいそのまま保持されているか?要約は目標、決定、進捗、次のステップを保持しているか?結果は人間が確認でき、モデル間で移行できるか?トリガーのタイミングは、残り領域、オーバーフローリスク、キャッシュコストの間で合理的なバランスを取っているか?
優れた compaction は「すべての過去を記憶すること」ではありません。忘却が避けられないことを受け入れ、その上で、本当に次のステップに影響を与える作業状態を次の担当者に引き渡すことです。
Pi Compaction ひと目でわかる
長いタスクでは、メッセージ、コード、ログ、ツールの結果が絶えず次のリクエストに持ち込まれます。Pi はすべてをクリアにするのではなく、古い履歴を作業の引き継ぎに書き換え、最近の内容を保持して続行します。
なぜ compacting context が発生するのか
モデルは応答のたびに現在のコンテキストを読み直す必要があります。履歴は増える一方で、最終的にはウィンドウの上限に近づきます。compaction は、タスクが完了する前に積極的に領域を確保することです。
会話をやり直すことと履歴を圧縮すること
- 会話をやり直すすぐにすべての領域を取り戻せますが、目標、進捗、決定、未解決の問題も一緒になくなります。
- 履歴を圧縮する作業の継続性は保たれますが、古い詳細は要約され、損失を伴う移行となります。
Pi が実際に行う切り分け
- 応答領域の確保contextTokens が contextWindow から reserveTokens を引いた値を超えたときにトリガーされます。デフォルトでは 16,384 トークンを確保します。
- 最近の作業を保持直近の 20,000 トークンを可能な限りそのまま新しいリクエストに含めます。これは予算であり、固定ラウンド数ではありません。
- 古い履歴を要約切れ目より前の内容はシリアライズされ、構造化された要約に書き換えられます。
- 現在のタスクを続行新しいリクエストは、system、tools、summary、recent turns、new user で構成されます。
要約はチャットの概要ではなく、作業の引き継ぎ
- 目標最終的に達成すること
- 制約と好み違反できないこと
- 進捗完了、進行中、妨げ
- 重要な決定選択とその理由
- 次のステップ次にどう進めるか
- 重要なコンテキストパス、関数、エラー
得られる領域は無料ではない
- 詳細の損失要約者が認識できなかった情報は失われる可能性があり、繰り返し圧縮すると特に顕著です。
- キャッシュの再計算古い履歴が新しい要約に置き換わると、正確なプレフィックスが変わり、古いプロンプトキャッシュは一時的にヒットしません。
- 実装は普遍ではない16,384 と 20,000 は Pi の現在の設定可能なデフォルト値であり、他のコーディングエージェントに外挿することはできません。
compaction の良し悪しを判断する
最近の作業、目標、決定、進捗、次のステップが保持されているか、人間が確認できモデル間で移行できるか、トリガーのタイミングが残り領域、オーバーフローリスク、キャッシュコストのバランスを取っているかを確認してください。優れた compaction はすべての過去を記憶することではなく、本当に次のステップに影響を与える作業状態を次の担当者に引き渡すことです。
長いタスクで、作業現場を次の担当者にどう引き継ぐか
開発者checkout がなぜ 502 を返すのか調べて。
Pi私が受け取るのはその言葉だけではなく、現在の作業現場全体も含まれます。
エージェントの継続性は、隠れた記憶ではなく、毎回のコンテキスト再生に由来します。
ウィンドウタスクはまだ終わっていないのに、もうすぐ満杯になりそうだ。
それぞれのステップは合理的でも、積み重なると容量の上限に達します。
Piやり直せばすべての領域を取り戻せますが、作業の継続性は失われます。私は古い履歴をより短く書き換えることを選びます。
Compaction は損失を伴う作業状態の移行であり、無劣化で復元できる圧縮ファイルではありません。
要約者古い履歴を構造化されたチェックポイントに整理します。
最近のメッセージ私は元の順序のまま新しいリクエストに進みます。
Pi はデフォルトで応答に 16,384 トークンを確保し、直近の 20,000 トークンを可能な限り保持します。どちらも設定可能な予算です。
前の担当者目標、制約、進捗、決定、次のステップ、重要なパスはすべてここにあります。
次の担当者すべての会話を再現しなくても、すぐに作業を始められます。
保持されるのは一字一句の履歴ではなく、検査可能で移行可能な作業状態です。
Prompt cache最近のメッセージは変わっていませんが、先頭が変わったので、以前のヒットを利用できません。
キャッシュはその後、新しいプレフィックスの上で再構築されます。本当に失いたくないルールは、要約だけに頼らず、永続的なファイルに書き込むべきです。
