Lesson 06 · メモリ

コンテキストが溢れたら、削る技術

「The agent can forget strategically and keep working forever.」戦略的な忘却は工学的な能力だ。

⏱ 約 12 分 · 📝 3 つのインタラクティブ要素 · 🧑‍💻 出典 shareAI-lab · s06_context_compact.py

なぜ compact が必要なのか

agent を長時間動かすと messages[] が肥大化する:read_file のたびに数千 token、bash のたびに数百 token、さらに各ターンのモデルの思考テキストが積み上がる。50ターン動かせば context は100K 超えになりうる。2つの結果:

  • モデルの上限に当たる:ウィンドウサイズを超えるとクラッシュするか、API 呼び出しコストが線形に増加する。
  • 注意力の希薄化:今手がけているタスクが30ターン前の無関係な tool_result に埋もれ、モデルが迷走し始める。

s06 のアプローチ:agent に重要でない内容を積極的に忘れさせ、重要な状態だけ保持する。3層の仕組み、軽い順に解説する。

Layer 1 · micro_compact(毎ターン静かに実行)

最も安い層だ。毎回の LLM 呼び出し前に一度走り、3つより古い tool_result をプレースホルダーに置き換える:

# 10ターン前より古いほとんどの tool_result はこうなる:
{
  "type": "tool_result",
  "tool_use_id": "toolu_01A",
  "content": "[Previous: used bash]"   # 数千文字から数十文字へ
}

例外が一つある:read_file の結果は圧縮しない。なぜか?read の出力は参照資料であり、圧縮したらモデルが再度読み直す必要が生じて、かえってコストが高くなるからだ。

PRESERVE_RESULT_TOOLS = {"read_file"}  # 永遠に圧縮しない

micro_compact がターンごとに古い結果を消化する様子

以下で10ターンのインタラクションをステップごとにシミュレートし、各ターン前に micro_compact を一度実行する。messages[] 内の古い tool_result が [Previous: ...] に置き換わり、最新の3つだけ完全な形で残るのを確認しよう。

Layer 2 · auto_compact(閾値超えで発火)

micro を走らせ続けても、ある規模を超えると溢れる。s06 には閾値(デフォルト 50000 token)が設定されている:

  1. token 数を見積もる len(str(messages)) // 4(粗いが十分)。
  2. 閾値超過 → 完全な transcript を .transcripts/transcript_TIMESTAMP.jsonlディスクに書き出す(バックアップ)。
  3. LLM に会話全体の summary を生成させる。
  4. messages 全体を一行の "[compressed] SUMMARY..." に置き換える。

代償は明白——具体的なツール出力や会話のトーンが失われ、概要だけ残る。しかし agent は作業を続けられる——これが核心的なメリットだ。

Layer 3 · モデル自身が compact ツールを呼ぶ

auto_compact は harness が自動的に発火させるもので、モデルは知らない。Layer 3 は逆だ:モデルに compact ツールを与え、それを能動的に呼ばせる——前段の探索がもう不要と判断したときや、新しいフェーズを始めたいときなどに。

モデルが呼ぶ:

tool_use("compact", focus="keep the API design decisions")

auto と同じ処理が発火するが、focus パラメータを渡して要約時に重点的に保持すべき内容を指定できる。実際の場面で非常に役立つ——モデルは「前半フェーズが終わった」とわかるので、harness のヒューリスティックより正確だ。

どの層が適切か:判定問題

以下のシナリオで、micro / auto / manual のどの発火が最も適切かを選ぼう。

Interactive

Widget 1 · Micro Compact · tool_result がターンごとに老化していく

Step で一歩ずつ進め、古い tool_result がどのように [Previous: used X] に置き換えられるかを確認しよう。最新の3つは完全な形で残る。read_file は圧縮されない(緑でハイライト)。

Turn: 0 · Tokens: ~0
Interactive

Widget 2 · Threshold Simulator · token が増えると各層がどう反応するか

スライダーで token 数を調整し、3層のどれがアクティブになるかを確認しよう。

3000
Interactive

Widget 3 · どの層が適切か · 6つのシナリオの判定問題

各シナリオで micro / auto / manual を選択し、それぞれがどんな状況に適しているか確認しよう。

正解 0 / 6