Claude Platform Docs
Messages思考

保持された思考

保持された思考(preserved thinking)により、モデルは以前のターンの思考ブロックを、そのモデル自身または固定された他のモデル群のいずれかが生成し、かつブロックより前の内容が何も変更されていない場合にのみ使用できます。

「preserved thinking」(保持された思考)は、「distillation」(蒸留)を防ぐための新しいClaudeモデルの特性です。これは、以前のターンから送り返した思考ブロックをモデルが使用できるかどうかを決定します。Claude Fable 5.1以降、thinkingまたはredacted_thinkingブロックがリクエストで返されると、APIはブロックのsignatureについて次の2点を確認します。

  • モデルがブロックを読み取れること。 各モデルは、自身の思考ブロックと、固定された他のモデル群の思考ブロックを読み取ります。Claude Fable 5.1はClaude Opus 5のブロックを読み取り、Claude APIではClaude Opus 5.5のブロックも読み取ります。Claude Opus 5とClaude Opus 5.5はいずれもClaude Fable 5.1のブロックを読み取りません。現在のモデルがブロックを読み取れない場合、APIはエラーを出さずにそのリクエストからブロックを削除します。会話の途中でのモデルの切り替えを参照してください。
  • 思考ブロックより前の内容が何も変更されていないこと。 ブロックより前にあるトップレベルのsystemプロンプト、tools、messagesが、そのブロックの「prefix」(プレフィックス)です。プレフィックスがブロック生成時に送信した内容と異なる場合、そのブロックとそれ以降のすべての思考ブロックは無効となり、APIは選択に応じて400エラーでリクエストを拒否するか、無効なブロックを削除します。プレフィックスを変更しないようにするを参照してください。

Claude Sonnet 5.5およびClaude Haiku 5.5の思考ブロックも、それを生成したアカウントに紐付けられています。APIがこれをどこで適用するかについては、思考ブロックはそれを生成したアカウントに留まるを参照してください。

モデルのチェックはすべてのアカウントに適用されます。APIは、2026年8月31日00:00 UTC以降に作成されたアカウントに対して、デフォルトでプレフィックスのチェックを適用します。それより古いアカウントでは、thinking.block_binding.prefix_mismatch_behaviorを設定したリクエストに対してのみプレフィックスのチェックを適用します。アカウントの作成時期にかかわらず、統合を追記専用(append-only)にしてください。 そうすれば、デフォルトで適用される新しいアカウントを含め、すべてのアカウントで同じコードが動作します。

変更が必要なケース

Claude Code、claude.ai、Claude Managed Agents、またはClaude Agent SDKがリクエストを構築している場合、あるいはコードがセッション中systemとtoolsを固定し、messagesに追記するだけの場合は、何も変更する必要はありません。Claude Mythos 5.1およびClaude Fable 5.1より前のモデルは、プレフィックスのチェックを実行しません。思考ブロックを一切送り返さない場合、プレフィックスのチェックで拒否されるものはありませんが、モデルは以前の推論を一切受け取りません。

1つの会話内の2つのリクエストの間で、統合が次のいずれかを行う場合は確認してください。各項目には、代わりに行うべきことへのリンクがあります。

古いアカウントでは、リクエストでprefix_mismatch_behaviorを設定しない限り、これらのいずれもエラーを発生させません。そのため、自分のキーでエラーなく実行できても、コードが影響を受けるかどうかはわかりません。ユーザーが自分のAPIキーでツールを実行する場合、新しいアカウントのユーザーはあなたより先に400エラーを受け取ります。リクエストの動作を変えずにユーザーが見るものを確認するには、thinking-binding-controls-2026-08-01ベータヘッダーを送信してください。古いアカウントでは、各レスポンスがチェックに失敗したブロックにフラグを付け、モデルは引き続きそれらを読み取ります(不一致時の動作を設定してinput_transformationsを読み取るを参照)。

また、統合があるアカウントのClaude Sonnet 5.5またはClaude Haiku 5.5の思考ブロックを、別のアカウントが行うリクエストで送信する場合も確認してください。思考ブロックはそれを生成したアカウントに留まるを参照してください。

会話の途中でのモデルの切り替え

Claude Fable 5.1とClaude Mythos 5.1は、互いが生成した思考ブロックと、それ以前のClaudeモデルが生成した思考ブロックを読み取ります。Claude Fable 5.1またはClaude Mythos 5.1の思考ブロックを読み取る他のモデルはありません。

Claude Opus 5.5は、Claude Opus 5、それ以前のOpus、Sonnet、Haikuモデル、そしてClaude APIとGoogle CloudではClaude Sonnet 5.5およびClaude Haiku 5.5の思考ブロックを読み取りますが、Claude FableやClaude Mythosモデルの思考ブロックは読み取りません。Claude APIでは、Claude Fable 5.1とClaude Mythos 5.1がClaude Opus 5.5の思考ブロックを読み取ります。他のモデルは読み取りません。したがって、Claude Opus 5からClaude Opus 5.5に移行する会話は推論を保持し、Claude APIでClaude Opus 5.5からClaude Fable 5.1またはClaude Mythos 5.1に移行する会話も同様です。Claude Fable 5.1またはClaude Mythos 5.1からClaude Opus 5.5に移行する会話、あるいはClaude Opus 5.5からこれら2つ以外のモデルに移行する会話では、切り替え後のターンは以前のモデルの推論なしで実行されます。このセクションで後述するように、ブロックは拒否されるのではなく削除されます。

Claude Sonnet 5.5は、Claude Sonnet 5、Claude Opus 4.8、Claude Haiku 4.5、およびそれ以前のモデル、そしてClaude APIとGoogle CloudではClaude Haiku 5.5の思考ブロックを読み取りますが、Claude Opus 5、Claude Opus 5.5、またはClaude FableやClaude Mythosモデルの思考ブロックは読み取りません。Claude APIとGoogle Cloudでは、Claude Opus 5.5がClaude Sonnet 5.5の思考ブロックを読み取ります。他のモデルは読み取りません。したがって、Claude Sonnet 5からClaude Sonnet 5.5に移行する会話は推論を保持し、Claude APIとGoogle CloudでClaude Sonnet 5.5からClaude Opus 5.5に移行する会話も同様です。Claude Opus 5、Claude Opus 5.5、またはClaude FableやClaude MythosモデルからClaude Sonnet 5.5に移行する会話では、切り替え後のターンは以前のモデルの推論なしで実行されます。Claude Sonnet 5.5からのその他の移行、たとえばClaude Sonnet 5へのサーバーサイドフォールバックも同様です。

Claude Haiku 5.5は、Claude Sonnet 5、Claude Opus 4.8、Claude Haiku 4.5、およびそれ以前のモデルの思考ブロックを読み取りますが、Claude Opus 5、Claude Opus 5.5、Claude Sonnet 5.5、またはClaude FableやClaude Mythosモデルの思考ブロックは読み取りません。Claude APIとGoogle Cloudでは、Claude Opus 5.5とClaude Sonnet 5.5がClaude Haiku 5.5の思考ブロックを読み取ります。他のモデルは読み取りません。したがって、Claude Haiku 4.5からClaude Haiku 5.5に移行する会話は推論を保持し、Claude APIとGoogle CloudでClaude Haiku 5.5からClaude Opus 5.5またはClaude Sonnet 5.5に移行する会話も同様です。Claude Opus 5、Claude Opus 5.5、Claude Sonnet 5.5、またはClaude FableやClaude MythosモデルからClaude Haiku 5.5に移行する会話では、切り替え後のターンは以前のモデルの推論なしで実行され、Claude Haiku 5.5からのその他の移行も同様です。

  • 以前のモデルから、またはClaude APIでClaude Opus 5.5からClaude Fable 5.1に移行する会話は、推論を保持します。 以前のモデルの思考ブロックは読み取り可能なままなので、モデルは切り替え後の最初のターンから通常どおり思考します。
  • Claude Fable 5.1からClaude Mythos 5.1以外のモデルに移行する会話は、そのリクエストでClaude Fable 5.1の推論を失います。 これは、ルーターがターンをより安価なモデルに送信した場合、分類器による拒否のフォールバックの後、またはサーバーサイドフォールバックの際に発生します。APIは、プロンプトがモデルに到達する前に読み取れないブロックを削除します。これらは課金されず、input_tokensにもカウントされません。

すべてのリクエストで、思考ブロックを含む完全な履歴を送信し続け、現在のモデルが読み取れないものはAPIに削除させてください。APIがmessages配列を編集することはないため、削除されたブロックは履歴に残ります。同じ履歴がClaude Fable 5.1に戻ると、そのブロックは以前のモデルの思考とともに再び読み取り可能になります。推論が完全に失われるのは、クライアント自身がブロックを削除した場合のみです。たとえば、モデル切り替え時に思考を取り除くハーネスや、各モデルが使用したものから履歴を再構築するハーネスなどです。

SystemToolsUserFable thinkingread againUserFable thinkingread again[change model → Opus]UserOpus thinkingdrops Fable thinking[back to Fable 5.1]UserFable thinkingall thinking readNo errors

thinking-binding-controls-2026-08-01ベータヘッダーを使用すると、レスポンスは削除された各ブロックを、トップレベルのinput_transformations配列にreason: "model_binding_mismatch"とともに一覧表示します。

{
  "input_transformations": [
    {
      "type": "thinking_dropped",
      "path": "messages.3.content.0",
      "reason": "model_binding_mismatch"
    }
  ]
}

ヘッダーがない場合、削除は通知なしで行われます。このエントリは統合のバグではなく、prefix_mismatch_behaviorはこれに影響しません。現在のモデルが読み取れないブロックは常に削除されます。

思考ブロックはそれを生成したアカウントに留まる

Claude Sonnet 5.5またはClaude Haiku 5.5が生成する思考ブロックは、それを生成したアカウント、またはそれにリンクされたアカウントでのみ機能します。別のアカウントがこれらのブロックのいずれかを送信すると、APIはモデルがそれを見る前にブロックを削除し、リクエストは成功します。モデルは、削除されたブロック内の推論なしで応答します。以前のモデルのブロックは影響を受けません。

Claude APIとGoogle Cloudでは、thinking-binding-controls-2026-08-01ベータヘッダーを使用すると、レスポンスは削除された各ブロックをinput_transformationsにreason: "organization_binding_mismatch"を持つthinking_droppedエントリとして一覧表示します。ヘッダーがない場合、削除は通知なしで行われます。

プレフィックスを変更しないようにする

Claude Fable 5.1、Claude Opus 5.5、Claude Sonnet 5.5、Claude Haiku 5.5では、思考ブロックは、それより前に送信したすべての内容が後続のリクエストで変更されていない間のみ有効です。チェックされるプレフィックスは3つの部分で構成されます。

  • トップレベルのsystemプロンプト
  • toolsのセット
  • ブロックより前のすべてのmessage

注:サーバー側のコンパクションを使用する場合、チェックされるプレフィックスは最新のコンパクションブロックから始まります。

effort、max_tokens、output_config、tool_choice、metadataなど、これら3つのフィールド以外のリクエストパラメータはプレフィックスのチェックの対象外であり、cache_controlマーカーも同様です。完全な一覧は編集とみなされるものにあります。

以前の思考ブロックはプレフィックスに含まれませんが、各思考ブロックは、ターンをまたいで、どの思考ブロックがその前にあったかを記録します。思考ブロックは、履歴の先頭から(古いものから順に)、末尾から、またはすべてを削除できます。失敗するのは欠落がある場合です。保持する思考ブロックは元のシーケンスの途切れのない連続でなければならないため、途中から1つを削除すると、それ以降の思考ブロックが無効になります。一度ブロックを削除したら、除外したままにしてください。元に戻すと、それが存在しなかった間に生成された思考ブロックが無効になります。

セッション中はsystemとtoolsを固定し、messagesを追記専用として扱ってください。同じ規律により、プロンプトキャッシングのプレフィックスも安定します。思考を無効にする編集は、キャッシュを最初からやり直させる編集と同じです。

無効なブロックに対するAPIの処理

処理方法はthinking.block_binding.prefix_mismatch_behaviorで選択します。

  • "error"(デフォルト): APIは400 invalid_request_errorでリクエストを拒否します。エラーには、最初に失敗したブロックが示されます。
  • "drop_block": APIは、失敗した各ブロックとそれ以降のすべての思考ブロックを削除し、リクエストは成功します。削除されたブロックは課金されません。モデルは、削除されたブロックの推論を使わずにそのターンに応答します。プロンプトキャッシュは編集箇所から再開されます。削除された各ブロックは、レスポンスのinput_transformations(ストリーミング時はmessage_startイベント)にreason: "prefix_binding_mismatch"とともに記載されます。

各セッションで、input_transformationsにprefix_binding_mismatchエントリを含むレスポンスの数をカウントしてアラートを出し、各編集をプレフィックスを編集せずに変更を加えるの対応するパターンに置き換えてください。Message Batches APIでは、このフィールドを設定していない項目は失敗しません。APIがデフォルトでチェックを適用する場合は、代わりに失敗したブロックを削除します。バッチ項目を失敗させたい場合は、そこで明示的に"error"を設定してください。

このフィールドとinput_transformations配列を使用するには、どちらもthinking-binding-controls-2026-08-01 ベータヘッダーが必要です。各SDKでのリクエスト例は、不一致時の動作を設定してinput_transformationsを読み取るを参照してください。

400エラーのメッセージは、次のように始まります。

messages.1.content.0: Invalid `signature` in `thinking` block. The block is bound to a different conversation. Remove the block, or set `thinking.block_binding.prefix_mismatch_behavior` to "drop_block".

リクエストでベータヘッダーを送信していない場合、メッセージは次のように続きます。

That setting requires the `thinking-binding-controls-2026-08-01` value in the `anthropic-beta` header.

メッセージの最後には通常、何が変更されたかを示す文が付きます。たとえば、systemプロンプトやtoolsリストがブロックの作成時と異なる、といった内容です。この文に示される可能性のある内容については、思考のトラブルシューティングを参照してください。

署名が改ざんされている場合や復号できない場合は、別の種類の失敗です。この場合は常に400が返され(Invalid `signature` in `thinking` block。会話に関する文は含まれません)、prefix_mismatch_behaviorは適用されません。

"drop_block"の出力トークンコスト

マルチターンのコーディングベンチマークにおけるAnthropicのテストでは、セッションごとに1回思考ブロックを削除すると、出力トークンがlow effortで2.5%、mediumで3.9%、highで4.5%、maxで20.1%増加しました。2ターン目以降の毎ターンで削除すると、出力トークンがlow effortで4.6%、mediumで9.7%、highで10.3%、maxで67.1%増加しました。これらの数値は誤差範囲の広い推定値であり、ワークロードへの影響はハーネスによって異なります。

Claudeが以前のターンの推論を読み取れなくなると、その推論を再作成するため、思考ブロックを削除するリクエストはより多くの出力トークンを生成し、応答に時間がかかる場合があります。毎ターンの削除は時折の削除よりもコストがかかり、どの程度多くかかるかはハーネス、つまりプレフィックスを編集する頻度と、各ターンが以前の推論にどの程度依存するかによって異なります。

"drop_block"に依存する前に、自分のワークロードで評価を実行して増加量を測定してください。増加が小さければ、"drop_block"は編集を修正する間リクエストを成功させ続けることができます。いずれにしても、プレフィックスを編集せずに変更を加えるのパターンで編集を修正することが、より良い長期的な解決策です。

コードでエラーを処理する

これは、このセクションで前述した400 invalid_request_errorです。同じ本文を再送信しないでください。毎回同じように失敗します。一時的な対処として、ベータヘッダーとprefix_mismatch_behavior: "drop_block"を付けて1回再試行し("drop_block"は出力トークンを増加させる可能性があります)、その選択をセッションとともに保存して、再起動後も含め、以降のすべてのリクエストでも送信されるようにしてください。Claude Sonnet 5.5とClaude Haiku 5.5では、block_bindingはthinking: {"type": "adaptive"}でのみ機能します。Claude Sonnet 5.5でbetween_toolsを使用する場合、またはClaude Haiku 5.5でthinking: {"type": "disabled"}を使用する場合は、履歴を追記専用に保つか、編集されたターン以降の思考ブロックを取り除いてください。ベータヘッダーを送信できない場合は、履歴からすべてのthinkingおよびredacted_thinkingブロックを一度削除し、除外したまま続行してください。その後、不一致の原因となった編集を修正してください。

不一致時の動作を設定してinput_transformationsを読み取る

thinking-binding-controls-2026-08-01ベータヘッダーは次を追加します。

  • すべてのレスポンスにおけるトップレベルのinput_transformations配列
  • thinking設定上のblock_bindingオブジェクト(唯一のフィールドはprefix_mismatch_behavior)

block_bindingは、thinking.type: "adaptive"およびthinking.type: "enabled"とともに受け付けられます。Claude Sonnet 5.5およびClaude Haiku 5.5では、block_bindingはthinking: {"type": "adaptive"}でのみ機能します。between_tools(Claude Sonnet 5.5)、またはClaude Haiku 5.5でのthinking: {"type": "disabled"}と一緒に送信すると、400エラーが返されます。ベータヘッダーなしで送信すると、メッセージがblock_binding: Extra inputs are not permittedで終わる400エラーが返されます。プレフィックスのチェックを実行しないモデルはこのオブジェクトを受け付け、モデルのチェックによる削除のみを報告するため、1つのリクエスト本文がモデル間で機能します。APIリファレンスでは、プレフィックスのチェックを会話のチェック(conversation check)と呼んでいます。

次のリクエストは、拒否ではなく削除を選択します。最初のターンでは再生するものがないため、input_transformationsは空で返されます。

client = anthropic.Anthropic()

response = client.beta.messages.create(
    model="claude-fable-5-1",
    max_tokens=16000,
    thinking={
        "type": "adaptive",
        "block_binding": {"prefix_mismatch_behavior": "drop_block"},
    },
    messages=[
        {
            "role": "user",
            "content": "What is the greatest common divisor of 1071 and 462?",
        }
    ],
    betas=["thinking-binding-controls-2026-08-01"],
)

for block in response.content:
    if block.type == "text":
        print(block.text)

print(f"Input transformations: {len(response.input_transformations or [])}")
Output
The greatest common divisor of 1071 and 462 is 21.
Input transformations: 0

ベータヘッダーを使用すると、思考に対応したモデルからのすべてのレスポンスにinput_transformationsが含まれます。各エントリは、path(たとえばmessages.1.content.0)によって1つの思考ブロックを示し、reasonを示します。エントリには2つのタイプがあります。

  • thinking_dropped: APIはモデルが読み取る前にブロックを削除し、そのブロックは課金されません。reasonはprefix_binding_mismatchまたはmodel_binding_mismatchです(会話の途中でのモデルの切り替えを参照)。reasonはorganization_binding_mismatchになることもあり、これはブロックが別のアカウントから来たことを意味します(思考ブロックはそれを生成したアカウントに留まるを参照)。
  • thinking_mismatch_allowed: ブロックはプレフィックスのチェックに失敗しましたが、APIはこのリクエストに対してそのチェックを適用しないため、ブロックは変更されずにモデルに届き、課金されます。reasonは常にprefix_binding_mismatchです。このエントリは、古いアカウントからのリクエストなど、APIがデフォルトでチェックを適用しないリクエストにのみ表示されます(APIがチェックを適用する条件を参照)。prefix_mismatch_behaviorをいずれかの値に設定すると、リクエストは適用対象になるため、これを設定したリクエストがこのエントリを受け取ることはありません。

削除されたブロックがなく、プレフィックスのチェックに失敗したブロックもない場合、配列は空です。今後のチェックで値が追加されるため、認識できないtypeまたはreasonを持つエントリは無視してください。

ストリーミング時は、配列はmessage_startイベントのmessageオブジェクト上で届きます。ストリーム途中のサーバーサイドフォールバックの後は、最後のmessage_deltaイベントが、応答したモデルのエントリとともに再び配列を含みます。メッセージバッチでは、明示的な"error"のもとでブロックがプレフィックスのチェックに失敗したアイテムはerroredとして解決されます。フィールドを未設定のままにしたアイテムは失敗しません。APIがデフォルトでチェックを適用する場合は、代わりに失敗したブロックを削除します。トークンカウントエンドポイントは同じプレフィックスのチェックを実行し、同じ400を返します。

APIがチェックを適用する条件

APIは、新しいアカウントに対して、Claude Fable 5.1、Claude Opus 5.5、Claude Sonnet 5.5、Claude Haiku 5.5でプレフィックスのチェックを適用します。

  • 2026年8月31日00:00 UTC以降に作成されたアカウント: APIはClaude Fable 5.1、Claude Opus 5.5、Claude Sonnet 5.5、Claude Haiku 5.5のリクエストをチェックし、"drop_block"を設定しない限り"error"を適用します。新しいアカウントの同じ定義が、Claude APIとクラウドプラットフォームに適用されます。
  • 古いアカウント: APIは、prefix_mismatch_behaviorを設定したリクエストに対してのみチェックを適用します。このフィールドを設定するとリクエストが適用対象になるため、新しいアカウントを作成せずに新しいアカウントが見るものを確認できます。フィールドを未設定のままにしたリクエストでは、APIは引き続きチェックを実行しますが、失敗したブロックをモデルに通します。ベータヘッダーを使用すると、レスポンスはそれぞれをinput_transformationsにthinking_mismatch_allowedとして一覧表示するため、モデルが受け取る内容を変えずにプレフィックスの編集を見つけることができます。

アカウントがどちらのグループに属するかを確認するには、思考ブロックを含むClaude Fable 5.1の会話を用意し、そのブロックより前の何かを変更して、ベータヘッダーやblock_bindingフィールドなしでClaude Fable 5.1に送信してください。ヘッダーに言及する400レスポンスは、アカウントがデフォルトで適用対象であることを意味します。200レスポンスは、適用対象でないことを意味します。確認するには、block_bindingなしのまま、ベータヘッダーを付けて同じリクエストを再度送信してください。レスポンスは、編集以降のすべての思考ブロックをinput_transformationsにthinking_mismatch_allowedとして一覧表示します。

編集とみなされるもの

各行は、連続する2つのリクエストの間の変更を示しています。

リクエスト間の変更以降の思考ブロック
末尾にメッセージを追記する有効
まだ何からも参照されていないdefer_loading: true付きのツールを追加する有効
履歴の先頭から、末尾から、またはすべてのthinkingブロックを削除する有効(モデルはその推論を失います)
system、tools、messages以外のリクエストパラメータ(effort、max_tokens、output_config、tool_choice、metadata、thinking.displayなど)を変更する有効
cache_controlマーカーを追加、移動、または削除する有効
同じバイト列を返す、ローテーションする署名付きURL有効
サーバー側のコンパクションまたはコンテキスト編集によってコンテンツが削除または置換される有効(チェックは、サーバーが編集したコピーではなく、送信した内容を比較します)
クリアされたターンスコープのシステムメッセージをそのまま残す有効
以前のuser、assistant、またはsystemメッセージを編集、並べ替え、または削除する無効。ただし、オンデマンドコンパクションの署名付きブロックが、残された思考の条件のもとで、要約対象のメッセージを置き換える場合を除きます
最初のユーザーメッセージに入れたコンテキストを、変更された値で再レンダリングするすべての思考ブロックが無効
以前のtool_resultをクリアまたは短縮する、以前の画像を再エンコードする、または以前のtool_useの入力を変更する以降のすべての思考ブロックが無効
以前のユーザーターンにテキストブロックを追加する、または前回追加したものを削除する無効
トップレベルのsystemの文字列またはブロックを変更する無効
tools内のツールを追加、削除、名前変更、または編集する無効
履歴の途中からthinkingブロックを削除し、それより後のブロックを保持する以降のすべての思考ブロックが無効
以前のリクエストで削除したthinkingブロックを元に戻すそのブロックがなかった間に生成された思考ブロックが無効
次のリクエストで異なるバイト列を返す画像またはドキュメントのURL無効
同じターンスコープのメッセージを、以降のリクエストで削除または書き換える無効

コードがプレフィックスを編集しているかを確認する

まず、送信内容の差分を取ります。コンパクションやツールの変更を含む、いくつかの通常のターンで統合が送信するリクエスト本文をキャプチャしてください。連続するリクエストの各ペアについて、system、tools、および共有するmessagesを比較します。新たに追記されたターンまでは同一であるはずです。

次に、APIで確認します。thinking-binding-controls-2026-08-01ベータヘッダーを追加し、prefix_mismatch_behaviorを"drop_block"に設定して、で統合を通じて通常のマルチターンセッションを実行してください。次の例は、統合があるべき方法で2つのターンを実行します。messagesは増えるだけで、各アシスタントターンはthinkingブロックを含めAPIが返したとおりに送り返され、すべてのリクエストでblock_bindingが設定されます。各ターンの後、レスポンス内のthinkingブロックの数と削除されたブロックの数を出力します。

client = anthropic.Anthropic()

user_turns = [
    "How many positive integers below 500 have exactly 6 positive divisors?",
    "How many of those are odd?",
]

# messages はターンごとに増えます。各 assistant ターンは返されたとおりそのまま送り返します
messages = []
for user_turn in user_turns:
    messages.append({"role": "user", "content": user_turn})
    response = client.beta.messages.create(
        model="claude-fable-5-1",
        max_tokens=16000,
        thinking={
            "type": "adaptive",
            "block_binding": {"prefix_mismatch_behavior": "drop_block"},
        },
        messages=messages,
        betas=["thinking-binding-controls-2026-08-01"],
    )
    messages.append({"role": "assistant", "content": response.content})
    thinking_blocks = sum(block.type == "thinking" for block in response.content)
    dropped = len(response.input_transformations or [])
    print(f"thinking blocks: {thinking_blocks}, dropped: {dropped}")
Output
thinking blocks: 1, dropped: 0
thinking blocks: 1, dropped: 0

以前の内容が何も変更されていないため、どちらのターンでもブロックは削除されません。最初のレスポンスにthinkingブロックが含まれていることを確認してください。適応型思考では、思考ブロックを含まないレスポンスもあります。セッション内のどのレスポンスにも含まれていない場合、チェックするものがなく、何を変更しても削除数は0になるため、例を再度実行してください。

あなた自身の統合のすべてのターンでinput_transformationsをログに記録してください。APIがブロックを削除すると、エントリは次のようになります。

{
  "input_transformations": [
    {
      "type": "thinking_dropped",
      "path": "messages.1.content.0",
      "reason": "prefix_binding_mismatch"
    }
  ]
}
  • thinkingブロックを含むセッションのすべてのターンで空: 統合はプレフィックスをそのまま保っています。
  • reason: "prefix_binding_mismatch": 前回のリクエスト以降、pathのブロックより前の何かが変更されました。そのターンまでのsystem、tools、messagesの差分を取って見つけるか、"error"でリクエストを再送信してください。400は通常、何が変更されたかを示す文で終わります。その後、プレフィックスを編集せずに変更を加えるで対応する置き換え方法を見つけてください。
  • reason: "model_binding_mismatch": 会話が、以前のモデルのブロックを読み取れないモデルに移行しました。これはプレフィックスの編集ではありません。会話の途中でのモデルの切り替えを参照してください。
  • reason: "organization_binding_mismatch": ブロックが別のアカウントから来ました。思考ブロックはそれを生成したアカウントに留まるを参照してください。

意図的に失敗を確認するには、前の例から3番目のターンを送信し、そのリクエストにのみsystemプロンプトを追加して、systemプロンプトがなかった最初の2つのリクエストと異なるようにしてください。"drop_block"では、削除数は0ではなくなります。レスポンスには履歴内の思考ブロックごとに1つのエントリがあり、それぞれreason: "prefix_binding_mismatch"を持ちます。"error"では、リクエストは無効なブロックに対するAPIの処理で説明した400を返し、その最後の文はsystemプロンプトを示します。cURLとCLIのタブでは、エラー本文を確認するためにjqフィルターを削除してください。カウントがまだ0の場合は、チェックするものがありませんでした。モデルがであること、リクエストがblock_bindingを設定していること、送信した履歴にthinkingブロックが含まれていること、最初の2つのリクエストにsystemプロンプトがなかったことを確認してください。

単純な2つのターンで問題が表れることはほとんどありません。リグレッションがCIで失敗するように"error"を設定して、次のそれぞれについてセッションを実行してください。

  • 最初のクライアント側のコンパクションまたはトリミング
  • 最初のターンの後に接続するツール、プラグイン、またはMCPサーバー
  • モードまたは指示の変更
  • リマインダーを追加したり古いツール結果を短縮したりする場合は、長いツールループ
  • 別のモデルへの切り替えと元への切り替え
  • 保存、再起動、および後日の再開

古いアカウントでは、適用対象にすることなく本番トラフィックを監視することもできます。ベータヘッダーを送信し、block_bindingを除外して、input_transformationsをログに記録してください。ヘッダーを送信するだけでは、モデルが受け取る内容は変わりません。編集したコンテンツより後にあるすべての思考ブロックはチェックに失敗し、それぞれ独自のthinking_mismatch_allowedエントリを受け取ります。このエントリは、thinking_droppedエントリと同じpathおよびreasonフィールドを持ちます。編集より前のブロックは引き続き合格します。systemまたはtoolsへの編集はすべてのブロックより前にあるため、リクエスト内のすべての思考ブロックが失敗します。1つのエントリは次のようになります。

{
  "input_transformations": [
    {
      "type": "thinking_mismatch_allowed",
      "path": "messages.1.content.0",
      "reason": "prefix_binding_mismatch"
    }
  ]
}

新しいアカウントでは3番目のリクエストが400で拒否されるため、次の例は古いアカウントから実行してください。この例はblock_bindingなしでヘッダーを送信し、システムプロンプトを追加する3番目のリクエストで前のセッションを拡張して、意図的にプレフィックスを変更します。各ターンの後、thinkingブロックの数とフラグが付いたブロックの数を出力します。

client = anthropic.Anthropic()

user_turns = [
    "How many positive integers below 500 have exactly 6 positive divisors?",
    "How many of those are odd?",
    "And how many of the odd ones are below 100?",
]

# messages はターンごとに増えます。各 assistant ターンは返されたとおりそのまま送り返します
messages = []
for turn, user_turn in enumerate(user_turns, start=1):
    messages.append({"role": "user", "content": user_turn})
    response = client.beta.messages.create(
        model="claude-fable-5-1",
        max_tokens=16000,
        thinking={"type": "adaptive"},
        # 最後のリクエストのみシステムプロンプトを追加し、意図的にプレフィックスを変更します
        system="Answer briefly." if turn == len(user_turns) else anthropic.omit,
        messages=messages,
        betas=["thinking-binding-controls-2026-08-01"],
    )
    messages.append({"role": "assistant", "content": response.content})
    thinking_blocks = sum(block.type == "thinking" for block in response.content)
    flagged = sum(
        transformation.type == "thinking_mismatch_allowed"
        for transformation in response.input_transformations or []
    )
    print(f"thinking blocks: {thinking_blocks}, flagged: {flagged}")
Output
thinking blocks: 1, flagged: 0
thinking blocks: 1, flagged: 0
thinking blocks: 1, flagged: 2

新しいシステムプロンプトがそれらすべてより前にあるため、3番目のレスポンスは以前のターンのすべての思考ブロック(この実行ではターンごとに1つ)にフラグを付けます。モデルは引き続きそれらを読み取りました。

これらのエントリは、prefix_binding_mismatchによる削除と同様に扱ってください。編集は、一覧表示された最初のブロックより前にあります。そのブロックのpathまでのsystem、tools、messagesを前回のリクエストと比較して差分を取って見つけ、プレフィックスを編集せずに変更を加えるの対応するパターンに置き換えてください。新しいアカウント、またはprefix_mismatch_behaviorを設定したリクエストでは、APIは代わりにリクエストを拒否するか、失敗したブロックを削除します。これらのエントリは、適用時に削除されるものの下限です。"drop_block"では、失敗したブロックはそのターンの残りの思考ブロックも一緒に削除し、1つのブロックを削除すると次のブロックも失敗する可能性があります。APIがチェックを記録するだけの場合は、各ブロックを個別に判断し、そのブロック自体が失敗した場合にのみ一覧表示します。

プレフィックスを編集せずに変更を加える

一般的なプレフィックスの編集にはそれぞれ、モデルに同じ情報を与えつつ以前のバイトを変更しない置き換え方法があり、以降の思考は有効なままになります。現在コードが行っている編集を最初の列で見つけてください。

避けるべき方法代わりに使用するものベータヘッダー
トップレベルのsystemプロンプトを再構築する会話途中のシステムメッセージなし
リクエストごとに最初のユーザーメッセージ内のコンテキスト(環境、日付、メモリ、プロジェクト指示)を再レンダリングする一度レンダリングし、変更せずに再送信する。何かが変わったら、新しいバージョンを最新のターンに入れるなし
古いtool_resultコンテンツをその場でクリアまたは短縮する、あるいは古い画像を再エンコードするツール結果の短縮や画像の縮小は、後からではなく最初に送信する前に行う。後で古い結果をクリアするには、clear_tool_uses_20250919でサーバー上でコンテキストをトリミングするcontext-management-2025-06-27
リマインダーを挿入し、次のリクエストで削除するターンスコープのシステムメッセージ(clear_at: "next_user_message")mid-conversation-system-clear-at-2026-08-21
toolsのエントリを追加または削除するtool_additionおよびtool_removalブロックinline-tools-2026-09-15(ツールがMCPコネクタ経由で接続されたMCPサーバーから来る場合はmcp-client-2026-09-15を追加)、またはClaude API、Amazon Bedrock、Google Cloudで機能する旧来のmid-conversation-tool-changes-2026-07-01
トップレベルのoutput_config.effortを変更する(キャッシュを最初からやり直させるが、思考には影響しない)メッセージごとのoutput_configmid-conversation-output-config-2026-07-01
クライアント側で古いターンを削除または要約する最近のターンを思考とともに保持するオンデマンドコンパクション、その他のサーバー側のコンパクションまたはコンテキスト編集、または古い思考を保持しないクライアント側のコンパクションcompact-2026-09-04
リクエスト間でバイトが変わる画像またはドキュメントのURLFiles APIのfile_id、またはbase64なし

これらはすべて、アシスタントターンを返されたとおりに送り返すことを前提としています。会話途中のシステムメッセージ、ターンスコープのシステムメッセージ、およびツールの変更は、すべてのモデルで利用できるわけではありません。会話途中のシステムメッセージとツール変更に、それらを受け付けるモデルが一覧表示されています。コードが複数のモデルに対応している場合、それらを受け付けないモデルについては、引き続きトップレベルのsystemプロンプトを編集してください。

Claude APIで1つのリクエストに複数のベータを使用するには、それらの名前を1つのanthropic-betaヘッダーにまとめます。

anthropic-beta: thinking-binding-controls-2026-08-01,mid-conversation-system-clear-at-2026-08-21,inline-tools-2026-09-15

これらのベータを提供する他のプラットフォームでも同じ名前を使用します。そこで送信する方法については、他のプラットフォームでのベータ機能を参照してください。

アシスタントターンを返されたとおりに送り返す

各レスポンスのcontent配列を保存し、アシスタントターンとして変更せずに送り返してください。すべてのブロックタイプを、受信した順序で、thinkingフィールドが空のthinkingブロックも含めて送り返します。未知のブロックタイプを削除したり、空のフィールドを削除したり、ブロックを並べ替えたりするシリアライザーは、以降のすべてのターンでプレフィックスを編集してしまいます。

Claude Fable 5.1、Claude Opus 5.5、Claude Sonnet 5.5、およびClaude Haiku 5.5では、thinkingフィールドはデフォルトで空であり、signatureが推論を保持しているため、空のブロックをスキップするシリアライザーは思考を削除してしまいます。すべてを削除した場合、何も失敗しませんが、モデルはすべてのターンで以前の推論を失います。ストリームを自分で解析する場合は、思考テキストが届かなくてもブロックを保持してください。ブロックは開始され、signature_deltaイベントでsignatureを受け取り、終了します。空のsignatureで送り返されたブロックは失敗します。

会話途中のシステムメッセージで指示を追加する

ハーネスによっては、現在時刻、トークン予算、モードフラグ、新たに見つかったプロジェクトコンテキストなどを伝えるために、リクエストごとにトップレベルのsystemプロンプトを再構築するものがあります。この方法では、会話内のすべての思考ブロックが無効になります。代わりに、セッション開始時にsystemを固定してください。状況が変わったら、その変更が有効になるmessages内の位置にrole: "system"メッセージを追加します。

{
  "role": "system",
  "content": "The user switched the workspace to read-only mode. Do not write files until told otherwise."
}

モデルはこのメッセージをシステムプロンプトと同等の権限で扱います。また、このメッセージより前の内容は変更されません。ツールループでは、このメッセージをtool_resultユーザーメッセージの後に配置してください。アシスタントのtool_useとそれに対応するtool_resultの間には配置しないでください(制限事項を参照)。一度送信したメッセージは、以降の思考のプレフィックスの一部になります。後続のリクエストでもそのまま残してください。

変化するコンテキストを最新のターンに入れる

ハーネスによっては、最初のユーザーメッセージに環境ブロック(作業ディレクトリ、ブランチ、日付、メモリ、プロジェクト指示)を入れ、リクエストごとに再レンダリングするものがあります。この場合、いずれかの値が変わるとmessages[0]が変わり、会話内のすべての思考ブロックが無効になります。環境ブロックは一度だけレンダリングし、以降はそのまま再送信してください。値が変わったら、その変更を最新のターンで伝えます。これから送信するユーザーメッセージにテキストブロックを追加するか、オペレーターとして変更を伝える場合は会話途中のシステムメッセージを追加します。

{
  "role": "user",
  "content": [
    {
      "type": "text",
      "text": "Environment update: the current branch is now release-2."
    },
    { "type": "text", "text": "Run the tests again." }
  ]
}

一度送信したテキストブロックは、以降の思考のプレフィックスの一部になります。後続のリクエストでもそのまま残してください。

ターンごとのリマインダーはターンスコープのシステムメッセージとして送信する

よくあるプレフィックス編集の1つに、ターンごとの「nudge」(促し)があります。これは、「独立した読み取りはまとめてリクエストしてください」や「しばらくユーザーに進捗を伝えていません」といった一文で、コードがツール結果のバッチごとに追加するものです。リマインダーが積み重ならないようにするには、各促しをclear_at: "next_user_message"付きの会話途中のシステムメッセージとして送信し、tool_resultユーザーメッセージの後に配置します。clear_atを使用するには、ベータヘッダーmid-conversation-system-clear-at-2026-08-21が必要です。次のmessages配列は、2回のツール呼び出しとその結果の後に送信するリクエストです。messages[3]は前回のリクエストで送信した促しで、そのまま残しています。messages[6]は今回のリクエストで送信する促しです。

[
  { "role": "user", "content": "Fix the failing test." },
  {
    "role": "assistant",
    "content": [
      { "type": "thinking", "thinking": "", "signature": "..." },
      {
        "type": "tool_use",
        "id": "toolu_01",
        "name": "read_file",
        "input": { "path": "tests/test_auth.py" }
      }
    ]
  },
  {
    "role": "user",
    "content": [{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "..." }]
  },
  {
    "role": "system",
    "clear_at": "next_user_message",
    "content": "Request every independent read in one turn."
  },
  {
    "role": "assistant",
    "content": [
      { "type": "thinking", "thinking": "", "signature": "..." },
      {
        "type": "tool_use",
        "id": "toolu_02",
        "name": "read_file",
        "input": { "path": "src/auth.py" }
      }
    ]
  },
  {
    "role": "user",
    "content": [{ "type": "tool_result", "tool_use_id": "toolu_02", "content": "..." }]
  },
  {
    "role": "system",
    "clear_at": "next_user_message",
    "content": "Request every independent read in one turn."
  }
]

tool_resultブロックのみを含むユーザーメッセージも「次のユーザーメッセージ」とみなされるため、messages[3]はすでにクリアされています。このメッセージはモデルが参照する内容には何も加えず、入力トークンも消費しません。しかし、配列内に残っているため、messages[4]の思考は有効なままです。messages[6]は、このターンでモデルが参照する促しです。後続のリクエストでは、どちらのメッセージもその位置に残したまま、次のtool_resultメッセージの後に新しい促しを追加してください。

tool_additionとtool_removalでツールを追加または削除する

セッションの途中でtools配列を編集すると、保持された思考ブロックが無効になります。配列は最初に送信したままにしておき、モデルが使用できるツールを変更するには、tool_additionまたはtool_removalブロックを含むrole: "system"メッセージを追加します。これらは会話途中のツール変更であり、ベータヘッダーinline-tools-2026-09-15が必要です。このヘッダーはClaude APIで利用できます。従来のmid-conversation-tool-changes-2026-07-01ヘッダーも、参照によってツールを指定する変更については、Claude API、Amazon Bedrock、Google Cloudで引き続き機能します。

これらのブロックの使い方は2通りあります。

  • すべてのツールを事前に宣言する。 セッションで必要になる可能性のあるツールをすべて、最初のリクエストのtoolsに含めます。モデルにまだ見せたくないツールにはdefer_loading: trueを付けます。その後、ツールを指定したtool_additionブロックとtool_removalブロックで、ツールの有効・無効を切り替えます。
  • 最初の時点のツールから始めて、必要に応じて追加する。 最初のリクエストのtoolsには、その時点で把握しているツールを含めます。新しいツールが必要になったら、toolsを編集する代わりに、tool_additionブロック内でそのツールを定義します。

どちらの方法でもtoolsは変わらないため、以前の思考は有効なままで、プロンプトキャッシュもヒットし続けます(このセクションの後半で述べる1つの例外を除く)。

たとえば、モードの切り替え後に危険なツールを使用できないようにするには、次のようにします。

{
  "role": "system",
  "content": [
    { "type": "tool_removal", "tool": { "type": "tool_reference", "name": "delete_branch" } },
    { "type": "text", "text": "Branch deletion is disabled for the rest of this session." }
  ]
}

defer_loading: trueで宣言したツールを有効にするには、そのツールを指定したtool_additionブロックを追加します。

{
  "role": "system",
  "content": [
    { "type": "tool_addition", "tool": { "type": "tool_reference", "name": "deploy" } },
    { "type": "text", "text": "Authentication succeeded. Deployment is now available." }
  ]
}

スキーマがまだわからないために、ツールを事前に宣言できない場合もあります。たとえば、アプリケーションが実行時に見つけるツールや、最初のターンの後に接続するMCPサーバーのツールです。このような場合は、toolsを変更せずに、tool_additionブロック内でツールを定義してください。inline-tools-2026-09-15では、ブロックのtoolに{"type": "tool_definition", "definition": {...}}を指定できます。ここには、toolsに入れる場合と同じエントリを記述します。

{
  "role": "system",
  "content": [
    {
      "type": "tool_addition",
      "tool": {
        "type": "tool_definition",
        "definition": {
          "name": "db_query",
          "description": "Run a read-only SQL query against the analytics database.",
          "input_schema": {
            "type": "object",
            "properties": { "sql": { "type": "string" } },
            "required": ["sql"]
          }
        }
      }
    }
  ]
}

新しいツールはmessages経由で追加され、toolsは変更されないため、以前の思考は有効なままです。toolsには、defer_loading: trueを付けていないツールを少なくとも1つ残してください。tools内のツールがすべて遅延読み込みの場合、この方法で最初にツールを定義したときに、プロンプトキャッシュが1回完全にミスします。

APIがMCPコネクタを通じてMCPサーバーに接続する場合は、mcp-client-2026-09-15も送信してください。このヘッダーはmcp-client-2025-11-20の機能をすべて含むため、mcp-client-2025-11-20の代わりに送信します。この場合、ブロックのdefinitionには、mcp_serversに記載したサーバーのmcp_toolsetを指定できます。APIがサーバーのツールリストを取得する必要がある場合、レスポンスの先頭にそのサーバーのmcp_tool_listingブロックが含まれます。このブロックは、アシスタントターンの他の部分とともに変更せずに送り返してください。また、このブロックを含む以降のすべてのリクエストで、mcp-client-2026-09-15を送信し続けてください。このブロックによってツールセットがそのリストに固定されるため、APIがツールリストを取得するためにサーバーへ再接続することはありません。これらのMCPコネクタの機能は、Claude APIで利用できます。

従来のヘッダーしか使用できない場合でも、セッションの途中で判明したツールをdefer_loading: true付きでtoolsに追加し、tool_additionブロックで提供できます。プレフィックスチェックは、tool_additionブロックから参照されるまで遅延ツールを無視するため、この方法は安全です。defer_loading: trueを付けずにツールを追加すると、プレフィックスが変更され、以前の思考が無効になります。

これらのブロックを含むrole: "system"メッセージは、以降の思考のプレフィックスの一部になります。後続のリクエストでもそのまま残してください。

メッセージごとのoutput_configでeffortを変更する

リクエスト間でトップレベルのoutput_config.effortを変更しても、effortはプレフィックスの一部ではないため、思考は無効になりません。ただし、トップレベルのeffortを変更するとプロンプトキャッシュは再スタートします。モデルとプラットフォームがメッセージごとのeffortをサポートしている場合は、代わりにそれを使用してください。空のcontentと新しいレベルを持つrole: "system"メッセージを追加します。これにはベータヘッダーmid-conversation-output-config-2026-07-01が必要です。Claude Haiku 5.5では、メッセージごとのeffortはClaude APIとGoogle Cloudで利用でき、適応型思考が必要です。

{ "role": "system", "content": [], "output_config": { "effort": "low" } }

新しいレベルがいつ有効になるかは、メッセージを置く位置によって異なります。新しい入力を含むuserメッセージの直後に置いた場合は、そのメッセージに対するClaudeの応答から有効になります。それ以外の位置、たとえばassistantメッセージの後や、tool_resultブロックのみを含むuserメッセージの後に置いた場合は、新しい入力を含む次のuserメッセージから有効になるため、すでに進行中のツールループはそれまで現在のレベルを維持します。一度送信すると、メッセージはmessagesの一部となり、したがって以降の思考のプレフィックスの一部になります。以降のリクエストでもそのまま残し、effortを再度変更するには別のメッセージを追加してください。

サーバー上でコンテキストをトリミングする

もう1つのよくあるプレフィックス編集は、クライアント側でのトリミングです。これは、最も古いターンを削除または要約し、最近のターンをそのまま残す方法です。残したターンの思考ブロックは、削除された履歴がまだ存在していたときに生成されたものなので、チェックに失敗します。一方、サーバー側で同じことを行う機能は、編集とはみなされません。チェックでは、送信したとおりの会話が比較されるためです。

  • オンデマンドコンパクション(ベータ)は、別のリクエストから要約を返します。このリクエストはバックグラウンドで実行できます。返されたブロックは、それが要約するメッセージの代わりに送信します。チェックはこの置き換えを受け入れるため、残したターンは残された思考の条件のもとで、その思考とともに有効なままにできます。要約をリクエストするでは、リクエストの例と必要なベータヘッダーを示しています。
  • トークンしきい値でのコンパクションは、コンテキストが設定したしきい値に近づくと、古いターンをコンパクションブロックに要約し、チェック対象のプレフィックスはそのブロックから始まり直します。そのinstructionsパラメータには、「すべてのティッカー、ポジションサイズ、および明示された前提を保持する」といった独自の要約プロンプトを指定できます。
  • コンテキスト編集は、ルールに従って古いツール結果や古い思考ブロックを、古いものから順にクリアします。戦略はclear_tool_uses_20250919とclear_thinking_20251015です。

クライアント側でのコンパクション

クライアント上でコンパクションを行うことも引き続き可能です。要約を自分で作成する場合は、書き換え前に生成された思考ブロックを送り返さないでください。オンデマンドコンパクションでAPIが要約を作成する場合は、残した思考が有効なままとなる条件に、残された思考が有効なままとなる場合が記載されています。

会話が長くなりすぎたら、セッション全体を1つのユーザーメッセージに要約し、そのメッセージと次の指示のみを送信します。それ以前のものは何も再送されないため、チェックに失敗する思考は残らず、モデルは要約から新たに推論します。

Request 4full historyuser 1asst 1thinkinguser 2asst 2thinkinguser 3asst 3thinkinguser 4compact on the clientRequest 5after compactionuser: summary of turns 1–4 + next instructionno earlier turns replayed, so no thinking to check
[
  {
    "role": "user",
    "content": "<summary of the session so far>\n\n<the next instruction>"
  }
]

Claudeモデルはこの方式で長期的なタスクについて訓練されており、ほとんどのワークロードで良好に機能します。

末尾保持型のコンパクション

末尾保持型のコンパクションは、古いターンを要約し、最新のターンをそのまま残すため、モデルは直近のいくつかのやり取りを一字一句そのまま見ることができます。要約を自分で書く場合、これはルールに違反します。残されたアシスタントターンには、要約ではなく元のターンが前にあったときに生成された思考ブロックがまだ含まれています。それらのブロックは失敗します。

その思考を保持するには、オンデマンドのコンパクションでAPIに要約を書かせてください。直近のターンを保持するコンパクションでその方法を示しており、残した思考が有効なままとなる条件に、残された思考が有効なままとなる場合が記載されています。

このセクションの残りの部分では、自分で書いた要約について説明します。

Beforefull historyuser 1asst 1thinkinguser 2asst 2thinkinguser 3asst 3thinkinguser 4asst 4thinkinguser 5Keep-tail, as writtensummary + recent turns verbatimsummary of 1–2user 3asst 3thinking ✗user 4asst 4thinking ✗user 5asst 3 and asst 4 thinking was produced after user 1 … asst 2, not after the summary, so it failsKeep-tail with drop_blockAPI drops the blockssummary of 1–2user 3asst 3droppeduser 4asst 4droppeduser 5The request succeeds. The model reads asst 3 and 4 without their thinking. input_transformations lists both blocks.

修正方法:ターンをそのままの状態で残し、prefix_mismatch_behavior: "drop_block"を送信します。APIは古くなった思考ブロックを削除し、モデルは残されたターンのtextおよびtool_useブロックを読み取り、リクエストは成功します。

コンパクションされた履歴をmessagesとして渡し、thinking設定にblock_bindingを設定します。次の例では、compacted_messagesはコンパクションのステップで生成された配列です。要約メッセージの後に、APIが返したとおりの残されたターンがthinkingブロックを含めて続きます。

client = anthropic.Anthropic()

# compacted_messages: 要約メッセージの後に、保持されたターンが返されたとおりに続きます
response = client.beta.messages.create(
    model="claude-fable-5-1",
    max_tokens=16000,
    thinking={
        "type": "adaptive",
        "block_binding": {"prefix_mismatch_behavior": "drop_block"},
    },
    messages=compacted_messages,
    betas=["thinking-binding-controls-2026-08-01"],
)

print(response.input_transformations)

レスポンスには通常どおり新しいアシスタントターンが含まれ、さらに削除されたブロックごとに1つのinput_transformationsエントリが含まれます。図の履歴の場合、それはアシスタントターン3と4の思考です。

{
  "input_transformations": [
    {
      "type": "thinking_dropped",
      "path": "messages.2.content.0",
      "reason": "prefix_binding_mismatch"
    },
    {
      "type": "thinking_dropped",
      "path": "messages.4.content.0",
      "reason": "prefix_binding_mismatch"
    }
  ]
}

それら2つのターンが履歴に残っている限り、以降のリクエストでも"drop_block"を送信し続けてください。このリクエスト以降にモデルが生成する思考は要約の後に続くため、有効なままです。ベータヘッダーに依存したくない場合の代替手段は、コンパクションされた履歴を構築する際に、残されたアシスタントターンからthinkingおよびredacted_thinkingブロックを自分で取り除くことです。

バックグラウンド(非同期)コンパクション

バックグラウンドコンパクションは、会話が続いている間にクリティカルパスの外で要約を構築し、数リクエスト後にそれを置き換えます。その間に生成された思考を保持するには、オンデマンドコンパクションでAPIに要約を作成させてください。バックグラウンドでのコンパクションに手順が記載されており、その思考は、残された最近のターンと同じ残された思考の条件のもとで有効なままです。

自分で構築した要約は、末尾保持の場合と同じように、ただし遅れてルールに違反します。要約の構築中に生成されたすべてのアシスタントターンには置き換え前の思考が含まれており、要約が反映された瞬間にそれらすべてが失敗します。自分で構築した要約を使用する場合は、置き換えを末尾保持と同様に扱い、置き換え以降は"drop_block"を送信するか、同期的にコンパクションを行ってください。

保持された思考と併用できないパターン

  • 途中のターンを切り取る。 個々のターンを削除すると、それ以降のすべての思考ブロックが無効になり、どのコンパクション方式でもこれを回避できません。指示を変更するためにターンを切り取ろうとしていた場合は、代わりに会話途中のシステムメッセージを追加してください。古いツール結果や古い思考を選択的に削除するには、サーバー側のコンテキスト編集を使用してください。
  • ツールラウンドの途中でコンパクションする。 アシスタントターンのtool_useと、それに応答するtool_resultの間でコンパクションしないでください。モデルが推論を保ったままラウンドを完了できるよう、そのアシスタントターンは思考をそのまま残して送り返してください。思考ブロックの保持を参照してください。

内容が変わるURLではなく、IDでファイルを参照する

urlソースを持つimageまたはdocumentブロックの場合、チェックの対象はURL文字列ではなく、取得されたバイトです。内容が変わるURL(「最新のスクリーンショット」エンドポイントや、ターンの間に誰かが編集するドキュメントなど)は、以降の思考を無効にします。同じファイルに対するローテーションする署名付きURLは無効にしません。複数のターンにわたって参照するコンテンツは、Files APIで一度アップロードしてfile_idを使用するか、base64で送信してください。

ライブラリ、プロキシ、ゲートウェイ

ライブラリ、プロキシ、ゲートウェイは他者の履歴とAPIの間に位置するため、それ自体による書き換えは編集とみなされ、そのユーザーはそれを確認することも修正することもできません。

  • 認識できないものはそのまま渡す。 呼び出し元のanthropic-betaの値とthinking.block_bindingを変更せずに転送し、input_transformationsを呼び出し元に返してください。未知のキーを拒否するオプションスキーマでは、ユーザーが"drop_block"を選択できなくなります。
  • role: "system"メッセージは呼び出し元が配置した場所に残す。 それをトップレベルのsystemフィールドに移動すると、そのリクエストのsystemが変わり、会話内のすべての思考ブロックが無効になります。
  • リクエストでツール使用をオフにするには、tool_choice: {"type": "none"}を送信する。 toolsは削除しないでください。
  • 400エラーを隠さない。 コードでエラーを捕捉し、思考を削除して呼び出し元の代わりに再試行する場合は、その旨をログに記録してください。呼び出し元の履歴は依然として編集されており、モデルは以降のすべてのリクエストで以前の推論を失います。

よくある質問

次のステップ

最も一般的な思考の失敗を診断して修正します。設定に関する 400 エラー、空または欠落した思考ブロック、max_tokens による停止、キャッシュミスなど。

それ以前のキャッシュ済みプレフィックスを無効にすることなく、会話の途中でシステム指示やツールの利用可否を変更します。

コンテキストウィンドウの上限に近づく長い会話を管理するための、サーバー側のコンテキストコンパクション。

cache_control でプロンプトのプレフィックスをキャッシュし、自動キャッシングまたは 5分もしくは 1時間の TTL を持つ明示的なブレークポイントを使用して、コストとレイテンシを削減します。

Was this page helpful?