◉CLAUDE LABEN
●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り44日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り44日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/API & SDK
⬡ API & SDK/2026-09-02中級

thinking ブロックを弾く 400 が出たとき、会話履歴のどこが書き換わっていたか

Claude Fable 5.1 から、thinking ブロックより前の system・tools・messages を書き換えたリクエストが 400 で弾かれるようになりました。自分のエージェントループが該当するかを1リクエストで確かめる手順と、system の組み立て直し・履歴の切り詰めを書き換えなしのやり方へ移す実装をまとめます。

Claude API128extended thinkingエージェント14トラブルシューティング52Fable 5.1

App Store のレビュー返信の下書きを作る小さなループを、私は Messages API を直接叩いて書いております。数年ぶんのレビューを相手にするので会話が長くなり、system プロンプトには「本日は 2026-09-02 です」のような行を毎回組み立てて入れておりました。日付が変われば文面のトーンも変わりますから、当然の実装のつもりでいたのです。

その「毎回組み立て直す」が、9 月 1 日から意味を持つようになりました。Claude Fable 5.1 では、thinking ブロックより前の会話を書き換えたリクエストが検査に引っかかります。私の実装は、まさに引っかかる側でした。

最初にお伝えしたいのは、慌てて全部を直す話ではないということです。適用されるのは Fable 5.1 だけで、しかも 2026 年 8 月 31 日 00:00 UTC 以降に作られた新しいアカウントに限られます。Claude Code・Claude Cowork・claude.ai、そして他社製品経由の利用は対象外です。ただし今後のモデルでは全アカウントに広がると公式が明記していますから、いま自分のループを一度点検しておくのは、無駄にならない作業だと思っております。

弾かれるのは「thinking ブロックより前」を書き換えたときです

Claude は応答の前に推論を出し、API ではそれが thinking ブロックとして返ります。マルチターンでは、このブロックを署名つきでそのまま送り返します。API 側はその署名を使って、そのブロックを生んだときと同じ system・tools・messages が送られてきているかを検証するようになりました。食い違えば 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".

検査の対象は 3 つあります。モデルが同じか新しいこと、ブロックより前の system・tools・messages が変わっていないこと、そして前の thinking ブロックの連なりが途切れていないことです。3 つめは見落としやすいところで、履歴の先頭から thinking ブロックを外すのは問題ありませんが、途中から1 つ抜くと、それより後ろの thinking がすべて無効になります。

何が「書き換え」に当たるかは、公式が表で示しております。日々の実装で迷いやすいところだけ抜き出します。

2 回のリクエストのあいだで起きたこと後続の thinking ブロック
末尾にメッセージを追加した有効
max_tokens や tool_choice など、system・tools・messages 以外のパラメータを変えた有効
cache_control の位置を足した・動かした・外した有効
サーバー側の compaction や context editing が中身を削った有効(送った内容で照合されるため)
過去の user / assistant / system メッセージを編集・並べ替え・削除した無効
トップレベルの system の文字列やブロックを変えた無効
tools にツールを足した・外した・名前や定義を変えた無効
履歴の途中から thinking ブロックを 1 つ抜いたそれより後ろがすべて無効
画像や文書の URL が、次のリクエストで別のバイト列を返した無効

最後の行は盲点でした。「最新のスクリーンショット」を返すエンドポイントを毎ターン参照していると、URL の文字列は同じでも中身が変わりますから、後続の thinking が無効になります。同じファイルを跨って参照するなら Files API の file_id か base64 に寄せるのが安全です。

自分のループが該当するかは、1 リクエストで分かります

推測で直し始める前に、実際に検査を通してみるのが早道です。ベータヘッダ thinking-binding-controls-2026-08-01 を付けて prefix_mismatch_behavior を "drop_block" にすると、アカウントの新旧に関係なく検査が有効になります。古いアカウントから、新しいアカウントの利用者が見るものを先に見られる、ということです。

curl https://api.anthropic.com/v1/messages \
  -H "content-type: application/json" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
  -d '{
    "model": "claude-fable-5-1",
    "max_tokens": 16000,
    "thinking": {
      "type": "adaptive",
      "block_binding": { "prefix_mismatch_behavior": "drop_block" }
    },
    "system": "You are a review-reply assistant.",
    "messages": [
      { "role": "user", "content": "この星1レビューに返信を書いてください。" },
      {
        "role": "assistant",
        "content": [
          { "type": "thinking", "thinking": "", "signature": "EqQBCkYIBxgCKkD..." },
          { "type": "text", "text": "レビュー本文を貼っていただけますか。" }
        ]
      },
      { "role": "user", "content": "「課金したのに広告が消えません」" }
    ]
  }'

この設定で通常どおり数ターン回すと、レスポンスの先頭に input_transformations が付いてきます。ここを毎ターン記録するだけで、自分の実装が append-only かどうかが判定できます。

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

読み分けは 2 通りです。prefix_binding_mismatch なら、path が指すブロックより前で何かを変えています。前回と今回のリクエストボディを取っておいて、system・tools・その手前までの messages を差分で突き合わせれば、犯人はすぐ出ます。一方 model_binding_mismatch は、ルーターやフォールバックで古いモデルへ移ったという意味で、実装の欠陥ではありません。こちらはブロックを送り続けて、読めない分を API に落とさせるのが正しい振る舞いです。

私は前回リクエストのボディを 1 つだけ手元に持っておいて、次のリクエストの直前に system と tools を突き合わせる 10 行ほどの関数を足しました。CI では "error" にして、履歴を書き換えたら赤くなるようにしております。

私が直したのは、system プロンプトの組み立て直しでした

日付を毎回入れ直していた実装は、会話中システムメッセージに置き換えれば済みました。トップレベルの system はセッション開始時に固定し、途中で伝えたいことができたら messages の中に role: "system" のメッセージを追記します。前の内容は 1 バイトも動きません。

# 変更前: 毎リクエストで system を組み立て直していた(後続の thinking がすべて無効になる)
system = f"You are a review-reply assistant. Today is {date.today()}."
 
# 変更後: system はセッション開始時に固定し、変化は messages へ追記する
system = "You are a review-reply assistant."
 
messages.append({
    "role": "system",
    "content": "日付が変わりました。本日は 2026-09-02 です。以降の返信の日付表記はこれに合わせてください。",
})
messages.append({"role": "user", "content": next_review_text})

この role: "system" メッセージは Fable 5.1 では安定機能で、ベータヘッダは要りません。モデルは system プロンプトと同じ強さで扱います。ツールループの中に置く場合は tool_result を含む user メッセージの後ろに置いてください。assistant の tool_use とその tool_result のあいだに挟むことはできません。

ツールの出し入れも同じ考え方です。tools 配列を直接いじる代わりに、全部をセッション開始時に宣言しておいて、tool_addition と tool_removal で途中から提供・撤回します。ツール定義の変更がプロンプトキャッシュごと壊す話は会話の途中でツールを差し替えるときのレジストリ設計にも書きましたが、今回の検査で「キャッシュが冷える」だけでは済まなくなりました。

履歴の切り詰めは、形によって可否が分かれます

もう 1 つよくある書き換えが、長くなった会話の切り詰めです。ここは全部が禁止されたわけではなく、書き換えた履歴の後ろに thinking ブロックを残さないという一点だけが条件になります。

圧縮の形検査との相性必要な手当て
サーバー側の compaction / context editing通ります不要(送った内容で照合されるため)
単純圧縮(全体を 1 通の要約にして、次のターンから始め直す)通ります不要。過去の thinking を一切引き継がない形です
末尾保持圧縮(古い分を要約し、直近のターンはそのまま残す)落ちます持ち越す assistant ターンから thinking と redacted_thinking を外し、text と tool_use は残します
バックグラウンド圧縮(裏で要約を作って差し替える)落ちます差し替え前に生まれた thinking を含むリクエストで "drop_block" を送るか、同期的に圧縮します
履歴の途中から特定のターンだけ抜く落ちますクライアント側で回避する形はありません。会話中システムメッセージかサーバー側の context editing へ寄せます

意外だったのは、公式が単純圧縮を推奨の形として挙げていることでした。要約 1 通と次の指示だけで messages を作り直し、過去のターンも thinking も一切送り返さない形です。手の込んだ方式と比べても多くのワークロードで同等に働く、と公式が述べております。階層的に要約を積む設計を私はチャット履歴の階層サマライズで試したことがありますが、あれを維持する手間を思うと、単純圧縮に寄せる判断は十分あり得ます。

ひとつだけ守るべき順序があります。ツールラウンドの途中では圧縮しないでください。tool_use が tool_result を待っている assistant ターンは、thinking を付けたまま送り返して、モデルにそのラウンドを最後まで考えさせるのが筋です。

本番では error と drop_block のどちらに倒すか

prefix_mismatch_behavior の既定は "error" です。実装が append-only になったあとであれば、不一致が起きること自体が自分のコードの欠陥を意味しますから、既定のまま 400 で気づくのが健全だと思います。私も CI ではこちらにしております。

"drop_block" を選ぶのは、落ちるより落とすほうがましな場面です。ルーターやフォールバックでモデルが動く構成、あるいは複数のクライアントが同じ会話を触る構成では、こちらのほうが運用が静かになります。ただし黙って消えるので、input_transformations の記録は必ずセットにしてください。記録しないと、品質が落ちた理由が後から分からなくなります。

本番で 400 を掴んだときの復旧手順も決めておくと落ち着きます。同じリクエストをそのまま再送しても通りません。ベータヘッダを付けて "drop_block" で送り直し、そのセッションの残りは "drop_block" を送り続けます。ベータを使えない事情があるなら、履歴からすべての thinking と redacted_thinking を外し、各ターンの text と tool_use を残して 1 回だけ再送します。そのうえで、書き換えていた箇所を直します。

副産物として、思考のコストにも効きます。前置きが 1 バイトも動かない会話はプロンプトキャッシュがそのまま効きますから、拡張思考を本番で回すときの費用にも跳ね返ります。この辺りの費用感は拡張思考を本番導入して見えたコストに整理しております。

私はこの一件を、制約というより設計の指針として受け取りました。会話履歴は書き足す場所であって、書き直す場所ではありません。 日付もモード切り替えもツールの増減も、過去に手を入れずに「いまから、こうです」と足していけば表現できます。言われてみれば当たり前のことなのに、そう気づいたのは、毎リクエスト system を組み立て直すコードを何年も書き続けたあとでした。

まずは手元のループを 1 セッションだけ "drop_block" で通し、input_transformations が空のまま終わるかを見てみてください。空でなければ、path が最初の 1 行を教えてくれます。私もそこから始めました。最後までお読みくださり、ありがとうございました。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

⬡ API & SDK2026-04-26
Claude の「Spanner Temporarily Unavailable」エラーが出たときの読み解き方と対処法
Claude API や Claude.ai で稀に発生する「Spanner temporarily unavailable」エラー。表示は短いのに原因が見えにくいこのエラーを、Anthropic のインフラ構造から逆算して読み解き、開発者が今すぐ取れる現実的な対処法を整理します。
⬡ API & SDK2026-03-28
Claude API 音声エージェント本番アーキテクチャ構築ガイド
Whisper/DeepgramとClaude APIを束ねた音声エージェントを、Cloudflare WorkersとGoogle Cloud Runの両方で運用してきた個人開発者の実体験から、レイテンシ予算・コスト逆算・障害切り替え・本番監視の判断材料を整理しました。
⬡ API & SDK2026-10-16
Make から Claude API に 40 行流すと 14 行目で止まる — 429 を待ち時間の計算で避ける
表計算の行を1件ずつ Claude API に渡すノーコード自動化が、途中で 429 になる理由と直し方です。模擬バケットで7通りの間隔を比べ、Sleep の秒数を 60÷上限−応答時間 で決める式と、失敗行を落とさない設定を示します。