思考ブロックのプレフィックスチェック
プレフィックスチェックが何を比較するか、どのモデルがそれを実行するか、リクエストがそれに失敗したときに何が起こるか、そして400エラーとエラーが発生しない場合への対処方法について説明します。
保持された思考を持つモデルに思考ブロックを送り返す各リクエストには、「prefix check」(プレフィックスチェック)が行われます。Claudeがブロックを生成した後にsystem、tools、またはそれより前のメッセージが変更された場合、プレフィックスチェックは失敗します。また、他の思考ブロックの間にある思考ブロックが省かれたり移動されたりした場合にも失敗します。
プレフィックスチェックに失敗した場合、400エラーになることもあれば、ならないこともあり、モデルによって異なります。そのため、両方のケースに対処するようにしてください。
プレフィックスチェックの影響を受けるのは誰か
次のいずれかに当てはまる場合、変更する必要はありません。
- Claude Code、claude.ai、またはClaude Managed Agentsが会話履歴を管理している。
- Claude Agent SDKが履歴を管理しており、SDKに渡すシステムプロンプトが変わらない。
- コードが「append-only」(追記のみ)な統合の3つの習慣に従っており、途中でリクエストを書き換えるものが何もない。
- 保持された思考を持つモデルを呼び出していない。
リクエストがライブラリ、プロキシ、またはゲートウェイを経由する場合は、それが送信する内容と、あなたが送信した内容を比較してください。それらを運用している場合は、何をそのまま通すべきかについてライブラリ、プロキシ、ゲートウェイを参照してください。
何が変わってはならないのか、そしてその理由
統合を追記のみにしてください。次の3つの習慣でそれが実現できます。
- 各アシスタントターンは、テキストが空の思考ブロックも含め、APIが返したとおりに正確に送り返します。
systemとtoolsは会話ごとに一度だけ構築し、毎回そのコピーを送信します。- すべての更新は末尾の新しいメッセージに入れ、そのままにしておきます。
各思考ブロックの推論は、そのブロックより前にあったもの、つまりsystem、tools、およびそれより前のすべてのメッセージに正確に基づいています。その内容がブロックのプレフィックスであり、プレフィックスチェックが比較するのはこれです。
プレフィックスチェックはプロンプトキャッシングに似ていますが、変更があった場合、単にキャッシュミスになるのではなく、その後の思考が無効になる点が異なります。
システムプロンプトに今日の日付を入れるアプリを例に考えます。午前0時に日付が変わると、会話内にすでにある思考のプレフィックスも変わります。その思考は無効になり、次のリクエストは失敗する可能性があります。追記のみのアプリは、システムプロンプトを元のまま保ち、新しい日付を末尾のメッセージで伝えます。
変更によって無効になるのは、すでにその後に続いている思考だけです。変更より前の思考と、その後にClaudeが生成する思考は有効なままです。
コードがシステムプロンプト、ツール、または履歴を変更する場合
| コードが次のことを行う場合… | 対処方法 |
|---|---|
| 日付、モード、または指示ファイルを使ってシステムプロンプトを再構築する | systemの変更をやめてください。独自の指示をシステムメッセージとして追加し(messages内のrole: "system"エントリ)、新しい値は最新のターンで伝えてください。他の人が編集できるテキストについては、代わりに他の人が編集できるテキストを参照してください。 |
| ツールを追加、削除、または言い換える、あるいはMCPサーバーの接続時にツールが増える | toolsの変更をやめ、システムメッセージでツールを追加または削除してください。 |
| 古いターンを切り詰める、折りたたむ、または要約し、最新のターンは変更しない | APIに要約を書かせるか、残したターンの思考を削除してください。 |
テキストが空の思考ブロックを省く、保存された会話を再構築するなど、その他の原因にはそれぞれ独自の修正方法があります。プレフィックスチェックに失敗せずにツールや指示を変更するを参照してください。自分の原因を見つけるには、エージェントにコードを確認させてください。
プレフィックスチェックが失敗したときに各モデルが行うこと
Claude APIおよび一部のクラウドプラットフォームでは、prefix_mismatch_behaviorを未設定のままにしてプレフィックスチェックに失敗した場合の結果は、モデルによって異なります。
| 保持された思考を持つモデル | 結果 |
|---|---|
| Claude Fable 5.2 | 400エラー |
| Claude Mythos 5.2 | 400エラー |
| Claude Mythos 5.1 | 400エラー |
| Claude Fable 5.1 | 400エラーの可能性あり |
| Claude Opus 5.5 | 400エラーの可能性あり |
| Claude Sonnet 5.5 | 400エラーの可能性あり |
| Claude Haiku 5.5 | 400エラーの可能性あり |
表に「400エラーの可能性あり」とある場合、2つのケースがあります。プレフィックスチェックに失敗したリクエストは、400エラーを受け取ることもあれば、エラーを受け取らないこともあります。エラーが返されない場合、プレフィックスチェックに失敗したブロックはモデルに届きます。Claudeはそれらを他の入力と同様に読み取り、それらに対して課金が発生し、Claudeはその後変更された内容についての推論をもとに作業します。
これらのモデルでは、リクエストがどちらのケースになるかを確認することができますが、両方のケースに対処するようにしてください。
prefix_mismatch_behaviorを未設定のままにしたMessage Batchesのアイテムはエラーを受け取らず、APIはプレフィックスチェックに失敗したブロックを除外する場合があります。
両方のケースに対処する
すべてのリクエストで1つの結果を得るには、統合を追記のみにするか、prefix_mismatch_behaviorを設定してください。そうでない場合、コードは両方の動作に対処する必要があります。
- 追記のみ: 3つの習慣に従えば、コードによってリクエストがプレフィックスチェックに失敗することはありません。
- 設定: すべてのリクエストで
"error"を指定すると、プレフィックスチェックの各失敗は400エラーになり、コードでそれを捕捉します。 - 両方の動作: 設定を未設定のままにする場合は、400エラーを捕捉し、Claudeに届いた、プレフィックスチェックに失敗した思考を監視してください。
400エラーの後は、回復するためにその会話の以降のリクエストで"drop_block"を送信してください。これにはコストが伴います。思考の除外によるコストを参照してください。エラーを隠すためにすべての会話でこれを送信しないでください。
技術的な詳細
プレフィックスチェックの仕組み
保持された思考を持つモデルは、各思考ブロックのプレフィックスのフィンガープリントをそのsignatureに記録します。APIリファレンスではプレフィックスチェックを会話チェックと呼んでおり、400エラーはプレフィックスチェックに失敗したブロックがis bound to a different conversationであると示します。
どのモデルがプレフィックスチェックを実行するか
プレフィックスチェックは、Claude APIおよび一部のクラウドプラットフォームで実行されます。これは、保持された思考を持つモデルが生成した思考ブロックを、それらのモデルのいずれかへのリクエストにおいてチェックします。Claude APIでは、Claude Opus 5などの他のモデルはこれを実行せず、それらのブロックも対象になりません。
何が変更とみなされるか
- 各ブロックはそれぞれ独自の記録と照合されます。 APIは、このリクエストでブロックより前にあるものと、Claudeがそのブロックを生成したときにその署名が記録したものを比較します。前回のリクエストは関係しません。プレフィックスチェックは内容だけを見て、セッション、ID、ユーザーは見ません。新しいリクエストやフォークでも同じ内容であれば、プレフィックスチェックに合格します。
- プレフィックスチェックは、Claudeが読み取った内容ではなく、あなたが送信した内容を比較します。 トークンしきい値でのコンパクションとコンテキスト編集は、Claudeが読み取る内容だけを変更するため、決して変更とはみなされません。しきい値コンパクションブロックの後は、APIはそのブロック以降のメッセージと、
systemおよびtoolsだけを比較します。オンデマンドコンパクションには独自の条件があります。残した思考が有効なままとなる条件を参照してください。URLで送信されたファイル、およびClaude APIではMCPツールリストについては、APIは代わりに取得した内容を比較します。 - 送信する思考は途切れのない連続でなければなりません。 思考ブロックは内容としては比較されません。ただし、送信する各思考ブロックは、最初のものを除き、Claudeがそれを生成したときと同じ直前の思考ブロックを持っていなければなりません。そのため、最も古いもの、最も新しいもの、またはすべてを省くことはできますが、間にあるものを1つ省くことはできません。
変更はツールの説明の1単語程度の小さなものでもあり得ます。それより前のメッセージの変更、挿入、移動、削除は、ロールにかかわらず変更とみなされます。同じメッセージ内で思考ブロックより前にあるテキストを変更した場合も同様です。
変更とみなされないもの
| 変更とみなされないもの | 理由 |
|---|---|
model、effort、max_tokens、tool_choice、metadata、thinking.display、およびその他のパラメータ | 比較されるのはsystem、tools、およびメッセージだけです |
| JSONのフォーマットやキーの順序 | APIはテキストではなく、パースされたJSONを比較します |
cache_controlマーカー | これらはどこでキャッシュするかを示すものであり、Claudeが読み取る内容ではありません |
何からも参照されていないdefer_loading: trueのツール | 何かが参照するまで、Claudeのコンテキストに含まれません |
prefix_mismatch_behaviorを設定する
ベータヘッダーthinking-binding-controls-2026-08-01は、設定thinking.block_binding.prefix_mismatch_behaviorと、レスポンスのinput_transformations配列を追加します。
| 値 | ブロックがプレフィックスチェックに失敗した場合 |
|---|---|
"error" | APIは、最初の無効なブロックを示す400エラーでリクエストを拒否します |
"drop_block" | APIは無効なブロックを除外し、リクエストは成功します。それらのブロックに対して課金は発生しませんが、それらを除外するとコストが増える場合があります |
未設定、またはnull | モデルによって異なります |
プレフィックスチェックに失敗したブロックは、変更が残っている間、それらを送信する以降のすべてのリクエストで無効なままです。この設定は、それを含む1つのリクエストに対してのみ作用します。思考がオフ("disabled"または"between_tools")の場合、これを送信するとすべてのモデルで400エラーになります。
次のリクエストはprefix_mismatch_behaviorを"drop_block"に設定しています。最初のターンでは送り返す思考がないため、input_transformationsは空で返されます。
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5-5",
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 [])}")本番トラフィックを監視する
prefix_mismatch_behaviorが未設定の場合、一部のモデルでは、プレフィックスチェックに失敗したリクエストがエラーを受け取らない可能性があります。その場合、プレフィックスチェックに失敗した思考ブロックはモデルに届きます。本番トラフィックでそれらのブロックを見つけるには、thinking-binding-controls-2026-08-01ベータヘッダーを送信し、設定を未設定のままにして、各レスポンスのinput_transformations配列をログに記録してください。ヘッダーはその配列を追加するものであり、モデルが受け取る内容は変わりません。
それらの各ブロックは、その配列内に独自のthinking_mismatch_allowedエントリを持ちます。1つのエントリは次のようになります。
{
"input_transformations": [
{
"type": "thinking_mismatch_allowed",
"path": "messages.1.content.0",
"reason": "prefix_binding_mismatch"
}
]
}変更を見つけるには、コードが変更したものを見つけるを参照してください。
どちらのケースになるかを確認する
一部のモデルでは、プレフィックスチェックに失敗したリクエストは、400エラーを受け取る可能性も、エラーを受け取らない可能性もあります。次のテストで、リクエストがどちらになるかがわかります。
- それらのモデルのいずれかによる思考ブロックを含む会話を用意します。システムプロンプト(
system)を変更または追加します。Claudeがそのブロックを生成した後にシステムプロンプトが変更されたため、そのブロックはプレフィックスチェックに失敗します。 thinking-binding-controls-2026-08-01ベータヘッダーを付けて同じモデルに送信し、prefix_mismatch_behaviorは未設定のままにします。
レスポンスは次のいずれかです。
bound to a different conversationと示す400エラー: リクエストは400エラーを受け取りました。input_transformations配列にthinking_mismatch_allowedエントリがある200レスポンス: リクエストはエラーを受け取りませんでした。各エントリは、プレフィックスチェックに失敗してClaudeに届いた思考ブロックを示します。input_transformations配列が空の200レスポンス: プレフィックスチェックに失敗したブロックはないため、このテストでは何もわかりません。会話にそのモデルによる思考ブロックが含まれていることを確認してください。
この結果はその1つのリクエストについて示すものであり、以降のリクエストについては何も保証しません。そのため、両方のケースに対処するようにコードを書いてください。
次のステップ
コードが会話に加える各変更の代わりに何を送信すべきかを説明します。
プレフィックスチェックに失敗している会話を回復し、コードが何を変更しているかを見つけ、それが解消されたことをテストします。
保持された思考とは何か、思考ブロックが何に結び付けられているか、そしてモデルやアカウントの切り替えについて説明します。
このページは役に立ちましたか?