跳至主要內容

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-12 beta 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。

  1. Create: 送出完整對話、system 與 tools,並加上 "thread": {"type": "create"}。
  2. Continue: 只送出新的訊息,加上 "thread": {"type": "continue", "previous_message_id": "<previous id>"},不要帶 system 與 tools。每次都以新回應的 id 作為下一輪的起點。
  3. 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(...) 即可。

請求之間哪些可以改

類別欄位規則
僅限 createsystem、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意義處理方式
404thread_not_foundAPI 無法延續此 thread。以新的 create 請求送出完整對話。
400thread_fingerprint_mismatch某個固定欄位不同;錯誤訊息會列出欄位。保持固定欄位不變,或開新的 thread。
400thread_already_continued每個回應 id 只能延續一次。從最新的 id 繼續;如果你的用戶端從未收到該回應,就 replay。
400thread_continue_in_flight從這個 id 發出的另一個 continue 請求仍在執行,通常是你自己先前的嘗試。等它完成後從它的 id 繼續,或 replay。
400thread_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_control breakpoint。最上層的那個算一個,create 請求中 system 與 tools 上的 breakpoint 在每個 continue 請求都會再算一次,已保存的較早訊息上的 breakpoint 則不計入。多一個就會回傳 thread_unsupported_request。
Message threadsPrompt 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_control breakpoint 不超過 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 月總整理。

資料來源