Claude Platform Docs
Messages保留思考

思考區塊的前綴檢查

前綴檢查比對的內容、哪些模型會執行它、請求未通過時會發生什麼,以及如何處理 400 錯誤與沒有錯誤的情況。

每個將思考區塊傳回給具備「preserved thinking」(保留思考)的模型的請求,都會經過「prefix check」(前綴檢查)。如果在 Claude 產生某個區塊之後,system、tools 或較早的訊息有所變更,前綴檢查就會失敗。如果位於其他思考區塊之間的某個思考區塊被省略或移動,前綴檢查也會失敗。

未通過前綴檢查可能會也可能不會導致 400 錯誤,視模型而定,因此請處理兩種情況。

前綴檢查會影響誰

如果下列任一項成立,您就不需要做任何變更:

  • 由 Claude Code、claude.ai 或 Claude Managed Agents 管理您的對話歷史。
  • 由 Claude Agent SDK 管理歷史,且您提供給 SDK 的系統提示保持不變。
  • 您的程式碼遵循僅附加整合的三項習慣,且途中沒有任何東西改寫其請求。
  • 您沒有呼叫任何具備保留思考的模型。

如果您的請求會經過程式庫、代理伺服器或閘道,請比對它送出的內容與您送出的內容。如果您自己運行這類元件,請參閱程式庫、代理伺服器和閘道,了解應該原樣傳遞哪些內容。

哪些內容必須保持不變,以及原因

請讓您的整合成為「append-only」(僅附加)。三項習慣即可做到:

  1. 將每個助理輪次完全按照 API 傳回的樣子送回,包括文字為空的思考區塊。
  2. 每個對話只建構一次 system 和 tools,並且每次都送出同一份。
  3. 將每項更新放在結尾的新訊息中,並讓它留在那裡。

每個思考區塊的推理,都是針對它之前的確切內容:system、tools 以及每一則較早的訊息。這些內容就是該區塊的前綴,也是前綴檢查所比對的對象。

前綴檢查與提示快取類似,不同之處在於,一項變更會使其後的思考失效,而不僅僅是未命中快取。

以一個在系統提示中放入今天日期的應用程式為例。到了午夜,日期改變,對話中既有思考的前綴也隨之改變。那些思考會因此失效,下一個請求就可能失敗。僅附加的應用程式會讓系統提示維持原樣,並在結尾的訊息中說明新的日期。

在結尾​新增​更新
systemtools
變更第 2 ⁠輪的​訊息
systemtools
變更 system 或 tools
systemtools
您的​訊息
思考,有效
已變更或已​新增
思考,失效

一項變更只會使已經位於其後的思考失效。位於它之前的思考,以及 Claude 之後產生的思考,都會保持有效。

如果您的程式碼會變更系統提示、工具或歷史

如果您的程式碼…該怎麼做
以日期、模式或指示檔案重新建構系統提示停止變更 system。將您自己的指示以系統訊息附加(即 messages 中的一個 role: "system" 項目),並在最新的輪次中說明新的值。對於其他人可以編輯的文字,請改為參閱其他人可以編輯的文字。
新增、移除或改寫某個工具,或在 MCP 伺服器連線時增加工具停止變更 tools,並在系統訊息中新增或移除工具。
修剪、收合或摘要較舊的輪次,並讓最新的輪次保持不變讓 API 撰寫摘要,或移除保留的輪次的思考。

其他原因,例如略過文字為空的思考區塊,或重新建構已儲存的對話,各有其修正方式:請參閱變更工具或指示而不使前綴檢查失敗。若要找出您的原因,請讓代理檢查您的程式碼。

前綴檢查失敗時各模型的行為

在 Claude API 和部分雲端平台上,當 prefix_mismatch_behavior 未設定時,未通過前綴檢查的結果取決於模型:

具備保留思考的模型結果
Claude Fable 5.2400 錯誤
Claude Mythos 5.2400 錯誤
Claude Mythos 5.1400 錯誤
Claude Fable 5.1可能出現 400 錯誤
Claude Opus 5.5可能出現 400 錯誤
Claude Sonnet 5.5可能出現 400 錯誤
Claude Haiku 5.5可能出現 400 錯誤

表格中標示「可能出現 400 錯誤」的地方,有兩種情況:未通過前綴檢查的請求可能會得到 400 錯誤,也可能不會得到錯誤。沒有傳回錯誤時,未通過前綴檢查的區塊會傳到模型。Claude 會像讀取任何其他輸入一樣讀取它們,您需要為它們付費,而 Claude 會依據針對已經變更之內容的推理來工作。

在這些模型上,您可以檢查請求會得到哪種情況,但仍請處理兩種情況。

將 prefix_mismatch_behavior 保持未設定的 Message Batches 項目不會得到錯誤,且 API 可能會捨棄未通過前綴檢查的區塊。

處理兩種情況

若要讓每個請求都得到單一結果,請讓您的整合成為僅附加,或設定 prefix_mismatch_behavior。否則,您的程式碼必須處理兩種行為。

發生 400 錯誤後,請在該對話之後的請求中送出 "drop_block" 以進行復原。這有其代價:請參閱捨棄思考的代價。請勿為了隱藏錯誤而在您所有的對話中送出它。

技術細節

前綴檢查如何運作

具備保留思考的模型會在每個思考區塊的 signature 中記錄其前綴的指紋。API 參考文件將前綴檢查稱為對話檢查(conversation check),而 400 錯誤會指出未通過前綴檢查的區塊 is bound to a different conversation。

哪些模型會執行前綴檢查

前綴檢查會在 Claude API 和部分雲端平台上執行。它會在送往具備保留思考的模型之一的請求上,檢查由這類模型所產生的思考區塊。在 Claude API 上,其他模型(例如 Claude Opus 5)不會執行它,它也不涵蓋這些模型的區塊。

什麼算是變更

  • 每個區塊都會與其自身的記錄比對。 API 會將此請求中某個區塊之前的內容,與 Claude 產生該區塊時其簽章所記錄的內容進行比對。您的上一個請求與此無關。前綴檢查只看內容,不看工作階段、ID 或使用者。新請求或分支中的相同內容都會通過前綴檢查。
  • 前綴檢查比對的是您送出的內容,而不是 Claude 讀取的內容。 在 token 閾值時進行壓縮和上下文編輯只會改變 Claude 讀取的內容,因此永遠不算是變更。在閾值壓縮區塊之後,API 只會比對從該區塊起的訊息,以及 system 和 tools。隨選壓縮有其自身的條件:請參閱保留的思考維持有效的條件。對於以 URL 傳送的檔案,以及在 Claude API 上的 MCP 工具清單,API 會改為比對它所擷取的內容。
  • 您送出的思考必須是連續不中斷的序列。 思考區塊不會作為內容進行比對。但您送出的每個思考區塊(第一個除外),其前一個思考區塊都必須與 Claude 產生它時相同。因此,您可以省略最舊的、最新的或全部的思考區塊,但不能省略中間的某一個。

變更可以小到只是工具描述中的一個字。變更、插入、移動或刪除較早的訊息都算是變更,無論其角色為何。變更思考區塊所在訊息中位於其前面的文字也算。

什麼不算是變更

這不算是變更原因
model、effort、max_tokens、tool_choice、metadata、thinking.display 及其他參數只會比對 system、tools 和訊息
JSON 格式或鍵的順序API 比對的是解析後的 JSON,而不是其文字
cache_control 標記它們指出要在哪裡快取,並非 Claude 讀取的內容
具有 defer_loading: true 且尚未被任何內容參照的工具在有內容參照它之前,它不在 Claude 的上下文中

設定 prefix_mismatch_behavior

beta 標頭 thinking-binding-controls-2026-08-01 會新增設定 thinking.block_binding.prefix_mismatch_behavior,以及回應中的 input_transformations 陣列。

值如果某個區塊未通過前綴檢查
"error"API 會以 400 錯誤拒絕該請求,錯誤中會指出第一個無效的區塊
"drop_block"API 會捨棄無效的區塊,請求會成功。您不需要為這些區塊付費,但捨棄它們可能會花費更多
未設定,或 null視模型而定

只要變更仍然存在,未通過前綴檢查的區塊在之後每個送出它們的請求中都會保持無效。此設定只作用於攜帶它的那一個請求。在思考關閉的情況下("disabled" 或 "between_tools"),送出此設定在每個模型上都會是 400 錯誤。

以下請求將 prefix_mismatch_behavior 設為 "drop_block"。在第一個輪次中沒有需要送回的思考,因此 input_transformations 會傳回空值:

client = anthropic.Anthropic()

response = client.beta.messages.create(
    model="claude-opus-5-5",
    max_tokens=16000,
    thinking={
        "type": "adaptive",
        "block_binding": {"prefix_mismatch_behavior": "drop_block"},
    },
    messages=[
        {
            "role": "user",
            "content": "What is the greatest common divisor of 1071 and 462?",
        }
    ],
    betas=["thinking-binding-controls-2026-08-01"],
)

for block in response.content:
    if block.type == "text":
        print(block.text)

print(f"Input transformations: {len(response.input_transformations or [])}")

監看正式環境流量

當 prefix_mismatch_behavior 未設定時,在部分模型上,未通過前綴檢查的請求可能不會得到錯誤。未通過前綴檢查的思考區塊接著會傳到模型。若要在正式環境流量中找出這些區塊,請送出 thinking-binding-controls-2026-08-01 beta 標頭、將此設定保持未設定,並記錄每個回應的 input_transformations 陣列。此標頭會新增該陣列,並不會改變模型接收到的內容。

每個這類區塊都會在該陣列中擁有自己的 thinking_mismatch_allowed 項目。一個項目看起來像這樣:

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

若要找出變更,請參閱找出您的程式碼變更了什麼。

檢查您會得到哪種情況

在部分模型上,未通過前綴檢查的請求可能會得到 400 錯誤,也可能不會得到錯誤。以下測試可顯示請求會得到哪一種:

  1. 取一個包含來自這些模型之一的思考區塊的對話。變更或新增系統提示(system)。該區塊接著會未通過前綴檢查,因為系統提示在 Claude 產生該區塊之後有所變更。
  2. 將其連同 thinking-binding-controls-2026-08-01 beta 標頭送往同一個模型,並將 prefix_mismatch_behavior 保持未設定。

回應會是下列其中之一:

  • 指出 bound to a different conversation 的 400 錯誤: 該請求得到了 400 錯誤。
  • input_transformations 陣列中含有 thinking_mismatch_allowed 項目的 200 回應: 該請求沒有得到錯誤。每個項目都指出一個未通過前綴檢查且傳到 Claude 的思考區塊。
  • input_transformations 陣列為空的 200 回應: 沒有區塊未通過前綴檢查,因此此測試無法顯示任何結果。請確認該對話包含來自該模型的思考區塊。

此結果只描述那一個請求,並不保證之後的請求會如何,因此請撰寫您的程式碼以處理兩種情況。

後續步驟

針對您的程式碼對對話所做的每項變更,應改為送出什麼。

復原未通過前綴檢查的對話、找出您的程式碼變更了什麼,並測試問題是否已消除。

保留思考是什麼、思考區塊與什麼綁定,以及切換模型或帳戶。

這個頁面有幫助嗎?