サブエージェントのautoCompactWindowで圧縮を早める — Claude Code
Claude Code v2.1.296で、サブエージェントのfrontmatterと--agents定義にautoCompactWindowを書けるようになりました。書き方、記載のない点、既存の圧縮設定との使い分けをまとめます。
サブエージェントの定義ファイルに autoCompactWindow を1行足すと、そのサブエージェントだけ、メインの会話より早く自動圧縮させられます。Claude Code v2.1.296で加わった書き方です。ただし、値の単位や下限はサブエージェントのドキュメントに載っていません。この記事では、書き方、載っていない点の扱い、似た設定との使い分けを説明します。
autoCompactWindowをサブエージェントに書く
追加された内容は、更新履歴の1行に収まっています。サブエージェントのfrontmatterと --agents の定義に autoCompactWindow を加え、メインの会話の窓より早く自動圧縮できるようにした、という内容です。
ファイルで定義するサブエージェントなら、frontmatterに書きます。値は設定ファイルのキーと同じトークン数を前提にした例です。
---
name: log-digger
description: 長いログを順に読み、原因の候補を短く返す
tools: Read, Grep, Bash
autoCompactWindow: 150000
---
あなたはログ調査の担当です。見つけた事実だけを、行番号つきで報告してください。起動時にJSONで渡す --agents では、同じ名前のキーを定義に足します。
claude --agents '{
"log-digger": {
"description": "長いログを順に読み、原因の候補を短く返す",
"prompt": "見つけた事実だけを、行番号つきで報告してください。",
"autoCompactWindow": 150000
}
}'150000 という値に根拠はありません。あくまで書式を見せるための例です。
値の単位と下限は、サブエージェントの側に記載がない
ここが最初の落とし穴です。サブエージェントのドキュメントにあるfrontmatterの表には、name から experimental までのフィールドが並びますが、autoCompactWindow の行は見当たりません。--agents の節も同様です。サブエージェントの記載は、更新履歴の1行が唯一の根拠になります。
一方、同じ名前の設定キーには、数値の範囲が書かれています。
| 設定場所 | 値 | 範囲の記載 |
|---|---|---|
設定ファイルの autoCompactWindow | 値トークン数(未設定ならモデルに合わせた既定) | 範囲の記載100000〜1000000。モデルのウィンドウで頭打ち |
CLAUDE_CODE_AUTO_COMPACT_WINDOW | 値整数のみ(500k は不可) | 範囲の記載100000〜1000000 |
| サブエージェントのfrontmatter | 値記載なし | 範囲の記載記載なし |
設定キーと同じ範囲だと推測するのは自然ですが、推測にとどまります。下限を下回る値が切り上げられるのか、無視されるのか、エラーになるのかも読み取れません。小さな値を入れる前に、後述の手順で実際の動きを確かめておくと安心です。
なお、既定に戻す指定は、メインの会話側にしかありません。/autocompact auto と --autocompact auto は、そのセッションをモデルに合わせた既定の窓に戻すコマンドとフラグです。サブエージェントのfrontmatterに同じ auto を書けるかどうかは、どのページにも記載がありません。既定に戻したいときは、フィールドごと消すのが手堅い方法です。
もう1つ、見落としやすい点があります。frontmatterのフィールド名は表の綴りと完全に一致させる必要があり、認識できないフィールドは、エラーを出さずに無視されます。v2.1.296より古いClaude Codeでは autoCompactWindow が未知のフィールドとして黙って捨てられるため、定義ファイルをチームで共有しているときは、全員のバージョンが揃っているかも効き目に響きます。
早めに圧縮したいのは、どんなサブエージェントか
サブエージェントは、新しい独立したコンテキストウィンドウで始まります。会話の履歴や、Claudeがすでに読んだファイルは引き継がれません。起動時に持つのは、サブエージェント自身のシステムプロンプト、委任メッセージ、CLAUDE.md、git status、事前読み込みしたスキルです。
つまり、短い調査で終わるサブエージェントは、そもそも圧縮に届きません。窓の設定が効いてくるのは、次のように長く走るものです。
- 大量のログやテスト出力を、何周もかけて読むもの
- 広いリポジトリを横断し、ファイルを読み続けるもの
- バックグラウンドで長時間動き、途中で人が確認しないもの
1Mのウィンドウを持つモデルは、既定では約967Kトークンまで圧縮されません。そこまで膨らむ前に切り上げたいサブエージェントには、小さな窓を決めておく意味があります。一定の大きさを超えた時点で要約に切り替わり、以降のコンテキストが小さく保たれます。
早く圧縮すると失うもの
圧縮は要約です。早く圧縮するほど、要約に置き換わる範囲が広がります。調査の途中で見つけた行番号や、却下した仮説のように、後で効いてくる細部が削られるおそれがあります。
そこで、定義ファイルのプロンプトに「見つけた事実は、その都度、番号つきで書き出す」といった指示を入れておくと、要約を挟んでも手がかりが残りやすくなります。窓を小さくするときは、プロンプトの側でこの備えをセットにしておく形です。
同じ目的の設定との使い分け
サブエージェントの圧縮を早める手段は、これまでにもありました。決め方が違うので、並べて見ます。
サブエージェントの圧縮を早める2つの手段
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE
自動圧縮のウィンドウに対する割合(1〜100)で、圧縮のタイミングを決めます。50 のような低い値で早まります。メインの会話とサブエージェントの両方に効くため、サブエージェントだけを狙えません。既定の割合より大きい値は無視され、遅らせる用途には使えません。
サブエージェントのautoCompactWindow
サブエージェントの定義に書くため、対象を1つに絞れます。メインの会話は既定の窓のままです。値の書式と、環境変数との優先関係は、サブエージェントのドキュメントに記載がありません。
役割分担は単純です。「特定のサブエージェントだけを早く圧縮したい」なら、frontmatterの autoCompactWindow が合います。「全部をまとめて早めたい」なら、環境変数の割合指定が手早い手段です。メインの会話の窓を決める方法は、autocompactの使い方にまとまっています。
環境変数が設定されているときの優先関係
CLAUDE_CODE_AUTO_COMPACT_WINDOW が設定されていると、/autocompact、--autocompact フラグ、設定ファイルのキーのすべてに優先します。サブエージェントのfrontmatterがこの並びのどこに入るかは、記載がありません。CIや共有の開発環境でこの環境変数を固定しているなら、frontmatterの値が効いているかを確かめておくと安心です。
効いているかを、サブエージェントのtranscriptで確かめる
圧縮が起きると、サブエージェントのtranscript(会話記録)にイベントが残ります。compact_boundary という種別のレコードで、圧縮の直前に何トークン使っていたかが preTokens に入ります。ファイルは ~/.claude/projects/{project}/{sessionId}/subagents/ の下に、agent-{agentId}.jsonl の名前で保存されます。
設定した窓で圧縮が起きたかを見る手順
- 1
サブエージェントを長めの作業で走らせる
窓を超えるまで読み続ける作業を依頼します。短い作業では、圧縮が起きないまま終わります。
- 2
圧縮の記録があるtranscriptを探す
次のコマンドで、圧縮を含むファイルを見つけ、
preTokensの行だけを取り出します。grep -l compact_boundary \ ~/.claude/projects/*/*/subagents/agent-*.jsonl grep -h -A4 compact_boundary \ ~/.claude/projects/*/*/subagents/agent-*.jsonl | grep preTokens - 3
preTokensを読む
preTokensが、指定した窓の近くにあれば、値が効いています。メインの既定の窓に近い値なら、frontmatterが読まれていません。
この確認は、値の単位や下限の挙動を知る手がかりにもなります。最初は少し大きめの値から試し、preTokens が想定どおりに並ぶのを見てから、小さくしていくやり方が安全です。
メインの会話が圧縮されても、サブエージェントのtranscriptは影響を受けません。別々のファイルに保存されるためです。逆に言えば、サブエージェントの窓を小さくしても、メインの会話の圧縮のタイミングは変わりません。
既定の圧縮タイミングから、値を逆算する
autoCompactWindow に入れる値は、そのモデルが何も指定しなければどこで圧縮するかとの差で決まります。モデルごとの既定は次のとおりです。
| 条件 | 既定の圧縮タイミング |
|---|---|
| 1Mのウィンドウを持つモデル(Fableシリーズ、Sonnet 5以降、Haiku 5.5、Opus 4.7以降) | 既定の圧縮タイミング約967Kトークン |
| 拡張コンテキストなしのSonnet 4.6 / Opus 4.6 | 既定の圧縮タイミング200Kの境界 |
CLAUDE_CODE_DISABLE_1M_CONTEXT=1 を設定した1Mモデル | 既定の圧縮タイミング200Kの境界 |
| クラウドセッション | 既定の圧縮タイミングモデルの上限に近づいたとき |
1Mモデルのサブエージェントなら、150000を指定すると約967Kから大きく前倒しされます。200K級の窓では、同じ150000でも前倒しは数万トークンです。下限が100000なので、早められる幅そのものが小さくなります。
値を決める順序は、次のとおりです。まず使っているモデルの既定を確かめ、早めたい幅を決めます。次に環境変数が固定されていないかを見て、最後に大きめの値からtranscriptで動きを確かめます。
モデルとeffortを定義側で決める流れは、サブエージェントのeffort指定と同じ考え方です。モデルの配分はサブエージェントのモデル配分設計、サブエージェント全般の仕組みはサブエージェント完全ガイドで扱っています。
圧縮後に何が残るか
サブエージェントの圧縮は、メインの会話と同じロジックで動き、トリガーの条件も同じです。transcriptには compact_boundary のレコードが1件ずつ残ります。trigger に自動圧縮かどうか、preTokens に圧縮前の使用量が入る形です。要約の中身がどこまで引き継がれるかは、サブエージェントのページに記載がありません。前に触れたとおり、手がかりはプロンプトの指示で書き出させておくほうが確実です。
まとめ
autoCompactWindow は、サブエージェントごとに圧縮の時期を分けるための1行です。更新履歴にしか記載がないため、単位、下限、環境変数との優先関係は、手元で確かめながら決めることになります。まずは長く走るサブエージェントを1つ選び、preTokens で動きを見るところから始めるのが確実です。