要点:Message Threads を使うと、Messages API が会話をサーバー側で短時間保持します。2 ターン目以降は新しいメッセージと直前の応答の id だけを送ればよく、リクエストが小さくなり、長い会話でも Claude が早く応答を始めます。減るのはレイテンシで、トークンではありません。
- Anthropic のリリースノートによると、11 月 2 日から Messages API でメッセージスレッドがベータ提供されています。リクエストにはベータヘッダー
message-threads-2026-08-12と、本文のthreadパラメータが必要です。スレッドは最後のリクエストから 5 分で失効し、最後の利用から 1 時間以内に削除されます。 - Anthropic の公式記事によると、Claude Code のほとんどのユーザーではすでに既定で有効になっており、50 万〜100 万トークンのリクエストで最初のトークンまでの時間の中央値が約 35% 短くなりました。Claude は毎ターン会話全体を読むため、トークン使用量は変わらず、課金とレート制限も変わりません。
- 11 月 3 日に aicodewith の Key で検証したところ、aicodewith 経由では現在
threadフィールドが無視されます。どのリクエストも 200 を返しますが、継続ターンには前の文脈がなく、モデルは前に言われた内容を答えられません。aicodewith 経由ではスレッドを使わず、これまでどおり履歴全体を送り、prompt caching を併用してください。Claude Code は aicodewith にスレッドのリクエストを送らないため、通常どおり動きます。
API Key を作成して、Claude Code・Codex・Cursor で Claude を使う →
Message Threads とは
Messages API は会話を記憶しません。スレッドがない場合、エージェントは毎ターン、それまでのすべてのメッセージとツール結果を送り直し、API もそれを毎回検証・トークン化し直します。会話が数十万トークンになると、それだけで最初のトークンが遅れます。
公式ドキュメントによると、仕組みは次のとおりです。最初のリクエストはこれまでどおり会話全体、system、tools を送り、"thread": {"type": "create"} を加えます。API は Claude の応答を含む会話を、その応答の id の下に保存します。以降のターンでは直前の応答より後のメッセージだけを送り、"thread": {"type": "continue", "previous_message_id": "..."} を加えます。API はモデルを呼ぶ前に会話全体を組み立て直します。返ってくるのは通常の message です。
| スレッドなし | スレッドあり | |
|---|---|---|
| 毎ターンのリクエスト本文 | 履歴全体 + system + tools | 1 ターン目は全体、以降は新しいメッセージ + 直前の応答 id のみ |
| 最初のトークンまでの時間 | 会話が長くなるほど遅くなる | 低く安定、会話が長いほど効果が大きい |
| トークン使用量 | 毎ターン会話全体を読む | 同じ、毎ターン会話全体を読む |
| 課金とレート制限 | 標準 | 変わらない |
| 会話を持つのは誰か | あなたのアプリ | サーバーが 5 分間、アプリ側も完全なコピーを保持する |
また @dotey の中国語での紹介によると、Anthropic の数値では長い会話のリクエストサイズ中央値が約 800 KB から 1.8 KB に下がりました。@ClaudeDevs の告知は 11 月 3 日早朝(北京時間)時点で約 20.9 万回表示、3,681 いいね、1,041 ブックマークで、X のトレンドにも入りました。
使い方:thread パラメータとベータヘッダー
スレッドのすべてのリクエストに anthropic-beta: message-threads-2026-08-12 が必要です。以下は Anthropic 公式 API 向けの書き方です(aicodewith については後述)。
curl
# Turn 1: full conversation + system (+ tools), create a thread
curl -sS https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: message-threads-2026-08-12" \
-H "content-type: application/json" \
-d '{
"model": "claude-opus-5-5",
"max_tokens": 1024,
"cache_control": {"type": "ephemeral"},
"system": "You are a support agent for Acme. Keep replies short.",
"messages": [{"role": "user", "content": "Hi! I have a question about an order."}],
"thread": {"type": "create"}
}'
# Turn 2: only the new message + the id of the turn 1 response
# (no system / tools here: the thread keeps them)
curl -sS https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: message-threads-2026-08-12" \
-H "content-type: application/json" \
-d '{
"model": "claude-opus-5-5",
"max_tokens": 1024,
"cache_control": {"type": "ephemeral"},
"messages": [{"role": "user", "content": "How long does standard shipping usually take?"}],
"thread": {"type": "continue", "previous_message_id": "'"$MSG_ID"'"}
}'
1 回目の応答の id を MSG_ID に保存し、2 ターン目はそこから継続します。常に最新の応答 id から継続し、各 id は 1 回しか継続できません。
Python
公式 SDK にはスレッドヘルパー client.beta.messages.thread(...) があります。ベータヘッダーを付け、continue リクエストから system と tools を外し、404 のときは会話全体を 1 回再送します。create に thread を自分で渡すこともできます。
import anthropic
client = anthropic.Anthropic() # official API, reads ANTHROPIC_API_KEY
# Option A: the SDK thread helper (adds the beta header, replays on 404 for you)
thread = client.beta.messages.thread(
model="claude-opus-5-5",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system="You are a support agent for Acme. Keep replies short.",
)
thread.send({"role": "user", "content": "Hi! I have a question about an order."})
second = thread.send({"role": "user", "content": "How long does standard shipping usually take?"})
print(second.content[-1].text)
# Option B: send the thread field yourself
first = client.beta.messages.create(
model="claude-opus-5-5", max_tokens=1024,
cache_control={"type": "ephemeral"},
system="You are a support agent for Acme. Keep replies short.",
messages=[{"role": "user", "content": "Hi! I have a question about an order."}],
thread={"type": "create"},
betas=["message-threads-2026-08-12"],
)
second = client.beta.messages.create(
model="claude-opus-5-5", max_tokens=1024,
cache_control={"type": "ephemeral"},
messages=[{"role": "user", "content": "How long does standard shipping usually take?"}],
thread={"type": "continue", "previous_message_id": first.id},
betas=["message-threads-2026-08-12"],
)
TypeScript
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic(); // official API, reads ANTHROPIC_API_KEY
const thread = client.beta.messages.thread({
model: "claude-opus-5-5",
max_tokens: 1024,
cache_control: { type: "ephemeral" },
system: "You are a support agent for Acme. Keep replies short.",
});
await thread.send({ role: "user", content: "Hi! I have a question about an order." });
const second = await thread.send({
role: "user",
content: "How long does standard shipping usually take?",
});
for (const block of second.content) {
if (block.type === "text") console.log(block.text);
}
各リクエストで送るもの
公式ドキュメントではフィールドを 3 種類に分けています。
| 種類 | フィールド | ルール |
|---|---|---|
| create のみ | system、tools | continue リクエストに含めると(null でも)400 |
| 固定 | model、tool_choice、thinking、mcp_servers、context_management、output_config、トップレベルの cache_control、anthropic-beta の値の組み合わせなど | 毎回 create と同じ値で送る。違うと 400 thread_fingerprint_mismatch |
| ターンごとに変更可 | max_tokens、stop_sequences、stream、metadata など | 毎ターン変えてよい |
システムプロンプト、ツール、モデルを変えたいときは、会話全体を新しい create リクエストで送り、新しいスレッドを始めます。
失効と再送
スレッドはベストエフォートです。最後のリクエストから 5 分で失効し、その後の continue リクエストは 404 を返し、error.details.error_code は thread_not_found になります。そのときは手元のコピーから会話全体を新しい create リクエストで送り、新しい id から継続します。つまり、会話の完全なコピーを必ず手元に残し、再送の処理を最初から組み込んでおく必要があります。公式 SDK のヘルパーは 1 回自動で再送します。
節約になるか:お金ではなくレイテンシが減る
公式ドキュメントによると、スレッドは課金もレート制限も変えません。リクエストは小さくなりますが、Claude は毎ターン会話全体を読むので、入力トークンは以前と同じです。
同じトークンの再処理を減らすには prompt caching が必要です。スレッドは自動でキャッシュしません。公式の例では毎回トップレベルの cache_control: {"type": "ephemeral"} を付けており、各ターンがそれまでの会話をキャッシュから読み、新しいターンを書き込みます。両者は補い合う関係で、スレッドはアップロードを、キャッシュは再処理を減らします。
Anthropic の記事によると、向いているのは長時間動くコーディングエージェント、毎ターンスクリーンショットを扱う computer use エージェント、文書や画像が多い会話です。短いチャットでは効果は小さめです。
Claude Code で何が変わるか
Anthropic の公式記事によると、Claude Code のほとんどのユーザーではすでにメッセージスレッドが既定で有効で、35% という数値はここから来ています。ユーザー側で設定を変える必要はありません。
ローカルのプロキシで、Claude Code 2.1.316 が独自の ANTHROPIC_BASE_URL で aicodewith に接続したときのリクエストを記録しました。2 つのファイルを読むタスクで 3 回のリクエストがあり、どれにも thread フィールドはなく、ベータヘッダーにも message-threads-2026-08-12 はありませんでした。メッセージ数は 2、4、6 と増え、毎回履歴全体(約 46 KB)を送り、タスクは正常に完了しました。サードパーティのベース URL では、Claude Code はこれまでどおりの方式で動き、スレッドのせいで壊れることはありません。
接続方法:
export ANTHROPIC_BASE_URL="https://api.aicodewith.ai"
export ANTHROPIC_AUTH_TOKEN="YOUR_API_KEY"
claude --model claude-opus-5-5
設定の永続化や Windows での設定は「Claude Code をサードパーティ API に接続する方法」を参照してください。長いセッションでもう少し速くしたい場合は effort を下げる方法もあります。「Claude Opus 5.5 の effort の選び方」をご覧ください。
Message Threads は Claude の Messages API の機能で、Codex は OpenAI の API を使うため関係ありません。Codex SDK にも「スレッド」がありますが、これはクライアント側のセッションを再開するもので、ここで説明したサーバー側の一時保存とは別物です。「Codex SDK 入門:TypeScript 呼び出し、ストリーミングイベント、スレッド再開」を参照してください。
aicodewith 経由で使えるか:検証結果
2026 年 11 月 3 日未明(北京時間)、aicodewith の Key、モデル claude-opus-5-5、ヘッダー message-threads-2026-08-12 で、aicodewith の Anthropic 互換エンドポイント https://api.aicodewith.ai/v1/messages を呼び、公式の例に沿って 1 つずつ確認しました。
| テスト | 公式 API での想定 | aicodewith 経由の実際 |
|---|---|---|
| create:会話全体 + thread: create | 200、スレッド作成 | 200、通常の応答 |
| continue:新しいメッセージ + 直前の id | 200、モデルが前の文脈を参照 | 200、ただし input_tokens は 27 で前の文脈なし |
| 同じ id を 2 回目に継続 | 400 thread_already_continued | 200 |
| 存在しない previous_message_id | 404 thread_not_found | 200 |
| continue で system を送る | 400 | 200 |
| Python SDK 2.4.0 のスレッドヘルパー | 2 ターン目が 1 ターン目を覚えている | 2 ターン目は「注文番号はない」と回答 |
継続ターンの実際の応答(抜粋):
Turn 1 (create): "Hi! I have a question about an order."
-> 200, "Happy to help. What's your order number, and what's the question about it?"
Turn 2 (continue, previous_message_id = turn 1 id):
"How long does standard shipping usually take? Also, what did I say my question was about?"
-> 200, input_tokens: 27
-> "...As for your question, you didn't say what it was about beyond asking about standard shipping..."
結論:aicodewith は現時点でメッセージスレッドに対応しておらず、thread フィールドをないものとして扱います。各リクエストは独立した 1 回きりのリクエストとして処理されます。注意すべきはエラーにならない点です。SDK のヘルパーは 404 を受け取らないので再送せず、会話は気づかないうちに文脈を失います。aicodewith 経由ではリクエストに thread を入れず、client.beta.messages.thread(...) も使わないでください。
代替案:履歴全体 + prompt caching
これまでどおり毎ターン履歴全体を送り、トップレベルの cache_control を付けて自動キャッシュを有効にします。同じ aicodewith の Key で 3 ターン実行しました(システムプロンプト約 7,500 トークン)。
| ターン | 入力(キャッシュ外) | キャッシュ書き込み | キャッシュ読み込み | 所要時間 | 応答 |
|---|---|---|---|---|---|
| 1 | 24 | 7,568 | 0 | 4.0 秒 | 正常 |
| 2 | 8 | 1,541 | 6,163 | 4.4 秒 | 正常 |
| 3 | 8 | 1,560 | 6,240 | 3.5 秒 | 「Your order number is A-1042.」 |
2・3 ターン目はキャッシュにヒットし、3 ターン目は 1 ターン目の注文番号を正しく答えました。Python の書き方:
import anthropic
client = anthropic.Anthropic(
base_url="https://api.aicodewith.ai",
api_key="YOUR_API_KEY",
)
SYSTEM = "You are a support agent for Acme. Keep replies short.\n\n" + open("policy.md").read()
history = [{"role": "user", "content": "Hi! My order number is A-1042 and it hasn't shipped yet."}]
def turn(next_user_message=None):
r = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
cache_control={"type": "ephemeral"}, # automatic caching: moves forward each turn
system=SYSTEM,
messages=history, # full history, no thread field
)
history.append({"role": "assistant", "content": [b.model_dump(exclude_none=True) for b in r.content]})
if next_user_message:
history.append({"role": "user", "content": next_user_message})
u = r.usage
print(u.input_tokens, u.cache_creation_input_tokens, u.cache_read_input_tokens)
return r
turn("When will it ship?")
turn("What was my order number again?")
turn()
TypeScript も同じ考え方で、履歴全体を messages に入れます。
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://api.aicodewith.ai",
apiKey: "YOUR_API_KEY",
});
const history: Anthropic.MessageParam[] = [
{ role: "user", content: "Hi! My order number is A-1042 and it hasn't shipped yet." },
];
const r = await client.messages.create({
model: "claude-opus-5-5",
max_tokens: 1024,
cache_control: { type: "ephemeral" },
system: "You are a support agent for Acme. Keep replies short.",
messages: history, // full history every turn, no thread field
});
history.push({ role: "assistant", content: r.content });
console.log(r.usage);
エンドポイントが本当にスレッドに対応しているか確かめる
存在しえない previous_message_id で continue を送ります。公式 API なら 404 thread_not_found が返ります。200 と通常の応答が返れば、そのエンドポイントは thread を無視しています。
# continue from an id that cannot exist
curl -sS https://api.aicodewith.ai/v1/messages \
-H "x-api-key: YOUR_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: message-threads-2026-08-12" \
-H "content-type: application/json" \
-d '{"model":"claude-opus-5-5","max_tokens":200,"cache_control":{"type":"ephemeral"},
"messages":[{"role":"user","content":"Hi"}],
"thread":{"type":"continue","previous_message_id":"msg_doesnotexist123"}}'
# official API: 404, error.details.error_code = "thread_not_found"
# a gateway that ignores thread: 200 and a normal reply
aicodewith がスレッドに対応したときも、アプリのコードを触らずにこのコマンドで確認できます。
よくあるエラー
公式ドキュメントによると、以下のエラーはモデルの実行前に返され、トークンを消費せず、スレッドと失効時刻も変わりません。
404 thread_not_found
スレッドが失効した(5 分間リクエストがない)、直前のターンが保存されなかった、直前の応答をフォールバックモデルが書いた、直前の応答がまだ生成中、別の API Key・組織・ワークスペースからのリクエスト、などが原因です。対処:会話全体を新しい create リクエストで送ります。存在しないモデルへのリクエストも 404 になるので、再送の前に error.details.error_code を確認してください。
{
"type": "error",
"error": {
"type": "not_found_error",
"message": "...",
"details": { "error_code": "thread_not_found" }
},
"request_id": "req_..."
}
400 thread_fingerprint_mismatch
固定フィールドが create のときと違います。たとえば model や thinking を変えた、トップレベルの cache_control を変えた、ベータヘッダーを増やした・減らした、などです。エラーメッセージに違うフィールドが示されます。変えるなら新しいスレッドを始めます。
400 thread_already_continued / thread_continue_in_flight
同じ応答 id は 1 回しか継続できない、または前の continue リクエストがまだ実行中です。常に最新の応答 id から継続してください。ストリーミングでは message_stop イベントを受け取ってから継続します。早すぎると 404 になることがあります。
400 thread_unsupported_request
スレッドが対応していない機能を使っています。cache_control のブレークポイントが 4 つを超える(トップレベルも 1 つと数える)、オンデマンドの compaction、ほとんどの context editing、HIPAA や Inference hooks が有効な組織などです。Message Batches とトークンカウントも thread に対応していません。その機能を外すか、thread なしで会話全体を送ります。
continue リクエストに system や tools を入れた
error_code のない 400 が返ります。continue では新しいメッセージだけを送り、system と tools はスレッドが保持します。
aicodewith 経由で継続ターンの文脈が消えた
aicodewith が現在 thread を無視しているためで、エラーにはなりません。thread を外し、前のセクションのとおり履歴全体 + cache_control に戻してください。
データ保持と制限
- 公式ドキュメントによると、スレッドは暗号化されてメモリに保持され、永続ストレージには書かれず、最後の利用から 1 時間以内に削除されます。ゼロデータ保持(ZDR)と HIPAA の対象外です。
- スレッドを一覧・取得・削除する API はありません。
- 提供先は Claude API、Claude Platform on AWS、Claude Models on Google Cloud(Anthropic managed)、Claude in Microsoft Foundry で、すべてのモデルでベータです。
- なお報道によると、11 月 3 日から Claude のテキスト透かしの対象モデルが広がります。スレッドとは関係なく、リクエストの変更も不要です。「Claude の透かしは 11 月 3 日から」を参照してください。
まとめ
Message Threads は、長い会話で毎ターン履歴全体を送り直すことによる遅延を解消します。1 ターン目でスレッドを作り、以降は新しいメッセージと直前の応答 id だけを送れば、最初のトークンが早く返ります。トークン使用量と課金は変わらず、5 分の失効後に再送できるよう手元に会話の完全なコピーを残しておく必要があります。公式 API に直接つなぐ長時間エージェントなら有効にする価値があります。aicodewith 経由では現在 thread が無視されるので、履歴全体を cache_control 付きで送ってください。Claude Code を aicodewith につなぐ場合は何も変える必要はありません。



