世界を動かす技術を、日本語で。

Piにおける圧縮の仕組み

2026年8月14日原文(earendil.com)

概要

  • LLMのコンテキストウィンドウ の制限による履歴圧縮(コンパクション)の必要性
  • Piなどのコーディングエージェント でのコンパクション発生タイミングと仕組み
  • 会話履歴の要約・圧縮方法 とPi独自の実装ポイント
  • プロンプトキャッシュ への影響とコスト最適化の工夫
  • カスタム圧縮プロンプト による拡張・実験の可能性

コーディングエージェントにおけるコンパクションの仕組み

  • LLM(大規模言語モデル)コンテキストウィンドウ により処理可能な入力量が制限
  • コーディングエージェント では会話履歴やツール呼び出し結果がリクエストごとに蓄積
  • 履歴が コンテキストウィンドウ を超えると エラー (リクエストサイズ超過)発生
  • 新規会話開始または 履歴の要約(コンパクション) で対応
  • コンパクションは 古い履歴を要約し、最新メッセージを保持 することで、会話継続を可能化

Piのコンパクション実装

  • Pi は会話が長くなると自動または手動(/compactコマンド)で コンパクション を実行
  • ターン終了時 に自動チェック、または コンテキストエラー発生時 に即時実行
  • 直近のメッセージのみ保持 し、それ以前を要約
  • 保持メッセージ数 はトークン数で調整(デフォルト2万トークン、約5~20ターン分)
  • 要約時は Pi専用プロンプト を使用し、目的・進捗・重要決定事項を構造化してまとめる
  • 要約結果は セッション内にテキストとして保存 し、モデル切替や移行も容易

プロンプトキャッシュとコンパクションの関係

  • プロンプトキャッシュ は同一会話内のリクエストコスト最適化に利用
  • コンパクション実施後 はキャッシュのプリフィックスが変わるため、一度キャッシュが無効化
  • 以降のリクエストでは新しいプリフィックスで再度キャッシュが有効化
  • キャッシュ無効化により、 一時的にコスト増加 するが、その後は再び最適化

Piの拡張性とカスタムコンパクション

  • Piは拡張性が高く、独自のコンパクション手法を実装可能
  • カスタムプロンプト による要約機能のテストや拡張が容易
  • Piに拡張リクエストを行い、 独自の要約アルゴリズム を組み込むことが可能

このように、コーディングエージェントでの 会話履歴圧縮(コンパクション) は、長時間のセッションや大規模なやり取りを効率的に継続するための重要な技術。 Pi は柔軟かつ効率的なコンパクション機能を備えており、カスタマイズや最適化も可能。

Hackerたちの意見

コンパクションは、ローカルのLLMを一つだけ動かしていると辛いよね。これを避ける一番の方法は、コンテキストをできるだけ小さく保つことだと思う。俺が役立つと思うトリックは、二つのKVキャッシュを持つモデルを使うこと。最初のキャッシュがトークンを生成している間に、二つ目のキャッシュがそれをすぐに要約するんだ(ツールの時間)。その後、ハーネスは二つ目のKVキャッシュに切り替わって、新しく生成された入力トークンを受け取る。一方、最初のキャッシュはコンパクトな要約トークンに置き換えられる。これって一種のピンポンみたいなもので、時間を短縮するためにスペースを交換してる感じ。まだ実験中だけど、うまくいってるみたいだし、GPUの利用率も改善されるのがいいね。ちなみに、俺は自分のハーネスとモデル提供コードを持ってるけど、他のハーネスやモデルサーバーでも簡単に実装できるよ。

まずはLLMに一連の質問をして、コンテキストが自分にとって十分になるまで進めることが多いんだ。その後、必要な作業をお願いするけど、/treeを使って前のコンテキストに戻る感じ。要するに、LLMから必要な答えを引き出すために質問をするってこと。計画ややることリストの答えだったり、何かをコーディングしたり変更したりするタスクだったりするね。

コンパクションに関しては、今の解決策がどれも好きじゃないな。何を要約すべきかを指定できる方法があればいいのに。大抵の時は、ノイズの多いMCPツールの呼び出しやテストの実行結果をコンパクトにしたいだけなんだ。要約するものを選ばせて、残りはそのままにしておいてほしい。

Piでそれができるよ!「拡張機能はコンパクションとブランチ要約の両方をカスタマイズできる」ってさ。https://pi.dev/docs/latest/compaction ただ、コンパクションを intercept して、欲しいものだけ残すか、他の方法で書き換える拡張機能を作ればいいだけ。数行で済むはず。

サブエージェントが気に入るかもね。エージェント > サブエージェントがエージェントのコンテキストを受け取る(おそらくキャッシュされてる)→ツール呼び出し→コンパクト/要約→メインエージェントに戻る。

おそらく、piの/handoff(または少なくともoh my pi)が君が探してるものだよ。

ちょっと軽く言うけど、コンパクションの限界に近づいたらエージェントにファイルを書かせればいいんじゃない?僕は大体50-70%のコンテキスト利用率にしてから、エージェントに会話を要約してファイルに保存させて、その後手動で/clearして、「さっきの会話を続けよう」って言うことが多いよ。要約を先に確認して、必要なら変更もできるし。

コンパクションの代わりに、プルーニングの成功した実装を見たことある人いる?つまり、エージェントが会話履歴を見て、価値の低いメッセージを削除するってこと。例えば、時々コンテキストが余計な話題やツール呼び出しの出力、価値の低いコードベースの探索で埋まっちゃうことがある。大抵は、要約するよりも会話の履歴を保持しておきたいんだ。要約された会話は、LLMが意図やコンテキストを見逃すから、将来のチャットがもっとイライラすることになると思う。(あるいは、LLMの出力が段落だらけになることで、次のトークン予測が鈍くなるのかな?よくわからないけど。)

コストが下がれば開ける戦略がたくさんあると思うけど、今は最後の瞬間まで待つ以外のことをすると、キャッシュ率とコストが毎回ダメージを受けるよね。

これは二つの組み合わせみたいな感じだね:https://github.com/spott/pi-task-compaction まだ試してる最中だけど、基本的にはモデルが領域を定義して、begin_taskとend_taskでマークするんだ。end_taskはその領域全体のかなりしっかりした要約も必要なんだよ。それで、その領域全体を引っ張ってきて要約に置き換える。モデルが望めば、会話から削除された出力を実際に見ることもできるけど、実際には要約が十分良いから、そこまで必要ないみたい。5.6 solで使ってるけど、長いセッションでも最後には約6%のコンテキストしか使ってないね。

これにはすごく興味があるよ。Claudeのセッションがコンパクトになると、すぐにタスクの重要な側面を再アラートしないといけない気がするけど、実際には低スキルのエージェントがコンテキストウィンドウ全体を半連続的にクロールして、削除や要約する部分を指名することも可能だと思う。もっと高いレベルでは、例えば「実はこの問題の三つの異なる側面に取り組んでることに気づいたから、コンテキストをその三つに分けて、他の部分の高レベルの要約だけを保持する」みたいな感じ。特定のリクエストのために他のエージェントにコントロールを渡すべきかどうかを知るためにね。これってサブエージェントみたいな感じだけど、明確なタスク→作業→結果を返す→終了のモデルじゃなくて、自分がマルチタスクしてるやり方に近いと思う。いくつかの長期的な実行スレッドを維持して、最も重要な作業に集中するために他のものを「忘れる」必要があるんだ。

自分のaichatツールコレクションには、いくつかのプルーニングのバリエーション(長いツール出力のトリミング、エージェント主導のトリミングなど)があるよ:https://pchalasani.github.io/claude-code-tools/tools/aichat/...

Hacker Newsで議論の続きを見る