變更工具或指示而不使前綴檢查失敗
傳送指示、工具、提醒或摘要,恢復已儲存的對話,或轉送其他人的請求,讓 Claude 保有其先前的思考。
要更新工具、指示或其他上下文,請讓您已傳送的所有內容維持原樣,並將更新加在結尾,讓它一直留在那裡。在具有 “preserved thinking”(保留思考)的模型上,變更您已傳送的內容可能會使其後的思考失效,且請求可能會失敗。
具備「preserved thinking」(保留思考)的模型為 Claude Fable 5.2、Claude Mythos 5.2、Claude Fable 5.1、Claude Mythos 5.1、Claude Opus 5.5、Claude Sonnet 5.5 以及 Claude Haiku 5.5。
原封不動地傳回助理輪次
依序傳回每個回應的完整 content 陣列,包括文字為空的思考區塊。文字為空的區塊是完整的,因為其 signature 以加密形式保存了推理內容。包含 fallback 區塊的輪次有其自己的規則。
序列化器、篩選器和串流解析器可能會破壞這一點。
變更指示
在每個請求中讓 system 保持不變。將您自己的指示放在結尾的 role: "system" 訊息中,且只在有所變更時才傳送。Claude 會將其視為來自您(營運者)的指示。請在對話的其餘部分保留它,因為之後刪除或改寫它會使其後的思考失效。您使用者的話語有其自己的規則。
必須隨每個輪次一起傳送的提醒則不同:傳送會自行清除的提醒。
系統訊息應放在最新的使用者訊息之後,即使該訊息包含工具結果也是如此。含有文字或工具區塊的系統訊息,若緊接在 Claude 的輪次之後或緊接在使用者訊息之前,會收到 400 錯誤。因此當 Claude 的輪次是最後一則時,請等到下一則使用者訊息就位後再傳送。
系統訊息並不保證 Claude 會遵循某項指示,因此請在執行您工具的程式碼中套用限制,例如唯讀模式。有些模型不接受系統訊息。
其他人可以編輯的文字
請思考您的使用者是否會預期 Claude 信任某個檔案,例如其他人可以編輯的 AGENTS.md 或 CLAUDE.md,或是已儲存的記憶。如果不會,請只在 tool_result 區塊中傳送其文字,包括第一個版本。原因請參閱間接提示注入。
不要將此類文字放在系統訊息或使用者訊息的文字中,且在新對話中,不要將其放在 system 中。
當您載入此類檔案或它有所變更時,請告訴 Claude 使用工具來讀取它,且不要包含其文字。或者,在下一則使用者訊息之後,自行附加工具呼叫及其結果:一則含有 tool_use 區塊的 assistant 訊息,接著一則其 tool_result 區塊保存該文字的 user 訊息。步驟請參閱自行撰寫工具呼叫。
您的使用者預期 Claude 遵循的檔案可以放在使用者訊息中。只有您能控制的指示檔案可以放在系統訊息中:載入一次,並附加每個更新後的版本。
更新日期、檔案或其他上下文
只建立一次 system 和第一則訊息,並在每個請求中原封不動地傳送它們。
將更新後的值放在您即將傳送的使用者訊息中其自己的文字區塊內,位於任何工具結果之後:
{
"role": "user",
"content": [
{ "type": "text", "text": "Environment update: the current branch is now release-2." },
{ "type": "text", "text": "Run the tests again." }
]
}只在它變更時才說明,並將其留在那裡。
將您的程式碼新增到訊息中的任何上下文與該訊息一起儲存。否則下一個請求會在相同的思考之前傳送不同的內容。
新增、移除或關閉工具
在每個請求中讓 tools 保持不變。在那裡新增、變更或移除工具(延遲載入的工具除外),會使對話中已有的思考失效,因為 tools 位於所有思考之前。描述中改寫一句話就足以造成這種情況。
要新增或移除工具,請附加一則含有 tool_addition 或 tool_removal 區塊的系統訊息,並使用適用於您情況的 beta 標頭。當 MCP 伺服器或外掛程式連線時,也請這樣做。
要在單一請求中關閉工具,請設定 tool_choice: {"type": "none"},並讓 tools 維持原樣。
修剪或摘要較舊的輪次
要保留最近的輪次及其思考,請讓 API 透過隨選 “compaction”(壓縮)撰寫摘要,並符合保留的思考維持有效的條件。以它傳回的壓縮區塊作為 messages 的開頭,並移除它所摘要的訊息。
如果由您自己的程式碼撰寫摘要,或在沒有摘要的情況下截掉較舊的輪次,請移除保留的輪次的思考,或傳送 "drop_block"。每次新的截斷都會再次使保留的輪次的思考失效,因此請減少截斷的次數,每次截斷較大的幅度。若要改為清除舊的工具結果,請使用上下文編輯。
儲存、恢復或分岔對話
儲存您傳送的內容和您收到的內容,並原封不動地傳送它們。恢復的對話就是一般的下一個請求:system、tools 和較早的 messages 必須具有它們原本的值。對於分岔,請將該分支的指示放在其第一則新的使用者訊息中,或放在其後的系統訊息中。思考無法移到具有不同歷史記錄的對話:請改為從摘要開始該對話。
變更您系統提示或工具的版本發布,對已在進行中的對話而言是一種變更。讓您的程式碼變成 “append-only”(僅附加)的修正也可能是。請繼續向每個進行中的對話傳送其最後一次成功請求的 system 和 tools,因為其最新的思考是在該版本之後產生的。回到較早的版本會使該思考失效。
在新對話中使用更新後的 system 和 tools。如果該版本發布出於安全考量而移除了某個工具或變更了某項指示,也請將其套用到進行中的對話。附加一個 tool_removal 區塊或一則系統訊息。
移除機密、個人資料或注入的文字
安全性和隱私權優先於讓思考保持有效。如果某則訊息含有您必須刪除的機密或個人資料,請移除該文字。也請從重複該文字的每則訊息和摘要中移除它。
對於含有注入指示的工具結果,請將其內容替換為簡短的說明,例如「已移除。」保留 tool_result 區塊本身,因為其 tool_use 需要一個。如果某個壓縮區塊含有該文字,請刪除該區塊,並從您自己的摘要開始。
接著刪除該文字首次出現處之後的每個 thinking 和 redacted_thinking 區塊。如果它位於 system 或 tools 中,那就是全部的區塊。每個區塊都可能重複該文字,而您無法讀取或編輯其中的內容。在此情況下傳送 "drop_block" 並不足夠,因為它會將這些區塊留在您儲存的歷史記錄中。對話會在沒有該推理的情況下繼續進行。
在注入的結果之後,後續的輪次可能已經根據它採取了行動。請檢查此後進行的工具呼叫,並撤銷您需要撤銷的部分。
技術細節
程式碼變更助理輪次的方式
- 序列化器捨棄它不認識的區塊類型,或重新排序、合併或分割區塊。這會改變每個後續區塊之前的內容。
- 程式碼略過看起來是空的思考區塊。如果它略過所有思考區塊,Claude 就會失去該推理。如果它只略過其中一些,缺口會使其後的思考失效。
- 您自己的串流解析器捨棄了沒有收到文字的思考區塊。SDK 的串流輔助工具會保留它。
省略思考
Claude 會失去您省略的推理。請省略最舊的區塊、最新的區塊或全部區塊,但不要省略中間的區塊。每個區塊都會記錄它是在哪個區塊之後產生的,因此缺口會使其後的區塊失效。在一個輪次中彼此之間沒有其他區塊的思考區塊會一起接受前綴檢查,因此請全部省略或全部不省略。一旦某個區塊被省略,就請持續省略它。
當工具呼叫尚未完成時,傳回該輪次的思考,讓 Claude 能以其推理完成這一回合。
工具迴圈中您的指示
訊息依此順序排列:
[
{
"role": "assistant",
"content": [
{ "type": "thinking", "thinking": "", "signature": "..." },
{
"type": "tool_use",
"id": "toolu_01",
"name": "run_tests",
"input": { "path": "tests/" }
}
]
},
{
"role": "user",
"content": [
{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "2 failed, 48 passed" }
]
},
{
"role": "system",
"content": "Plan mode is off. You can edit files."
}
]自行撰寫工具呼叫
在第一個請求中宣告一個讀取檔案的工具,或稍後在系統訊息中新增它,並讓您的程式碼回應 Claude 對它的呼叫。在下一則使用者訊息之後,附加一則含有該工具之 tool_use 區塊的 assistant 訊息。緊接在其後,附加一則 user 訊息,其 tool_result 區塊具有相符的 tool_use_id 並保存該檔案的文字。Claude 會在那之後回答:
[
{ "role": "user", "content": "Run the tests again." },
{
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "toolu_app_agents_md_1",
"name": "read_file",
"input": { "path": "AGENTS.md" }
}
]
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_app_agents_md_1",
"content": "The file's text"
}
]
}
]將兩者都保留在原處,並為每個新版本附加一組新的配對,使用新的 id。
工具迴圈中您使用者的話語與更新後的值
如果您要轉送使用者在 Claude 工作期間輸入的內容,請在傳送帶有 tool_result 區塊的使用者訊息之前加入它。將其作為最後一個 tool_result 之後的文字區塊。
來自您的值則可以改放在系統訊息中。在工具結果之後,Claude Sonnet 5.5 和 Claude Haiku 5.5 可能會將系統訊息中使用者的話語視為提示注入而忽略。如果您自己的指示和提醒位於每個工具結果之後,Claude Sonnet 5.5 也可能對它們這樣做。
當該輪次也呼叫了尚未有結果的伺服器工具,或使用了程式化工具呼叫時,含有工具結果的使用者訊息必須只包含 tool_result 區塊。此時請將文字加到下一則使用者訊息中。
不接受系統訊息的模型
在 Claude API 上,每個具有保留思考的模型都接受系統訊息。對於不接受的模型,請參閱當模型不接受系統訊息時。
為單一輪次傳送提醒
將提醒作為輪次範圍的系統訊息傳送:設定 clear_at: "next_user_message",並傳送 beta 標頭 mid-conversation-system-clear-at-2026-08-21。它應放在帶有 tool_result 區塊的使用者訊息之後:
{
"role": "system",
"clear_at": "next_user_message",
"content": "Run the linter before you report that a task is done."
}在下一則使用者訊息時,即使該訊息只有 tool_result 區塊,API 也會清除它,因此 Claude 會停止讀取它。在 Claude Sonnet 5.5 上,不要在每個工具結果之後都傳送一則。將每則提醒保留在您的 messages 中,無論是否已清除,除非它含有您必須移除的內容。移除或改寫提醒會使其後的思考失效。
若沒有該標頭,請傳送一般的系統訊息並將其留在原處。它永遠不會清除,因此提醒會不斷累積。在不接受系統訊息的模型上,請在使用者訊息中使用文字區塊。
工具變更需要哪種區塊和 beta 標頭
關於接受各個標頭的平台,請參閱對話中途的系統訊息與工具變更。
- 如果您在一開始就知道所有工具: 在第一個請求中宣告全部工具,並對稍後才提供的工具設定
defer_loading: true。接著在系統訊息的tool_addition或tool_removal區塊中指名該工具。Beta 標頭:inline-tools-2026-09-15或mid-conversation-tool-changes-2026-07-01。 - 如果您稍後才得知某個工具,或有結構描述會變更的工具: 在系統訊息的
tool_addition區塊中定義該工具。Beta 標頭:inline-tools-2026-09-15。 - 如果您稍後才得知某個工具,且所在平台沒有
inline-tools-2026-09-15標頭: 將該工具加到tools的結尾並設定defer_loading: true(這不算是變更),然後以名稱提供它。Beta 標頭:mid-conversation-tool-changes-2026-07-01。 - 如果您在 Claude API 上透過 MCP 連接器較晚連線 MCP 伺服器: 在
tool_addition區塊中定義其mcp_toolset。Beta 標頭:inline-tools-2026-09-15和mcp-client-2026-09-15。
如果 MCP 伺服器的工具清單可能會變更,請參閱固定 MCP 伺服器的工具清單。
這則系統訊息以名稱提供一個已宣告的工具並定義另一個工具,因此需要 inline-tools-2026-09-15:
{
"role": "system",
"content": [
{
"type": "tool_addition",
"tool": { "type": "tool_reference", "name": "search_tickets" }
},
{
"type": "tool_addition",
"tool": {
"type": "tool_definition",
"definition": {
"name": "get_weather",
"description": "Get the current weather in a city.",
"input_schema": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
}
}
]
}具有 defer_loading 的工具,以及指名它的 400 錯誤
具有 defer_loading: true 的工具不會進入 Claude 的上下文和前綴檢查,直到某則訊息或工具搜尋結果提及它為止。在那之前,新增、更新或移除它都不算是變更。在那之後就算。開啟或關閉 defer_loading 也算是變更 tools。
請至少宣告一個非延遲載入的工具,否則請求可能會收到指名 defer_loading 的 400 錯誤。
縮短或清除舊的結果和圖片
在首次傳送工具結果或圖片之前就先縮短或降低其解析度。如果您的程式碼清除、縮短或重新編碼已傳送的內容,其後的思考就會失效。若要稍後清除舊的工具結果(包括其中的任何圖片),請使用上下文編輯。傳送帶有類型為 clear_tool_uses_20250919 之編輯的 context_management,以及 beta 標頭 context-management-2025-06-27。完整的請求及其選項,請參閱上下文編輯。
透過 URL 傳送的檔案
對於透過 URL 傳送的檔案,API 會比對它擷取到的位元組。因此當簽署的 URL 過期時,為同一檔案使用新的 URL 是沒問題的。如果 URL 背後的內容可能會變更,請從第一個請求起就傳送 file_id 或 base64。
如果您自己的程式碼摘要或截斷較舊的輪次
在您自己的摘要或截斷之後,保留的輪次的思考會無法通過前綴檢查,因為它所跟隨的訊息已經不在了。請移除該思考,或傳送 "drop_block"。Claude 仍會在沒有它的情況下讀取該輪次。
程式庫、代理伺服器和閘道
如果其他人的請求會經過您的程式碼,您的改寫會變更他們的歷史記錄,而他們可能無法看到或修正這些變更。不要隱藏 400 錯誤。如果您替呼叫端進行復原,請告知他們,因為他們的歷史記錄仍保有該變更。
- 將
anthropic-beta值和thinking.block_binding按原樣傳遞。如果您的閘道只允許已知欄位,請加入thinking.block_binding和標頭值thinking-binding-controls-2026-08-01,否則您的使用者無法選擇"drop_block"。 - 不要移除 beta 標頭卻轉送該設定。那樣的請求會收到 400 錯誤。
- 將文字為空的思考區塊以及
input_transformations陣列傳回給呼叫端。 - 將
role: "system"訊息留在原處。將其移入system會使對話中已有的思考失效。 - 在
prefix_mismatch_behavior設定為"error"的情況下進行測試,這會在每個具有保留思考的模型上產生該錯誤。
後續步驟
什麼是保留思考、思考區塊與什麼綁定,以及切換模型或帳戶。
復原未通過前綴檢查的對話,並了解捨棄思考的代價。
系統訊息和工具變更應放在何處,以及哪些模型和平台接受它們。
這個頁面有幫助嗎?