Max Nardit
← 記事
7 mindev

Messages API の Claude メッセージスレッド:スレッドが省くのはアップロード、プレフィルを省けるのはキャッシュだけ

TTFT 35% 短縮という数字は本物ですが、対象は 50 万トークン以上の Claude Code のトラフィックに限られます。スレッドとプロンプトキャッシュは別々のコストを、別々のタイマーで削ります。1 時間キャッシュでは、先に期限が切れるのはスレッドの方です。

目次

11 月 2 日、Anthropic は Messages API にメッセージスレッドをベータとして追加しました。ベータヘッダーは message-threads-2026-08-12 です。最初のリクエストでは "thread": {"type": "create"} を付けて会話全体を送ります。以降のリクエストで送るのは新しいメッセージと直前のレスポンスの id だけで、残りは API 側で組み立て直されます。リリースノートによると、対象は Claude API、Claude Platform on AWS、Claude in Microsoft Foundry、Claude Models on Google Cloud(Anthropic 運営)です。

うたい文句は長いエージェントループの高速化です。ただ、ドキュメントをプロンプトキャッシュのページと並べて読むと、スレッドが取り除くのはコストの片方だけで、もう片方はキャッシュ任せだとわかります。大きいのはプレフィルの方で、スレッドはそこには一切手を付けません。

Claude メッセージスレッドで実際に速くなるのは何か

速くなるのは送信で、モデルによる読み込みではありません。ドキュメントによれば、スレッドなしではクライアントがターンごとに会話全体を再アップロードし、API がそのすべてを検証し直し、トークン化し直します。スレッドがあれば、その作業の大半は新しいターンの分だけで済みます。それでもモデルはすべてを読みます。Anthropic の発表も、トークン使用量は変わらず、料金とレート制限も変わらないとしています。

つまり効果は、再送している量に比例します。コンテキストが 80 万トークンに達したコーディングエージェントが 2,000 トークンのツール結果を追加する場合、これまでは 2,000 トークンの新情報を伝えるために 80 万トークンを丸ごと送っていました。発表に載っている実測値は 1 つだけです。

With message threads on by default for most Claude Code users, requests with
500k to 1M tokens see median TTFT drop by about 35%.

これは中央値で、Claude Code のトラフィックのうち、コンテキストサイズが最も大きい帯での数字です。なぜそこで効果が出るのか、私の見立てはこうです。Claude Code はプロンプトのプレフィックスをキャッシュしているので、プレフィルがすでに短く済む状態では、会話の転送時間が残りの待ち時間の大きな割合を占めます。5 万トークンの会話についての数字は誰も公開していません。再送する量がずっと少ないので短縮幅も小さいはずですが、どれだけ小さいかは測られていません。Claude Code の CHANGELOG は 2.1.317 までスレッドに一言も触れていません。「デフォルトで有効」という記述は Anthropic の発表の中にあるもので、どのバージョンからかを示すリリースノートの記載ではありません。

Claude メッセージスレッドはプロンプトをキャッシュするか

しません。ドキュメントにも一文ではっきり書かれています。スレッドがプロンプトを自動でキャッシュしてくれることはありません。プレフィル、つまり最初のトークンを出す前にモデルが会話を処理する工程を省けるのはプロンプトキャッシュで、ブレークポイントを置くのは引き続き自分です。簡単なのは、毎回のリクエストにトップレベルの cache_control を付ける方法です。

このフィールドは、スレッド内で変更できない固定フィールドの 1 つです。model、thinking、tool_choice、output_config、ベータヘッダーの組み合わせ、トップレベルの cache_control は毎ターン create リクエストと一致している必要があり、違えば API は thread_fingerprint_mismatch を返します。system と tools は create リクエストにだけ入れます。これらのいずれかを変えるなら、新しいスレッドが必要です。

ブレークポイントの上限はいつもどおり 4 つですが、自由度は下がります。create リクエストの system と tools に置いたブレークポイントは continue のたびに再びカウントされ、一度送ったブレークポイントは移動も削除もできません。手動でリプレイする場合は、先にメッセージ内の古いブレークポイントを外してください。SDK のヘルパーはこれを自動でやってくれます。

ここで、独立したタイマーが 2 つあることになります。スレッドは最後のリクエストから 5 分で失効します。キャッシュの寿命はデフォルトで 5 分、書き込み料金を上乗せして ttl: "1h" にすれば 1 時間です(Claude Code では 1 時間になるのは一部のセッションだけです)。1 時間 TTL の場合、20 分の中断でスレッドは消えても、キャッシュは有効なまま残ることがあります。その場合、リプレイでは全体を再アップロードしますが、プレフィックスと設定が一致していれば、プレフィックス部分はキャッシュから安く読み込まれます。失われたスレッドは自分から知らせてくれます。次の continue が 404 を返すからです。失われたキャッシュは何も言いません。期限切れのエントリーとプロンプトの変更を見分けるにはキャッシュ診断を使います。

Claude メッセージスレッドが対応していないもの

長い会話を管理するための道具の大半です。

append-only        each response id can be continued once; no edits, no branches
5-minute expiry    then a continue returns 404 thread_not_found
no compaction      compaction on demand returns 400; summarize in your code, start a new thread
no context editing except clear_thinking_20251015 with keep: "all"
no token counting  count the full conversation with system and tools instead
no batches         a batch item with thread fails with invalid_request_error
not ZDR eligible   held in memory, deleted no more than 1 hour after last use

HIPAA Readiness や推論フック(inference hooks)を使っている組織は、スレッドをまったく使えません。さらに、API がそのターンを保存したかどうかはどのレスポンスにも示されず、次の continue で初めてわかります。そのため、すべてのメッセージはアプリ側で保持してください。どのスレッドも 5 分放置されればリプレイで終わります。この経路は初日から組み込み、メインの経路と同じようにテストしてください。

Anthropic SDK は Claude メッセージスレッドをデフォルトで有効にするか

ツールランナーでは有効になります。anthropic 2.4.0 の Python wheel を読みました。ツールランナーは thread=False を渡さない限りリクエストをスレッド経由で送り、unsupported_request_behavior="continue_unthreaded" を設定します。thread_unsupported_request エラーが出たとき、またはリプレイ直後に 2 回目の thread_not_found が出たときは、スレッドを捨ててフルのリクエストを送ります。それ以外のエラーは引き続きコードに届きます。スレッドを許可するクライアント属性 _supports_message_threads は Anthropic と AsyncAnthropic では true になっており、AWS と Foundry のクライアントはそれを継承します。Bedrock と Vertex のクライアントでは false で、client.beta.messages.thread() は例外を投げます。ZDR 対象外の機能には渡さないと約束したデータでツールランナーのエージェントを動かしているなら、SDK を更新するのと同じ変更で thread=False を入れてください。

Claude メッセージスレッドを今から使うべきか

レイテンシが問題になり、コンテキストが巨大な場面では有効にしましょう。大規模なコーディングループや、スクリーンショットが毎ターンアップロードされるコンピューター操作(Computer Use)がそうです。人間やレビュー、タイマーを待つエージェントは 5 分を超えて止まります。そうしたエージェントではリプレイが通常の経路になり、スレッドが効くのは作業が集中している間だけです。

導入初日にやっておくべきことがあります。thread を追加する前に、リクエストごとにコンテキストサイズ、最初のトークンまでの時間、cache_read_input_tokens の 3 つを記録してください。発表が測ったのは 1 つのコホートで、自分の利用がそこに含まれるとは限りません。キャッシュの読み込みが少ないなら、プレフィルの時間を食っている原因はキャッシュの側にあり、その時間はスレッドでは短縮できません。

01 / ディスカッション

コメント欄はありません。議論は X で行っています。

Max Nardit@mnardit

02 / ほかの記事

  1. ChatGPT と Codex の利用上限が 12 月から共通に:Codex がすでに使っている枠にチャットが加わる

    Codex はすでに ChatGPT の Work と利用枠を共有しています。12 月に加わるのはチャットで、メッセージ数ではなくトークンで数えられ、Instant チャットは対象外です。チャットのモデル別メッセージ上限が残るのか、共通の枠がどれだけの大きさなのかを OpenAI は明らかにしていません。

  2. Claude Code の worktree: claude --worktree が分離するものと、ポート、データベース、インストールのように分離しないもの

    Claude Code 2.1.316 で検証しました。2 つの worktree が同じポートで衝突し、Docker Compose はそれぞれに別の Postgres ボリュームを計画し、スクリプト実行はロックされたチェックアウトと不要なブランチを残し、デフォルトのベースは未プッシュのコミットを含みませんでした。

  3. Claude Ultra が Max 20x に代わる: 認証済みアカウントは 5 時間制限なし、Anthropic によれば週の上限は最初から Pro の 10x

    旧名の 20x が表していたのは 5 時間枠で、2 つあるメーターのうち緩いほうでした。Anthropic の説明では、週の上限は導入された日から Pro の 10x です。Ultra の料金表示は週の数字を前面に出し、5 時間の数字をなくしました。人によっては条件が良くなり、20x を週の量と読んでいた人にとっては、読み違いだったことになります。