Claude Platform Docs
メッセージコンパクション

コンパクションと思考の保持

思考の保持に対応したモデルで、オンデマンドコンパクション後に保持されたターン内の思考ブロックが有効なままとなる条件と、その確認方法について説明します。

「preserved thinking」(思考の保持)に対応したモデルに「thinking blocks」(思考ブロック)を送り返し、かつ「compaction」(コンパクション)ブロックの後にターンを残す場合を除き、このページは読み飛ばしてください。「kept turns」(残したターン)とは、ブロックの後に続くターンのことです。直近のターンを保持するコンパクションのようにコンパクションリクエストから除外した最近のターン、またはバックグラウンドでのコンパクションのように要約の作成中に届いたターンがこれにあたります。

思考の保持に対応したモデルは、以前の思考ブロックを、それを生成した会話と照合してチェックします。要約はその会話の一部を置き換えますが、APIが要約を作成した場合、チェックはその置き換えを受け入れるため、残したターン内の思考は有効なままでいられます。

残した思考が有効なままとなる条件

残したターン内の思考ブロックは、次のすべてが成り立つ間、有効なままとなります。

  • コンパクションリクエストが思考の保持に対応したモデルで実行されること。 この条件は、最新のものだけでなく、思考ブロックが生成されて以降のすべてのコンパクションリクエストに適用されます。これを満たす方法の1つは、すべてのコンパクションリクエストを、会話で使用しているモデルに送信することです。
  • 残したターンが要約されたメッセージの直後に続き、それらを変更せずに送信すること。 残した各メッセージは、履歴にあるとおりそのまま送信してください。最後の要約されたメッセージと最初の残したメッセージの間で、メッセージを省略したり追加したりしないでください。また、最初の残したメッセージは最後の要約されたメッセージとは異なるロールである必要があり、会話途中の role: "system" メッセージであってはなりません。そうでない場合、APIはそれを最後の要約されたメッセージにマージします。最初の残したメッセージを正しく設定する方法の1つは、すでに送信したリクエストの messages をそのままコンパクションすることです。その場合、残したターンはそのリクエストに対するClaudeの返信から始まります。
  • system と、defer_loading: true が指定されていない tools が変更されないこと。 これらは、コンパクションリクエストと、残した思考を生成したリクエストとで同じであり、その後に続くリクエストでも同じままです。システムプロンプトまたはツールを変更するでは、それらを安全に変更する方法を説明しています。

条件が満たされない場合でも、コンパクション時には何も失敗せず、APIはいずれの場合も後続のリクエストでコンパクションブロックを受け入れます。失敗するのは保持された思考であり、それを送信する最初の後続リクエストで失敗します。その際に何が起こるかについては無効なブロックに対するAPIの処理で説明しており、このフィールドを設定しないリクエスト(Message Batchesの項目を含む)についてはprefix_mismatch_behavior が未設定の場合で説明しています。

古い思考を壊さずに再度コンパクションする

ターンを残したまま再度コンパクションできます。新しいブロックは、古い要約と、コンパクションリクエスト内でそれに続くすべてのメッセージをカバーし、そのリクエストから除外したターンは新しいブロックの残したターンになります。

残した思考の条件の1つ目は、思考ブロックが生成されて以降のすべてのコンパクションを対象とするため、2回のコンパクションを通じて残したターンでは、両方のコンパクションが思考の保持に対応したモデルで実行されている必要があります。

思考ブロックが生成される前のコンパクションは、その思考ブロックには影響しません。ブロックが配置された後に生成された思考はそのブロックに紐付けられ、条件を満たす後続のコンパクションを通じて有効なままとなります。

システムプロンプトまたはツールを変更する

その後のリクエストでは、コンパクションリクエストとは異なる system、異なる tools、または異なるモデルを使用でき、APIは引き続きブロックを受け入れます。このような変更は残されたターン内の思考を無効にする可能性がありますが、それ以外の影響はありません。

残した思考を無効にせずに system または tools を変更するには、まず会話全体をコンパクションして、ターンが残らないようにします。その後、次のリクエストでそれらを変更します。

system や tools に手を加えずに指示を追加したり利用可能なツールを変更したりするには、プレフィックスを編集せずに変更を加えるで説明されているように、変更を messages に追加します。

要約されたターン内にある会話途中のシステムメッセージも要約されるため、そのテキストによる指示は置き換え後には適用されなくなります。それらが設定したメッセージごとのeffortレベルも引き継がれません。後続のメッセージがレベルを設定するまで、ターンはリクエストのトップレベルの output_config.effort、または設定していない場合はモデルのデフォルトで実行されます。指示やeffortレベルを有効なままにするには、残したターンに続く最初の新しい user ターンの直後に、role: "system" メッセージで再度記述してください。それらのターン内のツール変更は、コンパクションリクエストが inline-tools-2026-09-15 も含んでいる場合、自動的に引き継がれます。返されたブロックはその正味の効果を tool_changes フィールドに記録するため、ブロックは変更せずに送り返してください。ブロックに tool_changes フィールドがない場合は、同じ方法でそれらのツール変更を再度記述してください。ブロックと残したターンの間に配置されたシステムメッセージは、それらのターンの思考を壊します。

残した思考が保持されたことを確認する

コンパクションのレスポンスからは、残した思考が有効かどうかはわかりません。それがわかるのは置き換え後の最初のリクエストです。テストで確認するには、次の手順を実行します。

  1. 思考を有効にして短い会話を行います。プレフィックスチェックを実行するモデルを使用し(プレフィックスを変更しないようにするを参照)、すべてのステップでそのモデルを使用してください。思考ブロックを読み取れないモデルは、エラーを出さずにそのブロックを破棄するためです。
  2. 古いターンをコンパクションし、思考ブロックを含むターンを少なくとも1つ残します。
  3. 次のリクエストを送信します。ブロックを先頭に、次に残したターン、その後に新しい user メッセージを配置し、thinking.block_binding.prefix_mismatch_behavior を "error" に設定します。
  4. 結果を確認します。input_transformations 配列が空の200レスポンスは、チェックに失敗した思考ブロックや破棄された思考ブロックがなかったことを意味します。ブロックが別の会話に紐付けられていることを示す400エラーは、そのようなブロックがあったことを意味します。メッセージは最初に失敗したブロックのパスから始まり、無効なブロックに対するAPIの処理にその全文が示されています。

prefix_mismatch_behavior フィールドには、compact-2026-09-04 ベータヘッダーに加えて thinking-binding-controls-2026-08-01 ベータヘッダーが必要です。リクエストで設定した値は、どのアカウントでも適用されます。

次のプログラムは4つのステップを実行します。残したターンに含まれる思考ブロックの数と、input_transformations のエントリ数を出力します。エントリがなければ、残した思考が保持されたことを意味します。

from anthropic.types.beta import BetaMessageParam, BetaThinkingConfigParam

client = anthropic.Anthropic()

# Claude Fable 5.1 は、送り返された思考を会話と照合する最初のモデルです。
MODEL = "claude-fable-5-1"
BETAS = ["compact-2026-09-04", "thinking-binding-controls-2026-08-01"]
SYSTEM = "You help plan a recipe app's release. Keep answers short."
# "error" を指定すると、チェックに失敗した思考ブロックによりリクエストが400で失敗します。
THINKING: BetaThinkingConfigParam = {
    "type": "adaptive",
    "block_binding": {"prefix_mismatch_behavior": "error"},
}

# 1. 思考を有効にして短い会話を行います。
history: list[BetaMessageParam] = [
    {"role": "user", "content": "What are the main entities in the app's data model?"}
]
first = client.beta.messages.create(
    model=MODEL,
    max_tokens=8192,
    system=SYSTEM,
    betas=BETAS,
    thinking=THINKING,
    messages=history,
)
history += [
    {"role": "assistant", "content": first.content},
    {
        "role": "user",
        "content": "Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?",
    },
]
second = client.beta.messages.create(
    model=MODEL,
    max_tokens=8192,
    system=SYSTEM,
    betas=BETAS,
    thinking=THINKING,
    messages=history,
)
history.append({"role": "assistant", "content": second.content})
thinking_blocks = sum(block.type == "thinking" for block in second.content)
print(f"Thinking blocks in the kept turn: {thinking_blocks}")

# 2. 最初のターンを要約します。2番目のターンはリクエストに含めません。
summary = client.beta.messages.create(
    model=MODEL,
    max_tokens=4096,
    system=SYSTEM,
    betas=BETAS,
    thinking=THINKING,
    messages=history[:2],
    compaction={"type": "summarize"},
)
if summary.stop_reason != "compaction":
    raise SystemExit(f"No summary: {summary.stop_reason}")

# 3. 保持したターンの前にブロックを配置し、次の質問をします。
history = [
    {"role": "assistant", "content": summary.content},
    *history[2:],
    {"role": "user", "content": "Which day should the release go out?"},
]
third = client.beta.messages.create(
    model=MODEL,
    max_tokens=8192,
    system=SYSTEM,
    betas=BETAS,
    thinking=THINKING,
    messages=history,
)

# 4. 破棄されたブロックがなく200が返れば、保持した思考は有効です。
print(f"Dropped thinking blocks: {len(third.input_transformations)}")
Output
Thinking blocks in the kept turn: 1
Dropped thinking blocks: 0

本番環境では、"drop_block"を使用すると、条件が満たされない場合でもリクエストは成功し続けます。レスポンスでは、削除された各ブロックがreason: "prefix_binding_mismatch"とともにinput_transformationsに一覧表示されます。pathが保持されたターン内にあるエントリは、そのターンの思考について条件が満たされなかったことを意味します。無効なブロックに対するAPIの処理では、何が削除されるかと、それに対してアラートを設定する方法について説明しています。Claude Sonnet 5.5およびClaude Haiku 5.5では、block_bindingはthinking: {"type": "adaptive"}の場合にのみ機能します。これらのモデルでその他の思考設定を使用している場合はblock_bindingを送信できないため、すべての条件が満たされていることを確認するか、保持されたターンからthinkingブロックとredacted_thinkingブロックを削除してください。

利用可能状況

コンパクションと思考の保持は一部のモデルでベータ版です。

APIサポート

ステータスベータ
クラウドプラットフォーム
モデル

必須のベータヘッダー

ベータヘッダーの概要

ベータヘッダーを使用すると、実験的な機能や新しいモデル機能が標準APIに組み込まれる前にアクセスできます。

ヘッダー
  • compact-2026-09-04

このページは役に立ちましたか?