Claude Platform Docs
Messagesコンパクション

オンデマンドコンパクション

アプリケーションが選んだタイミングでClaudeに会話を要約させ、その要約から会話を続けます。

「on-demand compaction」(オンデマンドコンパクション)では、会話をいつ要約するかをアプリケーションが決定します。compactionパラメータを付けたリクエストを1つ送信すると、Claudeは返答の代わりに要約を返します。

オンデマンドコンパクションの仕組み

コンパクションリクエストは、会話のターンとは別のものです。現時点の会話をcompactionパラメータとともに送信すると、レスポンスには単一のcompactionブロックが含まれます。このブロックには、読むことができるテキストとしての要約と、署名が含まれます。以降のリクエストでは、このブロックを受け取ったとおりにそのまま送信してください。

それ以降、このブロックは要約対象のメッセージの代わりになります。ブロックはmessagesの先頭に置き、要約されたメッセージは削除し、次のターンはその後に続けます。Claudeは、それらのメッセージがあった場所で要約を参照します。

Compaction requestfour messagesuser 1asst 1user 2asst 2Responseone block, no replycompaction blockNext requestblock firstcompaction blockuser 3

要約をリクエストする

要約を求めるリクエストと、署名付きブロックを含む以降のすべてのリクエストで、compact-2026-09-04ベータヘッダーを送信してください。モデルがオンデマンドコンパクションをサポートしているかどうかを確認するには、ベータヘッダーを付けてModels APIを呼び出し、各モデルのcapabilities.compactionを確認します。1つのリクエストでcompactioncontext_managementを組み合わせることはできません。

現時点の会話を"compaction": {"type": "summarize"}とともに送信します。APIはリクエスト内のすべてのメッセージを一度に要約し、その後に返答を生成せず、stop_reason"compaction"のブロックのみを返します。会話の他の部分で使用しているのと同じsystemプロンプトとtoolsを送信してください。要約処理はそれらを読み取ります。また、「preserved thinking」(思考の保持)を使用するモデルでブロックの後のターンを保持する場合、それらのターン内の思考はsystemtoolsが一致する場合にのみ有効なままとなります。この例の会話にはsystemプロンプトもツールもないため、リクエストではどちらも送信しません:

from anthropic.types.beta import BetaMessageParam

client = anthropic.Anthropic()

history: list[BetaMessageParam] = [
    {
        "role": "user",
        "content": "I am building a recipe app. Help me name the main entities in the data model.",
    },
    {
        "role": "assistant",
        "content": "Start with Recipe, Ingredient, and Step. Add a RecipeIngredient entry that holds the quantity and unit for each ingredient in a recipe.",
    },
    {"role": "user", "content": "Good. Now suggest field names for Recipe."},
]

response = client.beta.messages.create(
    model="claude-opus-5-5",
    # max_tokens は思考を含む呼び出し全体の上限となるため、数千トークンの余裕を持たせてください。
    max_tokens=4096,
    betas=["compact-2026-09-04"],
    messages=history,
    compaction={"type": "summarize"},
)
print(f"Stop reason: {response.stop_reason}")
Response
{
  "id": "msg_013Zva2CMHLNnXjNJJKqJ2EF",
  "type": "message",
  "role": "assistant",
  "model": "claude-opus-5-5",
  "content": [
    {
      "type": "compaction",
      "content": "Summary of the conversation: the user is designing the data model for a recipe app. The entities agreed so far are Recipe, Ingredient, Step, and RecipeIngredient, which holds the quantity and unit. The user then asked for field names for Recipe.",
      "signature": "EuYBCkQY..."
    }
  ],
  "stop_reason": "compaction",
  "usage": {
    "input_tokens": 0,
    "output_tokens": 0,
    "iterations": [{ "type": "compaction", "input_tokens": 144, "output_tokens": 276 }]
  }
}

要約呼び出しでは、リクエストのモデル、systemtools、思考設定、max_tokensが使用されます。要約処理はツール定義を読み取りますが、ツールを実行することはなく、レスポンスに思考は含まれません。max_tokensは、モデルが要約を書く前に行う思考を含め、呼び出し全体の上限となるため、数千トークンの余裕を持たせてください。コンパクションの使用量をカウントするでは、この呼び出しがどのように課金されるかを説明しています。

最後のassistantターンがまだ結果のないツール呼び出しで終わっている場合、APIはリクエストを拒否します。先にそのターンのツール結果を送信してください。また、stop_sequences、構造化出力のoutput_config.format、およびタイプがanyまたはtooltool_choiceは含めないでください。これらは要約呼び出しでは何の効果もなく、APIはこれらを拒否します。会話は引き続きモデルの「context window」(コンテキストウィンドウ)に収まる必要があるため、超過した後ではなく、超過する前にコンパクションを行ってください。

「streaming」(ストリーミング)でレスポンスを受け取る場合、ブロックは完全な形で届きます。完全なブロックを含むcontent_block_startイベントが1つ届き、その後にcontent_block_stopが続きます。content_block_deltaイベントはありません。pingイベントは、これらの前または間に届くことがあります。

要約から続ける

履歴内で、送信したメッセージを返されたアシスタントメッセージに置き換えます。compactionブロックは、signatureを含め、APIが返したとおりに保持してください。コンパクションリクエストを送信した後に行われたターンは、変更せずにブロックの後に続けます。これはバックグラウンドでのコンパクションの基盤となる仕組みです。以降のすべてのリクエストで、ベータヘッダーとともにブロックを先頭に置いて送信してください:

{
  "model": "claude-opus-5-5",
  "max_tokens": 2048,
  "messages": [
    {
      "role": "assistant",
      "content": [
        {
          "type": "compaction",
          "content": "Summary of the conversation: the user is designing the data model for a recipe app. The entities agreed so far are Recipe, Ingredient, Step, and RecipeIngredient, which holds the quantity and unit. The user then asked for field names for Recipe.",
          "signature": "EuYBCkQY..."
        }
      ]
    },
    {
      "role": "assistant",
      "content": "For Recipe, use title, description, servings, prep_minutes, and cook_minutes. Add created_at and updated_at timestamps."
    },
    { "role": "user", "content": "Now do the same for Ingredient." }
  ]
}

この例はリクエストのサンプルの続きであり、そのサンプルはuserターンで終わっていました。図は、要約の作成中にターンが行われない、より単純なケースを示しています。ここでの2番目のassistantメッセージは、要約された最後のuserターンへの返答です。これは要約の作成中に届いたため、要約対象のメッセージには含まれていませんでした。ブロックが引き続き先頭にあるため、ここではassistantメッセージが2つ連続しても問題ありません。

APIはブロックがある位置に要約を配置し、それ以降のすべてのメッセージを変更せずにClaudeに渡します。次のルールに従ってください:

  • ブロックをmessagesの先頭に置きます。単独のassistantメッセージとして置くか、最初のメッセージ(userメッセージでもassistantメッセージでも構いません)の最初のコンテンツブロックとして置きます。
  • 要約されたメッセージを削除します。ブロックの前にいずれかが残っている場合、リクエストは400エラー(compaction_block_misplaced)を返します。
  • 以降のすべてのリクエストで、リクエストごとにcompactionブロックを正確に1つ送信します。

「threshold compaction」(しきい値コンパクション)は逆の方法で動作します。そのブロックは要約対象のメッセージの後に続き、APIがそれらのメッセージを自動的に削除します。コンパクションブロックを返すを参照してください。

Pythonでは、このページのサンプルと同様にclient.beta.messagesを使用してください。client.messagesを呼び出してブロックを自分でシリアライズする場合は、to_dict()またはmodel_dump(exclude_none=True)を使用してください。通常のmodel_dump()はブロックにcitations: nulltext: nullを追加するため、APIに拒否されます。

ブロックの後のターンを保持し、その思考ブロックを送り返す場合、その思考を有効に保つための条件についてはコンパクションと思考の保持を参照してください。

再度コンパクションする

すでにブロックで始まっている会話をコンパクションするには、再度compactionを送信します。新しいブロックは、古い要約とその後のすべてを要約します。それ以降は、最新のブロックのみを送信してください。

ループでコンパクションする

各ターンの後、ループは最後のレスポンスの入力トークンと出力トークンを加算します。次のリクエストでは返答も送信されるためです。その合計が上限を超え、かつまだ次のターンが残っている場合、ループは同じモデルとsystemプロンプトでコンパクションリクエストを送信し、stop_reasonを確認し、履歴を返されたメッセージに置き換え、どのターンの前にコンパクションしたかを出力します。サンプルの上限である2,500トークンは、短い会話でもコンパクションが行われるように意図的に低く設定されています。実際の入力予算に近い値を設定してください。

from anthropic.types.beta import BetaMessageParam

client = anthropic.Anthropic()

# 実際の入力予算に近い値を設定してください。ここでは短い会話でもコンパクションが発生するよう低く設定しています。
COMPACT_AT_TOKENS = 2500
SYSTEM = "You help design a recipe app's data model. Keep answers short."

QUESTIONS = [
    "What are the main entities in the data model?",
    "Which fields should Recipe have?",
    "Which fields should Ingredient have?",
    "Which fields should RecipeIngredient have?",
    "Which fields should Step have?",
    "Which indexes should these tables have?",
    "Which fields should be required?",
    "Which fields should have default values?",
]

history: list[BetaMessageParam] = []
for turn, question in enumerate(QUESTIONS, start=1):
    history.append({"role": "user", "content": question})
    response = client.beta.messages.create(
        model="claude-opus-5-5",
        max_tokens=8192,
        system=SYSTEM,
        betas=["compact-2026-09-04"],
        messages=history,
    )
    history.append({"role": "assistant", "content": response.content})

    # 次のリクエストではこの応答も送信されるため、これもカウントしてください。
    conversation_tokens = response.usage.input_tokens + response.usage.output_tokens
    if conversation_tokens > COMPACT_AT_TOKENS and turn < len(QUESTIONS):
        summary = client.beta.messages.create(
            model="claude-opus-5-5",
            max_tokens=4096,
            system=SYSTEM,
            betas=["compact-2026-09-04"],
            messages=history,
            compaction={"type": "summarize"},
        )
        if summary.stop_reason == "compaction":
            history = [{"role": "assistant", "content": summary.content}]
            print(f"Compacted before turn {turn + 1}")

stop_reasonの確認は、コードがブロックを探す前に行われます。その理由は要約が返されない場合やエラーを処理するで説明しています。履歴は追加されるのではなく置き換えられます。返されたメッセージは、要約から続けるのルールに従い、リクエストに含まれていたすべてのメッセージを置き換えます。要約が返されない場合、ループは履歴を保持し、次のターンの後に再度リクエストします。

Python、TypeScript、C#、Go、JavaのSDKの「tool runner」(ツールランナー)は、コンパクションリクエストを代わりに送信できます。コンパクションを行うと決めたら、ランナーでcompact_before_next_turn()を呼び出します(TypeScriptとJavaではcompactBeforeNextTurn()、C#とGoではCompactBeforeNextTurn())。現在のターンとそのツール呼び出しが完了すると、ランナーはコンパクションリクエストを送信し、履歴を返されたメッセージに置き換えます。ランナーはベータを追加しないため、compact-2026-09-04ベータを指定してランナーを作成してください。ランナーは自身のパラメータからリクエストを構築し、context_managementを除外します。それらのパラメータにstop_sequences、タイプがanyまたはtooltool_choice、または構造化出力のoutput_config.formatが含まれている場合、APIは400エラーでリクエストを拒否します。その理由は要約をリクエストするで説明しています。ランナーのcontext_managementにコンパクション編集が含まれている間、ランナーはコンパクションを拒否するため、1つのランナーでは1種類のコンパクションを使用してください。

コンパクションのタイミング

完了したターンの後であればいつでもコンパクションリクエストを送信できるため、タイミングはコードで決定します。

次のリクエストのサイズを見積もるには、ループと同様に、最後のレスポンスのusageからinput_tokensoutput_tokensを加算します。「prompt caching」(プロンプトキャッシング)を使用している場合、input_tokensは最後のキャッシュブレークポイント以降のトークンのみをカウントするため、cache_read_input_tokenscache_creation_input_tokensも加算してください。同じメッセージを「token counting」(トークンカウント)エンドポイントに送信することもできます。

その数値を、モデルのコンテキストウィンドウより小さい、自分で選んだ上限と比較します。

独自の要約プロンプトを作成する

instructionsを指定しない場合、APIはデフォルトの要約プロンプトを使用します。空白でないinstructions文字列(最大16,384文字)を指定すると、そのプロンプトが完全に置き換えられます。例:

{
  "compaction": {
    "type": "summarize",
    "instructions": "Summarize this recipe app design conversation. Preserve every entity and field name agreed so far, and the user's latest open request. Do not call tools; respond with the summary text only."
  }
}

instructionsの有無にかかわらず、要約処理は以前の思考を含む会話全体を読み取ります。instructionsでは、要約に保持すべき内容を指定し、ツールを呼び出さないようモデルに指示してください。要約呼び出しは、他のリクエストと同じセーフガードの下で実行されます。

要約が返されない場合やエラーを処理する

要約が生成されるのは、要約呼び出しがテキストを含み、ツール呼び出しなしで正常に終了した場合のみです。それ以外の場合でもレスポンスは空のcontentを持つ200となるため、ブロックを探す前にstop_reasonを確認してください。この呼び出しは引き続き課金され、usage.iterationsで報告されます。呼び出しを実行できなかった場合、使用量はゼロになります。stop_reasonは、要約呼び出しが終了した際のものです。いずれの場合も、要約なしで続行し、後でコンパクションを行うことができます。

stop_reason原因対処方法
"max_tokens"要約が途中で切れました。より大きなmax_tokensで再送信します。
"model_context_window_exceeded"要約プロンプトのための余地がありませんでした。より短いinstructionsまたはより少ないメッセージで再送信します。
"tool_use"モデルが要約を書く代わりにツールを呼び出しました。ツールを呼び出さないようモデルに指示するinstructionsを付けて再送信します。
"refusal"リクエストが拒否されました。要約なしで続行します。
"end_turn"呼び出しがテキストを返しませんでした。要約なしで続行します。

要約呼び出しには、他のリクエストと同じセーフガードが適用されます。"refusal"の後は、stop_detailsによってその背後にあるポリシーカテゴリが特定されます。

エラー

コンパクションリクエスト、またはブロックを含むリクエストは、完全に失敗することもあります。ほとんどの400エラーには、何を削除または再送信すべきかを示すメッセージが含まれます。一部のエラーには、compaction_で始まるerror.details.error_codeも含まれます。compactionと組み合わせられないフィールドなどのパラメータエラーには、メッセージのみが含まれます。

エラー原因対処方法
529 overloaded_errorerror.details.error_code compaction_unavailableブロックの生成中、または送り返されたブロックの読み取り中に一時的なサーバーの問題が発生しました。リクエストを再試行します。
400 compaction_block_misplaced要約されたメッセージがブロックの前に残っています。それらを削除し、ブロックがmessagesの先頭に来るようにします。
400 compaction_signature_invalidまたはcompaction_content_mismatchAPIが返した後に、ブロックのsignatureまたはcontentが変更されました。signatureを含め、返されたとおりにブロックを送信します。
400リクエストに複数のcompactionブロックが含まれています。最新のブロックを正確に1つ送信します。
400最後のassistantターンが、まだ結果のないツール呼び出しで終わっています。そのターンのツール結果を送信してから、コンパクションを行います。
400 compaction_nothing_to_summarizemessagesuserまたはassistantのコンテンツがありません(空のリストなど)。少なくとも1つのuserまたはassistantメッセージを送信します。
コンパクションリクエストでの400で、compactionパラメータがrequires anthropic-beta: compact-2026-09-04であることを示すメッセージが含まれるコンパクションリクエストでベータヘッダーが省略されました。ベータヘッダーを追加します。要約をリクエストするを参照してください。
ブロックを含む以降のリクエストでの400:compactionが想定されるコンテンツブロックタイプのいずれでもないことを示す検証エラー。メッセージにはヘッダーについての言及はありませんそのリクエストでベータヘッダーが省略されました。ブロックを含むすべてのリクエストにベータヘッダーを追加します。要約をリクエストするを参照してください。
messages.0.content.0.compaction.citations: Extra inputs are not permittedなどの400検証エラーcitations: nullなど、APIが返さなかったフィールドを含むブロックが送り返されました。返されたとおりにブロックを送信します。要約から続けるを参照してください。

コンパクションの使用量をカウントする

要約呼び出しは他のリクエストと同様に課金され、「rate limit」(レート制限)の対象となり、usage.iterationsではcompactionエントリとして報告されます。返答が生成されないため、トップレベルのinput_tokensoutput_tokensはゼロです。会話で消費された量をカウントするには、トップレベルのフィールドではなく、usage.iterations全体を合計してください。以降のリクエストでブロックを送り返しても、コンパクションのコストは追加されません。

これで、会話をコンパクションし、要約が返されない場合を処理する、動作するループができました。2つのページでその動作を変更でき、両者を組み合わせることもできます。直近のターンを保持するコンパクションは最後のターンを一字一句そのまま保持し、バックグラウンドでのコンパクションは要約の作成中も会話を続けられるようにします。思考ブロックを送り返し、いずれかを行う場合は、コンパクションと思考の保持が適用されます。

制限と他の機能との相互作用

  • しきい値コンパクションと「context editing」(コンテキスト編集)。 同じリクエストでcompactioncontext_managementを送信することはできません。しきい値コンパクション(compact_20260112)は、署名付きブロックを含むリクエストでは実行できません。
  • プロンプトキャッシング。 ブロックのcache_controlは、要約の後にブレークポイントを配置します。
  • 会話途中のシステムメッセージとツールの変更。 要約範囲内のrole: "system"メッセージも要約されるため、ブロックがそれらを置き換えると、そのテキストの指示は適用されなくなります。指示が引き続き重要な場合は、role: "system"メッセージで再度記述してください。そのメッセージは次の新しいuserターンの直後に送信し、それ以降は履歴に残しておいてください。ツールの変更について、またブロックの後のターンを保持する場合にそのメッセージをどこに置くかについては、システムプロンプトまたはツールを変更するを参照してください。
  • タスク予算。 「task budget」(タスク予算)remaining値(output_config.task_budget.remaining)を、compactionとともに、またはブロックを含むリクエストで送信しないでください。送信すると400エラーが返されます。
  • トークンカウント。 トークンカウントエンドポイントはcompactionパラメータを無視します。
  • 要約で引き継げないコンテンツ。 要約されたメッセージ内の画像、ドキュメント、container_uploadブロック、取得したURLは、ブロックがそれらを置き換えると失われます。後のターンで引き続き必要なものは、再度記述するか再アップロードしてください。

Compatibility

Supported models
  • Fable 5 and 5.1
  • Mythos 5, 5.1, and Preview
  • Opus 4.6, 4.7, 4.8, 5, and 5.5
  • Sonnet 4.6 and 5
Supported platforms
  • Claude APIBeta
  • Claude Platform on AWSBeta
  • Google CloudBeta
  • Microsoft FoundryBeta

Was this page helpful?