保留思考
現在修改對話會導致錯誤或區塊被捨棄;如何檢查您的整合是否會這樣做,以及如何遷移。
在 Claude Fable 5.1 上,變更對話中先前的輪次(system 提示、tools 或任何較早的訊息)會影響 API 回應。預設情況下,這會使 API 以錯誤拒絕該請求,除非您選擇改為將受影響的「thinking blocks」(思考區塊)從模型所見的內容中捨棄(prefix_mismatch_behavior: "drop_block")。對於在 2026 年 8 月 31 日 00:00 UTC 當日或之後建立的新帳戶,此檢查預設為強制執行。更多細節請參閱 運作方式 與 受影響對象。
當您將區塊送回時,API 會使用其 signature 來檢查先前的對話是否未經變更,以及目前的模型是否能讀取該區塊。此檢查的存在,是為了讓在某一組指令下產生的推理,無法在另一組可能具對抗性的指令下被重播。
API 提供了一流的替代方案,可在對話進行中修改對話,涵蓋大多數編輯對話記錄的使用情境:用於新增指令的對話中途系統訊息、用於每輪提醒的輪次範圍系統訊息、用於新增與移除工具的對話中途工具變更,以及用於逐輪調整思考深度的逐訊息 effort。本頁其餘部分說明如何判斷您的整合是否受影響,以及如何將常見的 harness(代理執行框架)模式遷移至這些功能。額外的好處是,讓每個思考區塊之前的所有內容逐位元組保持不變,也能讓「prefix」(前綴)對「prompt caching」(提示快取)保持穩定,請參閱提示快取。
您是否需要採取任何行動,取決於由什麼來管理您的對話歷史:
- 您使用官方 Claude 產品或 SDK: Claude Code、claude.ai、Claude Managed Agents 或 Claude Agent SDK。這些會為您保持前綴完整。
- 您直接呼叫 Messages API,無論是從您自己的代理迴圈或任何其他環境。您應檢查程式碼,並確保
messages陣列被視為「append-only」(僅可附加)。以下常見模式會編輯前綴,並使編輯點之後的思考失效:- 修剪或捨棄較舊的輪次
- 在用戶端摘要較舊的輪次並保留最近的輪次
- 將提醒注入較早的輪次,並在下一個請求中移除
- 每次請求都重建
system提示(目前時間、token 預算、模式旗標) - 在工作階段中途新增或移除
tools中的項目
運作方式
對於新請求,API 會檢查:
- 模型相同或更新。 區塊可由產生它的模型以及之後的模型讀取,但無法由更早的模型讀取。移至較新模型的對話會保留其推理。移至較舊模型的對話,這些區塊會無法通過模型檢查,API 會在該請求中捨棄它們。確切的各模型清單請參閱保留思考。
- 區塊之前沒有任何變更。 頂層
system提示、tools中的工具集合,以及區塊之前的每則訊息。使用伺服器端壓縮時,受檢查的前綴從最近的壓縮區塊開始。 - 較早思考區塊的鏈結未中斷。 較早的
thinking與redacted_thinking區塊不屬於前綴的一部分,但每個思考區塊都會跨輪次記錄其前一個區塊。您可以從歷史的開頭移除思考區塊。從中間移除一個會使其後的每個思考區塊失效。
未通過模型檢查的區塊一律會被捨棄。對於前綴不符,您可透過 thinking.block_binding.prefix_mismatch_behavior 選擇處理方式,這需要 thinking-binding-controls-2026-08-01 beta 標頭:
"drop_block":API 會移除該區塊以及對話中其後的每個思考區塊,且請求成功。被捨棄的區塊不計費。回應會在頂層input_transformations陣列中列出它們(串流時位於message_start事件上)。"error":API 以 400invalid_request_error拒絕請求,並指出第一個失敗的區塊。
預設為 "error"。該標頭讓您可設定此欄位,並在回應中加入 input_transformations。
受影響對象
Claude Fable 5.1。模型清單請參閱保留思考。
在 Claude Fable 5.1 上,API 對新帳戶強制執行此檢查。新帳戶是指在 2026 年 8 月 31 日 00:00 UTC 當日或之後建立的帳戶。相同定義適用於 Claude API 與雲端平台。之後的模型將對所有使用者強制執行此檢查。
設定了 prefix_mismatch_behavior 的請求,無論帳戶年齡為何,都會選擇加入強制執行,這也是您從較舊帳戶進行測試的方式。若要檢查您的帳戶是否預設強制執行,請在不帶 beta 標頭的情況下傳送一個編輯歷史的請求:若收到指出該標頭名稱的 400,即表示已強制執行。
如何判斷您的整合是否受影響
擷取您的整合在幾個正常輪次中傳送的確切請求主體,若您的產品會進行壓縮或工具變更,也請包含在內。對於每一對連續請求,比較 system、tools 以及 messages 的共用部分。在新附加的輪次之前,它們應逐位元組完全相同。
接著對照 API 進行確認。使用 thinking-binding-controls-2026-08-01 beta 標頭 與 claude-fable-5-1,將 thinking.block_binding.prefix_mismatch_behavior 設為 "drop_block",並透過您的整合執行一個正常的多輪工作階段。此請求是這類工作階段的第二輪,將第一個回應的 assistant 輪次原封不動地送回:
curl https://api.anthropic.com/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: thinking-binding-controls-2026-08-01" \
-d '{
"model": "claude-fable-5-1",
"max_tokens": 16000,
"thinking": {
"type": "adaptive",
"block_binding": { "prefix_mismatch_behavior": "drop_block" }
},
"system": "You are a coding agent.",
"messages": [
{ "role": "user", "content": "Fix the failing test." },
{
"role": "assistant",
"content": [
{ "type": "thinking", "thinking": "", "signature": "EqQBCkYIBxgCKkD..." },
{ "type": "text", "text": "I need to see the test first. Which file is it in?" }
]
},
{ "role": "user", "content": "tests/test_auth.py" }
]
}'之後每個回應都帶有頂層 input_transformations 陣列。請在每一輪記錄它:
{
"input_transformations": [
{
"type": "thinking_dropped",
"path": "messages.1.content.0",
"reason": "prefix_binding_mismatch"
}
]
}- 每一輪皆為空: 您的整合保持歷史完整。
reason: "prefix_binding_mismatch": 位於path的區塊之前的某些內容,在此請求與前一個請求之間發生了變更。比對system、tools與直到該輪次的messages以找出差異。reason: "model_binding_mismatch": 對話移至無法讀取較早模型區塊的模型(路由器、備援)。這不是您整合中的錯誤。請繼續傳送這些區塊,讓 API 捨棄目前模型無法讀取的部分。
這在任何帳戶上都有效,因為設定該欄位會讓請求選擇加入強制執行。若要改為在 CI 中明確失敗,請設定 "error"。400 的開頭為:
messages.1.content.0: Invalid `signature` in `thinking` block. The block is bound to a different conversation. Remove the block, or set `thinking.block_binding.prefix_mismatch_behavior` to "drop_block".若請求未帶 beta 標頭,訊息會接續:That setting requires the `thinking-binding-controls-2026-08-01` value in the `anthropic-beta` header. 訊息通常以一句指出變更內容的句子結尾,例如 system 提示或 tools 清單與區塊建立時不同。
此錯誤的所有變體請參閱思考疑難排解。
什麼算是編輯
在兩個連續請求之間:
| 請求之間的變更 | 之後的思考區塊 |
|---|---|
| 在結尾附加訊息 | 有效 |
新增一個帶有 defer_loading: true 且尚未被任何內容參照的工具 | 有效 |
從歷史開頭移除 thinking 區塊(某個點之前的每個思考區塊) | 有效 |
變更 system、tools 與 messages 以外的任何請求參數(max_tokens、output_config、tool_choice、metadata 等) | 有效 |
新增、移動或移除 cache_control 標記 | 有效 |
| 回傳相同位元組的輪替簽署 URL | 有效 |
| 伺服器端壓縮或上下文編輯移除或取代內容 | 有效(檢查比較的是您傳送的內容,而非伺服器編輯後的副本) |
| 保留在原位的已清除輪次範圍系統訊息 | 有效 |
編輯、重新排序或刪除任何較早的 user、assistant 或 system 訊息 | 無效 |
| 在較早的 user 輪次新增文字區塊,或移除您上次新增的文字區塊 | 無效 |
變更頂層 system 字串或區塊 | 無效 |
在 tools 中新增、移除、重新命名或編輯工具 | 無效 |
從歷史中間移除一個 thinking 區塊並保留之後的區塊 | 對之後的每個思考區塊皆無效 |
| 在下一個請求回傳不同位元組的圖片或文件 URL | 無效 |
| 同一則輪次範圍訊息在之後的請求中被刪除或改寫 | 無效 |
更新您的整合
每個模式都以一項 API 功能取代一種歷史編輯,該功能對模型具有相同效果,而不會變更較早的位元組。
原樣附加回傳的 assistant 輪次
儲存每個回應的 content 陣列,並將其原封不動地作為 assistant 輪次送回,所有區塊類型皆依接收順序,包括 thinking 欄位為空的 thinking 區塊。不要透過會捨棄未知區塊類型或空欄位的中介型別重新序列化。
以對話中途系統訊息新增指令,而非編輯 system
如果您的程式碼每次請求都重建頂層 system 提示(目前時間、token 預算、模式旗標、新發現的專案上下文),對話中的每個思考區塊都會無法通過檢查。請在工作階段開始時凍結 system,當有變更時,在 messages 中該變更成立的位置附加一則 role: "system" 訊息:
{
"role": "system",
"content": "The user switched the workspace to read-only mode. Do not write files until told otherwise."
}模型會以系統提示的權威對待它,且其之前的所有內容皆未變更。在 Claude Fable 5.1 上不需要 beta 標頭。在工具迴圈中,請將其放在 tool_result user 訊息之後,絕不要放在 assistant 的 tool_use 與其 tool_result 之間(請參閱限制)。
以輪次範圍系統訊息傳送每輪提醒
最常見的歷史編輯是每輪的提示推動(nudge):在每批工具結果之後附加一行(「將獨立的讀取一起請求」、「您已有一段時間未向使用者更新進度」),並在下一個請求中移除,以免提醒堆積。移除它就是編輯。
請改為在 tool_result user 訊息之後,以帶有 clear_at: "next_user_message" 的對話中途系統訊息傳送該提醒(beta 標頭 mid-conversation-system-clear-at-2026-08-21)。此 messages 陣列是兩輪工具回合之後的請求。messages[3] 是前一個請求的提醒,保留在原位,而 messages[6] 是此請求的副本:
[
{ "role": "user", "content": "Fix the failing test." },
{
"role": "assistant",
"content": [
{ "type": "thinking", "thinking": "", "signature": "..." },
{
"type": "tool_use",
"id": "toolu_01",
"name": "read_file",
"input": { "path": "tests/test_auth.py" }
}
]
},
{
"role": "user",
"content": [{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "..." }]
},
{
"role": "system",
"clear_at": "next_user_message",
"content": "Request every independent read in one turn."
},
{
"role": "assistant",
"content": [
{ "type": "thinking", "thinking": "", "signature": "..." },
{
"type": "tool_use",
"id": "toolu_02",
"name": "read_file",
"input": { "path": "src/auth.py" }
}
]
},
{
"role": "user",
"content": [{ "type": "tool_result", "tool_use_id": "toolu_02", "content": "..." }]
},
{
"role": "system",
"clear_at": "next_user_message",
"content": "Request every independent read in one turn."
}
]僅含 tool_result 的 user 訊息算作「下一則 user 訊息」,因此 messages[3] 已被清除:它不呈現任何內容,也不耗用輸入 token,但它仍在陣列中,因此 messages[4] 中的思考保持有效。messages[6] 是模型在本輪看到的內容。在之後的請求中,將兩者保留在原位,並在下一則 tool_result 訊息之後附加下一個副本。輪次範圍訊息僅帶有 text,不接受 cache_control。請將快取斷點放在前一個 user 輪次上。請參閱輪次範圍系統訊息。
若無此 beta,請將提醒作為 text 區塊附加在同一則 user 訊息中的 tool_result 區塊之後,並將較早的副本保留在原位。模型會依最新的一則行動。
以 tool_addition 與 tool_removal 變更工具,而非編輯 tools
如果工具集合在工作階段中途變更(工具在驗證後解鎖、危險工具在模式切換後撤回),不要編輯 tools。請在工作階段開始時宣告完整集合,並使用對話中途工具變更從該點起提供或撤回工具(beta 標頭 mid-conversation-tool-changes-2026-07-01)。尚不可用的工具會取得 defer_loading: true 以及之後的 tool_addition 區塊,其形狀與此 tool_removal 相同:
{
"role": "system",
"content": [
{ "type": "tool_removal", "tool": { "type": "tool_reference", "name": "delete_branch" } },
{ "type": "text", "text": "Branch deletion is disabled for the rest of this session." }
]
}您在工作階段中途才得知其結構描述的工具(在執行階段發現的 MCP 伺服器),可以帶著 defer_loading: true 附加到 tools,並以 tool_addition 提供。未被參照的延遲工具不屬於前綴的一部分,因此附加它是安全的。附加一般工具則不安全。
盡可能在伺服器端修剪上下文
用戶端截斷與摘要是第二常見的編輯:捨棄或摘要最舊的輪次,並逐字保留最近的輪次。最近輪次的思考區塊是在您移除的歷史仍存在時產生的,因此它們無法通過檢查。伺服器端的對應功能不算作編輯,因為檢查比較的是您所傳送的對話:
- 壓縮(compaction)會在上下文接近您設定的閾值時,將較舊的輪次摘要為一個壓縮區塊,而受檢查的前綴會從該區塊重新開始。其
instructions參數接受您自己的摘要提示(「保留每個股票代號、部位大小與已陳述的假設」)。 - 上下文編輯(context editing)依規則清除舊的工具結果(
clear_tool_uses_20250919)或由舊到新清除舊的思考區塊(clear_thinking_20251015)。
用戶端自訂壓縮
此檢查並不禁止用戶端壓縮。規則更為狹窄:不要在您已重寫的前綴之後保留思考區塊。
簡單壓縮是建議的形式,且不需要任何變更。當對話變得太長時,將其摘要為一則訊息,並以該摘要加上新的 user 輪次開始下一個請求,不重播任何較早的輪次或思考區塊:messages 變為 [{"role": "user", "content": "<summary of the session so far>\n\n<the next instruction>"}]。沒有較早的思考留存,因此沒有任何內容會失敗,模型會在壓縮後的對話上重新思考。Claude 模型以此方案在長時程任務上進行訓練,對大多數工作負載而言,其表現與更精細的方案相當。它會在壓縮點重設提示快取,任何壓縮皆是如此。
另外兩種常見形式照原樣會失敗,各需一項變更:
- 保留尾端壓縮摘要較舊的輪次,並逐字保留最近的輪次。保留輪次的思考區塊是針對完整歷史產生的,因此它們在摘要之後會失敗。修正方式:從您帶過去的每個 assistant 輪次中剝除
thinking與redacted_thinking,保留text與tool_use,或傳送prefix_mismatch_behavior: "drop_block"讓 API 剝除它們。 - 背景壓縮在關鍵路徑之外建立摘要,並在對話持續進行時將其換入,因此期間產生的每個輪次都帶有早於換入的思考。修正方式:在每個仍帶有換入前產生之思考區塊的請求上傳送
"drop_block"(或自行剝除這些區塊;換入後第一個回應上的input_transformations會精確列出是哪些),或同步進行壓縮。
從對話記錄中間剪除個別輪次會使其後的所有內容失效,沒有任何用戶端形式能避免這一點。請針對您原本要做的指令變更使用對話中途系統訊息,或使用伺服器端上下文編輯進行選擇性移除。
不要在工具回合中途壓縮:tool_use 仍在等待 tool_result 的 assistant 輪次應帶著完整的思考送回,讓模型以其推理完成該回合(請參閱保留思考區塊)。
以 ID 參照檔案,而非內容會變更的 URL
對於帶有 url 來源的 image 或 document 區塊,擷取到的位元組屬於受檢查前綴的一部分,而 URL 字串則不是。「最新螢幕截圖」端點或經編輯的文件會使之後的思考失效。同一檔案的輪替簽署 URL 則不會。對於您跨輪次參照的內容,請以 Files API 上傳一次並使用 file_id,或傳送 base64。
決定不符時的處理方式
一旦您的整合為僅可附加,請為正式環境選擇一個 prefix_mismatch_behavior。它僅管控前綴不符。目前模型無法讀取的區塊(在路由器切換或伺服器端備援之後)一律會被捨棄,並在傳送 beta 標頭時於 input_transformations 中回報。
"error"(預設):若前綴不符只可能意味著您程式碼中的錯誤。您會在測試中從 400 得知,而非從被靜默捨棄的區塊得知。在 Message Batches API 中,未設定時的預設會捨棄失敗的區塊,而非使批次項目失敗;若您希望項目出錯,請明確設定"error"。"drop_block":若您寧願捨棄受影響的區塊而非失敗。請記錄input_transformations。
如果您在正式環境中捕捉到 400,重試相同請求不會清除它。請以 prefix_mismatch_behavior: "drop_block"(以及 beta 標頭)重試,這會精確移除失敗的區塊,包括 tool_use 仍在等待其 tool_result 的 assistant 輪次中的任何區塊。捨棄僅適用於該請求,因此請在工作階段的其餘部分持續傳送 "drop_block"(以及 beta 標頭)。若無此 beta,請從歷史中剝除每個 thinking 與 redacted_thinking 區塊,保留每個輪次的 text 與 tool_use 區塊,並重試一次。然後修正造成此問題的編輯。
本頁使用的 API 功能
| 功能 | 取代的做法 | 狀態 | 標頭 |
|---|---|---|---|
未保留區塊的控制項(thinking.block_binding.prefix_mismatch_behavior、input_transformations) | 在前綴不符時選擇拒絕或捨棄,並查看捨棄了什麼 | Beta | thinking-binding-controls-2026-08-01 |
對話中途系統訊息(messages 中的 role: "system") | 重建頂層 system 提示 | 穩定 | 無 |
輪次範圍系統訊息(clear_at: "next_user_message") | 注入提醒並在下一個請求刪除 | Beta | mid-conversation-system-clear-at-2026-08-21 |
對話中途工具變更(tool_addition、tool_removal) | 編輯 tools 陣列 | Beta | mid-conversation-tool-changes-2026-07-01 |
壓縮(用於自訂摘要提示的 instructions) | 用戶端摘要舊輪次 | Beta | compact-2026-01-12 |
上下文編輯(clear_tool_uses_20250919、clear_thinking_20251015) | 用戶端刪除舊工具結果或思考 | Beta | context-management-2025-06-27 |
Files API(file_id 來源) | 內容在請求之間變更的 URL | 穩定 | 無 |
逐訊息 effort(role: "system" 訊息上的 output_config.effort) | 在請求之間變更頂層 effort(保護提示快取,而非思考:effort 不屬於前綴的一部分) | Beta | mid-conversation-output-config-2026-07-01 |
若要在一個請求中組合標頭:
anthropic-beta: thinking-binding-controls-2026-08-01,mid-conversation-system-clear-at-2026-08-21,mid-conversation-tool-changes-2026-07-01相同的 beta 名稱適用於 Amazon Bedrock 與 Google Cloud。如何以各 SDK 傳送它們,請參閱 Beta 標頭。
檢查清單
- 如果由官方 Claude 產品或 SDK(Claude Code、claude.ai、Claude Managed Agents、Claude Agent SDK)管理您的對話歷史,到此為止即可。
- 連續的請求主體在
system、tools與共用的messages前綴上逐位元組完全相同。 - 在
prefix_mismatch_behavior: "drop_block"下的完整工作階段未記錄任何prefix_binding_mismatch項目。 - Assistant 輪次依回傳內容逐位元組送回,包含所有區塊類型。
- 頂層
system與tools在工作階段中固定不變。變更放入role: "system"訊息與tool_addition/tool_removal區塊。 - 每輪提醒為輪次範圍系統訊息(或尾隨文字區塊),每次全新附加且從不移除。
- 上下文透過壓縮或上下文編輯修剪,或透過不在重寫前綴之後留下任何思考區塊、且從不拆分工具回合的用戶端壓縮修剪。
- 跨輪次檔案為
file_id或 base64,而非可變的 URL。 - 已設定正式環境的
prefix_mismatch_behavior,並監控其 400 或捨棄項目。
後續步驟
診斷並修正最常見的思考失敗:設定 400 錯誤、空白或遺失的思考區塊、max_tokens 停止,以及快取未命中。
在對話進行到一半時變更系統指令或工具可用性,而不使其之前的快取前綴失效。
伺服器端上下文壓縮,用於管理接近上下文視窗限制的長對話。
以 cache_control 快取提示前綴以降低成本與延遲,可使用自動快取或具 5 分鐘或 1 小時 TTL 的明確斷點。
Was this page helpful?