Claude API Message Threads(Beta):加速 agent 迴圈
Claude Messages API 推出 message threads(beta):對話暫存在伺服器端,之後每一輪只送新訊息,降低首個 token 延遲。整理用法、5 分鐘到期規則、錯誤處理,以及和 prompt caching 的搭配與取捨。
Message threads(訊息串)是 Claude Messages API 在 2026 年 11 月 2 日公布的 beta 功能。Thread 會把對話短暫保留在伺服器端,所以從第二個請求開始,每一輪只需要送出新的訊息,以及上一個回應的 id。依官方文件的說法,請求會變小,而且即使對話越來越長,首個 token 延遲(time to first token,TTFT)也能維持得更低、更穩定。
Beta 功能: 同一個 thread 的每個請求都必須帶上
message-threads-2026-08-12beta header(SDK 的 thread helper 會自動加上)。Thread 不符合 ZDR(零資料保留)資格。
為什麼每輪重送整段對話會變慢
在 agent 迴圈裡,每個工具結果都要透過一個帶著完整歷史的請求送回 Claude。文件指出,沒有 thread 時,每一輪都要重新上傳整段對話,API 也要再次驗證並 tokenize 全部內容;有了 thread,大部分工作只需處理新的那一輪。
Anthropic 表示,message threads 已對大多數 Claude Code 使用者預設啟用,在 50 萬到 100 萬 token 的請求上,TTFT 中位數下降約 35%。Anthropic 也指出,agent 帶著的上下文越多,message threads 能縮短的首個 token 延遲就越多。官方舉的例子包括長時間執行的 coding agent、computer use agent,以及大量處理文件與圖片的工作流程。
伺服器保存什麼、不保存什麼
Thread 會保存 API 送給模型的對話、create 請求中的 system 與 tools,以及用來檢查後續請求的固定欄位指紋(fingerprint)。檔案以參照方式保存,因此使用 thread 期間請讓這些檔案保持可用。MCP 伺服器 URL、MCP 授權 token 與 container 的 id 都不會被保存;凡是用到它們的請求,都要附上 mcp_servers 與 container。
沒有任何 API 能列出、讀取或刪除 thread,也沒有任何回應會告訴你 API 是否已保存該輪。你的應用程式仍是對話的真實來源(source of truth),所以請自行保留完整副本,並從一開始就把 replay(重送完整對話)的路徑做好。(Claude Managed Agents 的 session threads 是另一個功能。)
如何建立與延續 thread
在 Messages API 請求加上一個參數 thread 即可;回應仍是一般的 message。
- Create: 送出完整對話、
system與tools,並加上"thread": {"type": "create"}。 - Continue: 只送出新的訊息,加上
"thread": {"type": "continue", "previous_message_id": "<previous id>"},不要帶system與tools。每次都以新回應的id作為下一輪的起點。 - Replay: 如果 continue 請求回傳 404 錯誤,就用新的 create 請求送出完整對話,再從該回應的
id繼續。
使用 SDK 的 thread helper
Helper 接受與 Messages 請求相同的欄位,會自動加上 beta header,並在記憶體中保留完整對話。以下是 Python 與 TypeScript 範例(官方文件提供七種語言):
client = anthropic.Anthropic()
# Create the helper. This call sends no request.
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.",
)
# Turn 1: the helper creates a thread and sends the full conversation
thread.send({"role": "user", "content": "Hi! I have a question about an order."})
# Turn 2: the helper continues the thread and sends only the new message
second = thread.send(
{"role": "user", "content": "How long does standard shipping usually take?"}
)
for block in second.content:
if block.type == "text":
print(block.text)
const client = new Anthropic();
// Create the helper. This call sends no request.
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."
});
// Turn 1: the helper creates a thread and sends the full conversation
await thread.send({ role: "user", content: "Hi! I have a question about an order." });
// Turn 2: the helper continues the thread and sends only the new message
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);
}
}
最上層的 cache_control 是選用的。SDK 的 beta tool runner(也就是我們 MCP helpers 介紹中的 tool_runner() 迴圈)預設也會使用 thread;若不想使用,建立時在 Python 傳入 thread=False,在 TypeScript 傳入 thread: false。
自行送出 thread 欄位
使用 cURL、CLI 或 SDK 的 create 方法時,每個請求都要帶上 beta header:
# Turn 1: send the full conversation and create a thread
curl -sS --fail-with-body https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2026-10-21" \
-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: send only the new message. Set message_id to the id of the turn 1 response.
# Leave out system and tools: the thread keeps them.
curl -sS --fail-with-body https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2026-10-21" \
-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": "'"$message_id"'"}
}'
第 2 輪仍會重複送出固定欄位。在 Python 中,把同樣的 thread 值與 betas=["message-threads-2026-08-12"] 傳給 client.beta.messages.create(...) 即可。
請求之間哪些可以改
| 類別 | 欄位 | 規則 |
|---|---|---|
| 僅限 create | system、tools | 只能放在 create 請求。在 continue 請求中送出任一個(即使是 null)都會回傳 400 錯誤。 |
| 固定 | model、tool_choice、thinking、mcp_servers(各伺服器的授權 token 除外)、context_management、output_config、container 中的 skills、最上層的 cache_control,以及 anthropic-beta 值的集合 | 每個請求都要帶相同的值。值不同會回傳 400 錯誤 thread_fingerprint_mismatch,並列出不同的欄位。 |
| 可自由變更 | max_tokens、stop_sequences、stream、metadata、service_tier,以及文件未列出的欄位 | 每一輪都可以改。 |
要變更僅限 create 或固定的欄位,就得開一個新的 thread。若使用 server-side fallback,fallbacks 必須在同一個 thread 的每個請求都送,或全都不送。在 Claude Fable 5.1、Mythos 5.1、Opus 5.5、Sonnet 5.5 與 Haiku 5.5 上,變更 system 或 tools 會讓對話中既有的 thinking 與 redacted_thinking 區塊失效,create 請求可能回傳 400 錯誤;把這些區塊拿掉就能避免,模型會在沒有那段先前推理的情況下回答。
關於訊息:
- 只送新的訊息。 API 不會拿它們和已保存的內容比對,重送的訊息可能出現兩次,或導致錯誤。
- 通常以
user訊息開頭: 你的下一輪,或回答tool_use的tool_result區塊。 - 用
"messages": []恢復pause_turn: 從該回應的id送出 continue 請求。暫停期間送出新的user訊息會被拒絕。 - 只能附加,每個
id只能延續一次。 從最新的回應id繼續;要編輯或分支,請開新的 thread。
要做 compaction,請在自己的程式中寫好摘要,透過新的 create 請求連同 system 與 tools 送出;thread 不支援 compaction on demand。我們的上下文壓縮教學說明 Claude Code 如何處理長 session。
存活時間、到期與復原
Thread 採 best-effort(盡力而為)方式保存:最後一個請求後 5 分鐘到期(API 每保存一個回應,就重新計算這 5 分鐘),並在最後一次使用後最多 1 小時內被刪除。
當 API 無法延續 thread 時,continue 請求會回傳 404,error.details.error_code 為 thread_not_found,但不會說明原因。可能的原因包括:thread 已到期;API 已回應但未保存該輪(例如回應結尾是一個被 max_tokens 截斷的 tool call);上一個回應由 fallback 模型產生;請求來自不同的組織、workspace、使用者或服務帳戶;以及新訊息加入了已保存對話無法接受的內容,例如在原本沒有圖片的對話中加入第一張圖片。
復原方式:從你自己的副本,以新的 create 請求送出完整對話(含 system 與 tools,並移除較早訊息上的 cache_control breakpoint),再從新的 id 繼續。replay 前先檢查 error_code:請求不存在的模型同樣會回傳 404。如果 replay 後立刻又出現 404,代表 API 可能無法保存這段對話;這時請不帶 thread 送出。
- 串流: 雖然
id在message_start就會出現,仍要等收到message_stop才能延續。continue 請求的串流若中斷,就再送一次相同的請求;若收到thread_already_continued或thread_continue_in_flight,就 replay。文件強調:replay 永遠是安全的。 - 拒絕回應: 回應出現
stop_reason: "refusal"後不要再延續,請開新的 thread,並拿掉或改寫導致拒絕的那一輪。 - Fallback: API 不會保存由 fallback 模型寫出的那一輪。如果
usage.iterations中有fallback_message項目,就以新的 create 請求送出完整對話(包含該回應)。
SDK 的 helper 遇到 thread_not_found、thread_already_continued 或 thread_continue_in_flight 時會自動 replay 一次;你不帶訊息呼叫 send() 時,它會恢復 pause_turn;遇到拒絕回應或 fallback 模型的回應後,它會重新開始一個 thread。它不會自行重試中斷的串流,而 thread_fingerprint_mismatch 與 thread_unsupported_request 錯誤會交給你的程式處理。
錯誤
下列錯誤都在模型執行前回傳,不消耗 token,thread 本身及其到期時間也不會改變。
| 狀態碼 | error_code | 意義 | 處理方式 |
|---|---|---|---|
| 404 | thread_not_found | API 無法延續此 thread。 | 以新的 create 請求送出完整對話。 |
| 400 | thread_fingerprint_mismatch | 某個固定欄位不同;錯誤訊息會列出欄位。 | 保持固定欄位不變,或開新的 thread。 |
| 400 | thread_already_continued | 每個回應 id 只能延續一次。 | 從最新的 id 繼續;如果你的用戶端從未收到該回應,就 replay。 |
| 400 | thread_continue_in_flight | 從這個 id 發出的另一個 continue 請求仍在執行,通常是你自己先前的嘗試。 | 等它完成後從它的 id 繼續,或 replay。 |
| 400 | thread_unsupported_request | 請求用到 thread 不支援的功能或組織設定;若有提供,error.details.unsupported 會指出是哪一項。 | 移除該功能,或不帶 thread 送出完整對話。 |
有些 400 錯誤不帶 error_code,例如缺少 previous_message_id 的 continue 請求,或帶了 system 或 tools 的 continue 請求。
支援的模型與平台
文件列出的每個模型都以 beta 形式支援 message threads:claude-fable-5-1、claude-mythos-5-1、claude-fable-5、claude-mythos-5、claude-mythos-preview、claude-opus-5-5、claude-opus-5、claude-sonnet-5-5、claude-sonnet-5、claude-haiku-5-5、claude-haiku-4-5-20251001、claude-opus-4-8、claude-opus-4-7、claude-opus-4-6、claude-sonnet-4-6、claude-opus-4-5-20251101 與 claude-sonnet-4-5-20250929。
支援的平台(皆為 beta):Claude API、Claude Platform on AWS、Claude Models on Google Cloud(Anthropic managed)與 Microsoft Foundry。在 Claude Platform on AWS 上,同一個 thread 的每個請求都要以建立該 thread 的 IAM role 或 IAM user 憑證簽署。
資料處理、定價與速率限制
Message threads 不符合 ZDR 資格,但使用它不會影響你使用其他符合 ZDR 資格的功能。API 會把 thread 保存在記憶體中、以伺服器端管理的金鑰加密、絕不寫入持久性儲存,並在最後一次使用後最多 1 小時內刪除。Thread 也不符合 HIPAA 資格。
文件寫得很明確:thread 不會改變定價或速率限制。Anthropic 的公告也說明了原因:雖然每個請求變小了,Claude 每一輪仍會讀取完整對話,所以 token 用量不變。
Message threads 與 prompt caching 的差別
Thread 不改變定價,所以 prompt caching(提示快取)仍是你降低成本的手段;文件也明說,thread 不會替你快取 prompt。在 thread 上:
- 每個請求都送出最上層的
cache_control(它是固定欄位);之後每一輪都會從快取讀取先前的對話,並把新的一輪寫入快取。 - 帶有
thread的請求最多只能有 4 個cache_controlbreakpoint。最上層的那個算一個,create 請求中system與tools上的 breakpoint 在每個 continue 請求都會再算一次,已保存的較早訊息上的 breakpoint 則不計入。多一個就會回傳thread_unsupported_request。
| Message threads | Prompt caching | |
|---|---|---|
| 減少什麼 | 上傳量與每輪的驗證、tokenize 工作,讓首個 token 延遲更低 | 處理時間與成本,方式是從已快取的前綴接續 |
| 定價 | 不變 | 快取讀取為基本輸入價格的 0.1 倍或更低(依模型而定);寫入為 1.25 倍(5 分鐘)或 2 倍(1 小時) |
| 存活時間 | 最後一個請求後 5 分鐘到期 | 預設 5 分鐘,每次使用時刷新;另有 1 小時選項,需額外付費 |
| ZDR | 不符合 | 符合(Covered Models 除外) |
在長時間、持續進行的 agent 迴圈中,請兩者並用;官方 thread 文件的範例也都這樣做。若是 Message Batches、必須符合 ZDR 的流量,或每輪間隔超過 5 分鐘的情境,就只用 prompt caching;間隔超過 5 分鐘時 thread 已經到期,但 1 小時快取仍可能命中。
什麼時候不該用 message threads
以下情況請不要加 thread:
- 每輪間隔通常超過 5 分鐘,例如每一步都要等人審閱:每次 continue 都會變成一次 404 加上一次 replay。
- 你使用 Message Batches 或 token counting,兩者都不接受
thread。 - 你依賴 compaction 或 context editing(
keep: "all"的clear_thinking_20251015除外)。 - 你的組織要求這類流量符合 ZDR,或啟用了 HIPAA readiness 或 Inference hooks。
- 你經常改寫歷史,或切換
system、tools、model。 每次變更都等於開一個新的 thread。 - 請求是一次性的。 文件指出,thread 在長時間的 agent 迴圈中幫助最大。
Agent 開發者的決策檢查清單
如果 session 持續進行、上下文會越長越大,你使用的是上述四個平台之一,而且以上情況都不適用,就可以採用 thread。上線前請確認:
- 你的應用程式保留完整對話,並且能 replay。
- 僅限 create 與固定的欄位,在同一個 thread 內保持不變。
- 只從最新的回應
id延續;使用串流時,等到message_stop之後才延續。 - 程式依
error.details.error_code分支,而不只看 HTTP 狀態碼。 - 拒絕回應與 fallback 模型的回應都會改開新的 thread。
- 每個請求的
cache_controlbreakpoint 不超過 4 個(含最上層那個)。 - 每個 thread 只使用一組 API key 與 workspace(在 Claude Platform on AWS 上,也只用同一個 IAM role 或 user)。
常見問題
Thread 會降低我的 token 費用嗎?
不會。定價、速率限制與 token 用量都不變;要降低成本請用 prompt caching。
可以從較早的某一輪分支出去嗎?
在同一個 thread 內不行。請開新的 thread,例如使用 helper 的 thread.params,並把 messages 截到想要的位置。
Claude Code 有用 message threads 嗎?
Anthropic 表示,message threads 已對大多數 Claude Code 使用者預設啟用。Claude Code 本月的其他變更,請見我們的 2026 年 11 月總整理。
資料來源
- Message threads,Claude Platform 官方文件
- Release notes(2026 年 11 月 2 日),Claude Platform 官方文件
- Make long-running agents faster with message threads,Anthropic,2026 年 11 月 2 日
- Prompt caching,Claude Platform 官方文件