# 圧縮タイミングをアプリ側で制御するCompaction設計

> Claude APIのCompaction On Demand（2026年9月14日ベータ、ヘッダーcompact-2026-09-04）は会話の圧縮タイミングをアプリ側が選べる。既存の閾値圧縮との違いと実装パターンを解説する。

- Canonical: https://kuucorp.com/blog/claude-compaction-on-demand-background-loop-design/
- Date: 2026-10-07
- Last modified: 2026-10-07
- Publisher: Kuu株式会社 (https://kuucorp.com)

---
長時間稼働するエージェントの会話は、何ターンか進むとコンテキストウィンドウを食い尽くす。これまでAnthropicが提供してきた圧縮は、入力トークンが閾値を超えた瞬間にAPI側が自動で圧縮する仕組みだけだった。アプリがいつ圧縮するかを選べず、バックグラウンド実行もできない。2026年9月14日にベータ公開された[Compaction On Demand](https://platform.claude.com/docs/en/build-with-claude/compaction-on-demand)は、この制御をアプリ側に戻す新しいAPI機能だ。

## Compaction On Demandとは何か

> Compaction On Demandは、圧縮の実行タイミングをAPIではなくアプリ側が選べる新しい圧縮方式だ。

ベータヘッダー`compact-2026-09-04`を付け、リクエストに`"compaction": {"type": "summarize"}`を含めると、Claudeはそのリクエストの会話全体を要約した`compaction`ブロックだけを返す。応答は生成されず、`stop_reason`は`"compaction"`になる。このブロックには要約テキストと署名（`signature`）が入り、以降のリクエストでは要約済みのメッセージを削除し、ブロックを`messages`の先頭に置いて送り直す。既存の閾値圧縮（`compact-2026-01-12`）はAPIが判断してブロックを通常の応答に続けて返すが、Compaction On Demandは圧縮専用のリクエストを明示的に送る点が根本的に異なる。

## 圧縮ループはどう実装すればよいか

> トークン予算を超えたら圧縮リクエストを送り、返るブロックで履歴全体を置き換える。

実装パターンは単純だ。各ターンの応答から`input_tokens + output_tokens`を累積し、設定した閾値を超えたら次のユーザー発話を待たずに`compaction`パラメータ付きリクエストを送る。`stop_reason`が`"compaction"`であれば、履歴を「返ってきた`compaction`ブロックを含むアシスタントメッセージ1件」に完全に置き換える。追記ではなく置換であることが重要で、要約済みのメッセージが先頭以外に残っていると次のリクエストは`compaction_block_misplaced`エラーで400になる。要約プロンプトは`instructions`（最大16,384字）で独自のものに置き換えられ、特定のエンティティ名や未解決の依頼を残すよう指示できる。この要約呼び出し自体の課金は`usage.iterations`の`compaction`エントリに記録され、トップレベルの`input_tokens`/`output_tokens`はゼロになる。

## エラー時はどう扱えばよいか

> 要約が得られない場合もAPIは200を返すため、`stop_reason`で成否を判定する。

要約呼び出しがテキストで終わらず終了した場合（`max_tokens`で途切れた、ツールを呼んでしまった、拒否された等）、レスポンスは200のままブロックを含まない。`stop_reason`が`"max_tokens"`なら`max_tokens`を増やして再送し、`"tool_use"`なら「ツールを呼ばない」と明示した`instructions`を付けて再送する。`"refusal"`や`"end_turn"`の場合は要約なしで続行し、次のターン終了後に再試行すればよい。ブロックそのものを送り返すリクエストが失敗する場合は、`signature`や`content`を1バイトも変更せずそのまま送っているかを確認する。改変すると`compaction_signature_invalid`で400が返る。529の`compaction_unavailable`は一時的な障害なので、そのリクエストをそのまま再試行する。

## 既存機能とどう連携させるべきか

> ミッド会話システムメッセージの指示は圧縮範囲に含まれると失効し、画像やドキュメントも圧縮後は参照できなくなる。

圧縮されたメッセージ範囲に入っていた`role: "system"`の指示は要約に埋もれて効力を失うため、まだ必要な指示は圧縮後の最初のユーザー発話の直後に[ミッド会話システムメッセージ](/blog/claude-mid-conversation-tool-changes-cache-design/)として再送する必要がある。[Preserved Thinking](/blog/claude-preserved-thinking-append-only-conversation-design/)対応モデルで直近ターンのthinkingを保持する場合は、`system`とツール定義が圧縮リクエストと以降のリクエストで一致している条件を満たす必要がある。また、画像・ドキュメント・`container_upload`ブロックは要約に置き換えられると内容が失われるため、後のターンで必要なら再アップロードする設計にする。タスク予算の`remaining`を指定したまま圧縮リクエストを送ると400になる点も実装時の落とし穴だ。複数チームが共有するエージェント基盤でこうした圧縮設計を標準化したい場合は、[Kuuの大規模実装支援（RDE）](https://kuucorp.com/services/rde/)でハーネス全体の設計レビューを行っている。

## 参考

- [Compaction overview - Claude Platform Docs](https://platform.claude.com/docs/en/build-with-claude/compaction)
- [Compaction on demand - Claude Platform Docs](https://platform.claude.com/docs/en/build-with-claude/compaction-on-demand)
- [Claude Platform release notes](https://platform.claude.com/docs/en/release-notes/api)

## まとめ

Compaction On Demandは、圧縮を「API側が閾値で自動実行するもの」から「アプリ側が任意のタイミングで要求するもの」に変える設計転換だ。履歴の置換ルールとエラーハンドリング、ミッド会話システムメッセージやPreserved Thinkingとの相互作用を正しく実装すれば、長時間稼働するエージェントでも会話の連続性を保ったまま圧縮タイミングを自社のワークロードに合わせて制御できる。自社のエージェント基盤への組み込みは[Kuuの運用管理サービス（AI-Ops）](https://kuucorp.com/services/ai-ops/)でも相談できる。
