Piにおけるコンパクションの仕組み
コーディングエージェントにおけるコンテキスト管理
大規模言語モデル(LLM)は固定されたコンテキストウィンドウ内で動作するため、一度のリクエストで処理できる入力量に制限があります。コーディングエージェントのセッションでは、システムプロンプト、ツールの定義、会話履歴、およびツールの出力が蓄積されるにつれて、入力が継続的に増加します。この合計がコンテキストウィンドウを超えると、LLMはサイズエラーでリクエストを拒否します。
セッションの失敗を防ぐために、エージェントは新しい会話を開始するか(これにより蓄積されたすべてのコンテキストと以前の決定が破棄されます)、あるいはコンパクションを実装する必要があります。コンパクションは、既存の履歴のより小さく圧縮された表現を作成することで、新しいメッセージのためのスペースを確保します。
Piのコンパクション実装
Piは、最近のメッセージの特定の予算(バジェット)を保持しつつ、古い会話内容を要約することでコンパクションを実現しています。このプロセスは、コンテキスト制限がウィンドウの総サイズに近づいたときに自動的にトリガーされるか、/compact コマンドを介して手動で実行されます。
コンパクションのプロセス
Piのコンパクションは、トークンを無駄にすることなくエージェントが重要な情報を保持できるように、特定のワークフローに従います。
- 保持バジェット: Piは、設定可能な数の最近のメッセージ(デフォルトは20,000トークン、およそ5〜20ターン)をそのまま保持します。
- シリアライズ: 保持のカットオフポイントより前のすべてのメッセージは、抽出され、要約のためにシリアライズされます。
- 特化型リクエスト: Piは、標準的なコーディングアシスタントではなく、「コンテキスト要約アシスタント」に対してスタンドアロンのリクエストを送信します。これにより、Piは要約のために、よりコスト効率の高い別のLLMモデルを使用することが可能になります。
- 構造化出力: コンパクションのプロンプトは、目標、進捗、および主要な決定の3つのセクションに分かれた構造化された要約を明示的に要求します。これは、会話の次のフェーズのための「引き継ぎブリーフィング」として機能します。
統合とポータビリティ
生成された要約は、セッション内でプレーンテキストとして保存されます。このアプローチにより、圧縮されたコンテキストがユーザーにとって読みやすく、かつ異なるLLMモデル間でポータブル(移植可能)であることが保証され、ユーザーは要約された履歴を失うことなくモデルを切り替えることができます。
プロンプトキャッシュへの影響
プロンプトキャッシュは、LLMプロバイダーが会話のプレフィックス(接頭辞)を再利用できるようにすることで、コストとレイテンシを削減します。しかし、キャッシュにはトークン単位での正確な一致が必要です。
コンパクションは、古い履歴の大きなブロックを新しい要約に置き換えるため、会話のプレフィックスを変更します。これにより、既存のプロンプトキャッシュが事実上的に無効化されます。つまり、要約の後に続くすべてのトークン(保持された最近のターンを含む)は、コンパクション後の最初のリクエストにおいて再計算される必要があります。新しい状態が確立された後は、その後続のリクエストは再びキャッシュの恩恵を受けることができます。
代替のコンテキスト戦略とコミュニティの視点
PiはLLMベースの要約を使用していますが、開発者やユーザーは、コンテキストオーバーフローを管理するためのいくつかの代替戦略を提案しています。
プルーニング(枝刈り) vs 要約
一部のユーザーは、要約よりもプルーニング(決定論的な低価値メッセージの削除)の方が優れていると主張しています。
"I find summarized conversations lead to more frustrating future chats because the LLM misses intent and or context."
提案されているプルーニング戦略には、思考のトレース、ツールの呼び出し出力、およびコードベースの探索ログを削除し、ユーザーのメッセージと最終的なアシスタントの結論を保持することなどが含まれます。
アーキテクチャ上の代替案
- ネストされたスレッド: 一つのアプローチは、古いメッセージを、それ自体を要約するサブスレッドに移動させることです。これにより、クリーンな親スレッドを提供しつつ、親スレッドを維持しながら、子スレッドで完全な履歴にアクセスできるようにします。
- 動的プルーニング: 一部の実装では、ラベルを使用して、ツールの呼び出しやチャット履歴の要約をコールラップ(折りたたみ)および展開を動的に行います。
- KVキャッシュの操作: ローカルスタックを実行しているユーザー向けに、GPU上で直接操作を行い、推論中に古いツールの呼び出しを、要約に置き換える、あるいは消去することで、完全な新しいLLMリクエストを回避する方法が提案されています。
- 引き継ぎ (Handoffs): コンパクションではなく、新しい会話セッションのために必要なすべての情報を要約するように現在のLLMに指示する「引き継ぎ」を好むユーザーもいます。
現在のアプローチの限界
標準的なコンパクションの批判者は、128kトークンを解析して小さな要約を生成するためだけに、ローカルLLMにとって計算コストが高すぎる可能性があると指摘しています。さらに、一部のユーザーからは、ツールの呼び出しループが長い場合、エージェントがループの終了までコンパクション制限にチェックを行わないため、ポテンシャル的にメモリ不足(OOM)エラーが発生する可能性があると報告されています。
Sources
関連
- Dispatch
- Dispatch
- Dispatch
- Dispatch