Claude Platform Docs
Messages思考

保持された思考

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

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

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

モデルチェックはすべてのアカウントに適用されます。プレフィックスチェックは、2026年8月31日00:00 UTC以降に作成されたアカウントではデフォルトで適用されます。それより前に作成されたアカウントでは、thinking.block_binding.prefix_mismatch_behaviorを設定したリクエストにのみ適用されます。今後のモデルでは、すべてのアカウントにプレフィックスチェックが適用されます。 そのため、今のうちに統合を「append-only」(追記専用)にしてください。

変更が必要なケース

Claude Code、claude.ai、Claude Managed Agents、またはClaude Agent SDKがリクエストを構築している場合は、対応は不要です。コードがセッション中にsystemtoolsを固定し、messagesへの追記しか行わない場合も同様です。Claude Mythos 5.1と、Claude Fable 5.1より前のモデルは、プレフィックスチェックを実行しません。思考ブロックを一切送り返さない場合は、プレフィックスチェックで拒否されるものはありません。ただし、その場合モデルは以前の推論を一切利用できません。

1つの会話内の2つのリクエストの間で、統合が次のいずれかを行っている場合は確認が必要です。各項目のリンク先で、代わりの方法を説明しています。

古いアカウントでは、リクエストでprefix_mismatch_behaviorを設定しない限り、これらはいずれもエラーになりません。そのため、自分のキーでエラーなく実行できても、コードが影響を受けるかどうかは判断できません。ユーザーが自分のAPIキーでツールを実行する場合、新しいアカウントのユーザーは、あなたより先に400エラーに遭遇します。テストでprefix_mismatch_behaviorを設定して、ユーザーと同じ結果を確認してください。

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

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

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

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

アニメーション:Claude Opusに切り替えると、そのターンではClaude Fable 5.1の思考がスキップされ、元に戻すとすべてが再び読み取られる

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 Fable 5.1では、思考ブロックが有効なのは、そのブロックより前に送信したすべての内容が、後続のリクエストでも変更されていない間だけです。チェック対象のプレフィックスは、次の3つの部分で構成されます。

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

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

これら3つのフィールド以外のリクエストパラメータ(effortmax_tokensoutput_configtool_choicemetadataなど)は、プレフィックスチェックの対象外です。cache_controlマーカーも対象外です。完全な一覧は編集とみなされるものを参照してください。

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

セッション中はsystemtoolsを固定し、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"とともに記載されます。

"drop_block"を使うとリクエストは成功し続けますが、原因となった編集が修正されるわけではありません。各セッションで、input_transformationsprefix_binding_mismatchエントリを含むレスポンスの数を集計し、アラートを設定してください。Message Batches 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は適用されません。

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

ここで扱うのは、このセクションで前述した400 invalid_request_errorです。同じボディを再送信しないでください。何度送信しても同じように失敗します。ベータヘッダーとprefix_mismatch_behavior: "drop_block"を付けて一度だけ再試行してください。そのうえで、この設定をセッションとともに保存し、再起動後も含めて以降のすべてのリクエストで送信するようにします。ベータヘッダーを送信できない場合は、履歴からすべての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"のどちらとも併用できます。ベータヘッダーなしで送信すると400エラーが返され、そのメッセージはblock_binding: Extra inputs are not permittedで終わります。プレフィックスチェックを実行しないモデルもこのオブジェクトを受け付け、モデルチェックによる削除のみを報告します。そのため、同じリクエストボディを複数のモデルで使用できます。なお、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が含まれます。何も削除されなかった場合、この配列は空です。各エントリには、type: "thinking_dropped"、削除されたブロックのpath(例:messages.1.content.0)、およびreasonが含まれます。reasonprefix_binding_mismatchまたはmodel_binding_mismatchのいずれかです(会話の途中でのモデルの切り替えを参照)。今後のチェックで値が追加される可能性があるため、認識できないtypereasonを持つエントリは無視してください。

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

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

プレフィックスチェックは、新しいアカウントのClaude Fable 5.1リクエストで実行されます。

  • 2026年8月31日00:00 UTC以降に作成されたアカウント: APIはClaude Fable 5.1のリクエストをチェックし、"drop_block"を設定しない限り"error"を適用します。新しいアカウントの定義は、Claude APIとクラウドプラットフォームで共通です。
  • それより前に作成されたアカウント: APIは、prefix_mismatch_behaviorを設定したリクエストのみをチェックします。このパラメータを設定するとリクエスト単位でチェックが有効になるため、新しいアカウントを作成しなくても、新しいアカウントと同じ動作を確認できます。
  • 今後のモデル: すべてのアカウントのすべてのリクエストでチェックされます。

自分のアカウントがどちらに該当するかを確認するには、思考ブロックを含むClaude Fable 5.1の会話を用意し、そのブロックより前の内容を変更します。そのうえで、ベータヘッダーもblock_bindingフィールドも付けずにClaude Fable 5.1に送信します。ヘッダーに言及した400レスポンスが返された場合、そのアカウントではデフォルトでチェックが適用されています。

編集とみなされるもの

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

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

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

まず、送信内容の差分を確認します。コンパクションやツールの変更を含む通常の数ターン分について、統合が送信するリクエストボディを記録します。連続するリクエストの各ペアについて、systemtools、および両方に含まれる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ブロックが含まれていることを確認してください。「adaptive 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が示すブロックより前の内容が変更されています。そのターンまでのsystemtoolsmessagesの差分を取って原因を特定してください。または、"error"を設定してリクエストを再送信します。400エラーのメッセージの最後には通常、何が変更されたかを示す文が付きます。原因を特定したら、プレフィックスを編集せずに変更を加えるで対応する代替手段を確認してください。
  • reason: "model_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サーバー
  • モードまたは指示の変更
  • 長いツールループ(リマインダーを追加する場合や、古いツール結果を短縮する場合)
  • 別のモデルへの切り替えと、元のモデルへの復帰
  • 保存、再起動、および後日の再開

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

よくあるプレフィックス編集には、それぞれ代替手段があります。代替手段を使うと、モデルに同じ情報を伝えつつ、以前のバイト列を変更せずに済むため、以降の思考は有効なままです。現在コードで行っている編集を、最初の列から探してください。

避けるべき方法代わりに使用するものベータヘッダー
トップレベルの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ブロックmid-conversation-tool-changes-2026-07-01
トップレベルのoutput_config.effortを変更する(キャッシュは最初からやり直しになりますが、思考には影響しません)メッセージごとのoutput_configmid-conversation-output-config-2026-07-01
クライアント側で古いターンを削除または要約する最近のターンを思考とともに保持できるオンデマンドコンパクション、その他のサーバー側のコンパクションまたはコンテキスト編集、または古い思考を残さないクライアント側コンパクションcompact-2026-09-04(Amazon BedrockとGoogle Cloudでは利用不可)
リクエストごとにバイト列が変わる画像またはドキュメントのURLFiles APIのfile_id、またはbase64なし

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

1つのリクエストで複数のベータを使用するには、値を1つのanthropic-betaヘッダーにまとめます。Amazon BedrockとGoogle Cloudでも、そのベータが利用可能であれば、ベータ名は同じです(ベータヘッダーを参照)。

anthropic-beta: thinking-binding-controls-2026-08-01,mid-conversation-system-clear-at-2026-08-21,mid-conversation-tool-changes-2026-07-01

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

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

Claude Fable 5.1では、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_additiontool_removalでツールを追加または削除する

セッションの途中でtools配列を編集すると、保持された思考ブロックが無効になります。代わりに、セッションで必要になる可能性のあるツールをすべて最初のリクエストのtoolsで宣言し、以降は配列を変更しないでください。ある時点からモデルが使用できるツールを変更するには、tool_removalブロックまたはtool_additionブロックを含むrole: "system"メッセージを追加します。これらは会話途中のツールの変更と呼ばれる機能で、ベータヘッダーmid-conversation-tool-changes-2026-07-01が必要です。たとえば、モードの切り替え後に危険なツールを使用できないようにするには、次のようにします。

{
  "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を付けてtoolsで宣言しておきます。ツールを使用できるようになったら、tool_additionブロックを追加します。

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

スキーマがまだわからないために、ツールを事前に宣言できない場合もあります。よくある例は、実行時に見つかるMCPサーバーです。このような場合は、そのツールをdefer_loading: true付きでtoolsに追加し、tool_additionブロックで提供してください。遅延ツールの追加は安全です。プレフィックスチェックは、tool_additionブロックから参照されるまで遅延ツールを無視するため、以前の思考は有効なままです。defer_loading: trueを付けずにツールを追加すると、プレフィックスが変更され、以前の思考が無効になります。

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

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

effortはプレフィックスに含まれないため、リクエスト間でトップレベルのoutput_config.effortを変更しても、思考は無効になりません。ただし、トップレベルのeffortを変更すると、プロンプトキャッシュは最初からやり直しになります。Claude Fable 5.1では、代わりにメッセージごとのeffortを使用してください。contentを空にし、新しいレベルを指定したrole: "system"メッセージを追加します。この機能を使用するには、ベータヘッダーmid-conversation-output-config-2026-07-01が必要です。

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

新しいレベルは、次のuserターンから適用されます。一度送信したメッセージはmessagesの一部となり、以降の思考のプレフィックスにも含まれます。後続のリクエストでもそのまま残してください。effortを再度変更するときは、新しいメッセージを追加します。

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

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

  • コンパクションは、コンテキストが設定したしきい値に近づくと、古いターンをコンパクションブロックに要約します。チェック対象のプレフィックスは、そのブロックから始まり直します。instructionsパラメータには、「すべてのティッカー、ポジションサイズ、明示された前提を保持する」のような独自の要約プロンプトを指定できます。オンデマンドコンパクション(ベータ)では、別のリクエストで要約を取得でき、このリクエストはバックグラウンドで実行できます。リクエストボディで"compaction": {"type": "summarize"}を送信すると、レスポンスには通常の応答の代わりに、要約と署名を含む単一のcompactionブロックが返されます。オンデマンドコンパクションはClaude APIで利用できますが、Amazon BedrockとGoogle Cloudでは利用できません。要約リクエストと、そのブロックを含む以降のすべてのリクエストで、compact-2026-09-04ベータヘッダーが必要です。このブロックは、要約対象のメッセージの代わりに送信します。チェックはこの置き換えを許容するため、Keep-tailコンパクションの条件を満たせば、残したターンを思考とともに有効なまま保てます。
  • context editing」(コンテキスト編集)は、ルールに従って、古いツール結果や古い思考ブロックを古いものから順にクリアします。使用できる戦略はclear_tool_uses_20250919clear_thinking_20251015です。

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

クライアント側でも引き続き「compaction」(コンパクション)を行えます。要約を自分で作成する場合は、書き換え前に生成された「thinking block」(思考ブロック)を送り返さないでください。APIがオンデマンドコンパクションで要約を作成する場合、保持された思考が有効なままとなる条件は末尾保持コンパクションに記載されています。

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

Simple compaction(シンプルなコンパクション):リクエスト4は各アシスタントターンに思考を含む完全な履歴を送信します。リクエスト5はターン1〜4の要約と次の指示を含む1つのユーザーメッセージを送信するため、以前の思考は送信されず、何もチェックされません
[
  {
    "role": "user",
    "content": "<summary of the session so far>\n\n<the next instruction>"
  }
]

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

末尾保持コンパクション

「keep-tail compaction」(末尾保持コンパクション)は、古いターンを要約し、最新のターンをそのまま保持するため、モデルは直近のいくつかのやり取りを一字一句そのまま参照できます。要約を自分で作成すると、ルールに違反します。保持されたアシスタントターンには、要約ではなく元のターンが前にあった時点で生成された思考ブロックが残っているためです。これらのブロックは失敗します。

その思考を保持するには、オンデマンドコンパクションでAPIに要約を作成させます。compactionパラメータとcompact-2026-09-04ベータヘッダーを付けたリクエストで、古いターンのみを送信します。次に、返された署名付きブロックをそれらのターンの代わりに送信し、その後に保持するターンを返されたとおりに続けます。以下のすべてが満たされている間、保持された思考は有効なままです。

  • コンパクションリクエストが、「preserved thinking」(保持された思考)に対応したモデルで実行されること。会話自体のモデルを使うのが簡単な選択です。
  • 保持するターンが要約されたメッセージの直後に続き、最初の保持メッセージが、APIが最後の要約メッセージにマージするようなメッセージ(同じロールのメッセージ、またはrole: "system"メッセージ)ではないこと。
  • systemと非遅延のtoolsがコンパクションリクエストと一致していること。

2つ目の条件を満たす最も簡単な方法は、すでに送信したリクエストのmessagesをそのままコンパクションすることです。要約されたターン内の会話途中のシステムメッセージも要約されるため、その指示とツール変更は置き換え後に適用されなくなります。いずれかを有効なままにするには、保持するターンの後に続く最初の新しいuserターンの直後に、role: "system"メッセージで再度記述してください。ブロックと保持するターンの間にシステムメッセージを配置すると、それらの思考が無効になります。

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

Keep-tail compaction(末尾保持コンパクション):履歴はターン1と2の要約と、それに続くそのままのターン3〜5に置き換えられます。アシスタントターン3と4の思考は要約ではなく元のターンの後に生成されたため、失敗します。同じリクエストをprefix_mismatch_behavior drop_blockで送信すると成功し、APIはこれら2つのブロックを削除してinput_transformationsに記載します

修正方法:ターンをそのまま保持し、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に要約を作成させます。

  1. これまでの会話を、compactionパラメータとcompact-2026-09-04ベータヘッダーを付けた別のリクエストで送信します。
  2. そのリクエストの実行中も、完全な履歴で作業を続けます。
  3. ブロックが届いた後の最初のリクエストで、コンパクションリクエストに含まれていたメッセージの代わりにそのブロックを送信し、その後にそれ以降に追加されたすべてのターンを続けます。

要約の構築中に生成された思考は、末尾保持コンパクションと同じ条件のもとで有効なままです。

自分で構築した要約は、末尾保持の場合と同じように、ただし遅れてルールに違反します。要約の構築中に生成されたすべてのアシスタントターンには置き換え前の思考が含まれており、要約が反映された瞬間にそれらすべてが失敗します。自分で構築した要約を使用する場合は、置き換えを末尾保持と同様に扱い、置き換え以降は"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?