系統指令通常位於頂層的 system 欄位中,排在對話中所有訊息之前。這個位置對於 prompt caching(提示快取)來說非常理想:系統提示是穩定前綴的一部分,因此後續的回合都能命中快取。但對於您在會話進行到一半才發現需要的指令來說,這個位置並不理想,因為編輯頂層 system 欄位會改變提示的最開頭部分,並使其後所有內容的快取失效。
對話中途的系統訊息彌補了這個缺口。您可以在對話中新指令變得相關的位置附加一個 {"role": "system"} 訊息,而不是編輯頂層的 system 欄位。已快取的前綴保持不變,因此下一個請求仍會從快取中讀取,而新指令仍會被視為系統指令而非一般使用者文字來套用。
本頁涵蓋兩項功能:對話中途的系統訊息(已正式推出),以及對話中途的工具變更,這是隨 Claude Opus 5 推出的測試版功能,將相同的方法套用於 tools 陣列。
tools 陣列在雜湊請求前綴中的位置甚至比頂層 system 欄位更靠前,因此編輯它會使整個對話的提示快取失效。對話中途的工具變更是隨 Claude Opus 5 推出的測試版功能,是對話中途系統訊息在工具方面的對應功能。您不必在對話的整個生命週期中固定工具清單,而是可以在回合之間變更提供給模型的工具:預先在 tools 中宣告完整的工具集,然後使用 tool_addition 和 tool_removal 區塊,從對話中的特定位置開始向模型提供或撤回某個工具。tools 陣列本身從不改變,因此已快取的前綴保持完整。
tool_addition 和 tool_removal 是 role: "system" 訊息的 content 陣列中的內容區塊,可以與同一訊息中的 text 區塊混合使用。該訊息遵循與任何對話中途系統訊息相同的放置規則(請參閱限制),且變更從對話中的該位置開始生效。每個區塊的 tool 欄位是參照工具而非定義工具:{"type": "tool_reference", "name": "..."} 指名在請求的 tools 陣列中宣告的工具,而 MCP 連接器工具可以透過 mcp_tool_reference(server_name 和 name)個別參照,或透過 mcp_toolset_reference(server_name)作為整個工具集參照。參照未在 tools 中宣告的名稱會傳回 400 錯誤。
在 tools 中宣告的每個工具從對話開始就會提供給模型,除非它以 defer_loading: true 宣告,這會使其保持隱藏狀態,直到 tool_addition 區塊將其顯露出來。tool_addition 也會重新提供先前被 tool_removal 撤回的工具。
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5",
max_tokens=1024,
betas=["mid-conversation-tool-changes-2026-07-01"],
# 完整的工具集在一開始就宣告且永不變更,因此
# 快取的前綴保持完整。
tools=[
{
"name": "get_weather",
"description": "Get the current weather for a location.",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"},
},
"required": ["location"],
},
},
],
messages=[
{
"role": "user",
"content": "Say OK.",
},
# 從此處開始撤回 get_weather。此區塊透過名稱參照
# 該工具而非編輯 `tools`,因此先前的回合保持
# 位元組完全相同,快取仍可命中。
{
"role": "system",
"content": [
{
"type": "tool_removal",
"tool": {"type": "tool_reference", "name": "get_weather"},
},
],
},
],
)
for block in response.content:
if block.type == "text":
print(block.text)對話中途的工具變更目前為測試版。若要使用此功能,請在您的請求中包含測試版標頭 mid-conversation-tool-changes-2026-07-01。此功能適用於 Claude Fable 5、Claude Mythos 5、Claude Opus 4.8 和 Claude Opus 5,可在 Claude API、Amazon Bedrock 和 Google Cloud 上使用。
提示快取會依序對請求前綴進行雜湊:先是 tools,然後是 system,最後是 messages。快取命中要求前綴與最近的請求完全相符,逐位元組一致,直到快取斷點為止。
這種排序意味著頂層 system 欄位位於雜湊前綴的最開頭附近。對它的任何變更,即使只是附加一個句子,都會產生不同的雜湊值,導致請求無法命中系統提示及其後所有已快取訊息的快取。
對話中途的系統訊息讓您可以將指令新增到訊息歷史的末尾。新指令之前的所有內容都保持不變,因此現有的快取項目仍然相符,只有新訊息會被當作全新輸入處理。
以下是幾種適用的情況:
system 欄位會重新處理整個歷史記錄。在上述所有情況下,您都可以將指令放在一般的 user 訊息中,而 Claude 確實會遵循在使用者回合中到達的指令。差別在於優先順序:user 訊息被視為來自終端使用者,而 system 訊息被視為來自您,即應用程式操作者。當兩者衝突時,系統指令優先,因此請對操作者層級的事實和限制使用 system 角色,這些內容即使終端使用者要求不同的做法也應保持有效。對話中途的系統訊息保留了這種操作者層級的優先順序,同時無需承擔編輯頂層 system 欄位所帶來的快取未命中成本。
將一個 "role": "system" 的訊息新增到 messages 陣列中。content 可使用純字串或內容區塊,與 user 或 assistant 回合相同。該指令從對話中的該位置開始生效。當指令衝突時,較晚的系統訊息優先於較早的系統訊息,而對話中途的系統訊息在其後的回合中優先於頂層 system 欄位。
您仍然可以設定頂層 system 欄位,用於應套用於整個對話的指令。將對話中途的系統訊息保留給稍後才變得相關的指令,或您想要新增但不想使已快取前綴失效的指令。
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
# 自動提示快取:每個請求都會快取目前為止的對話,
# 而下一個請求會從快取中讀取未變更的前綴。
cache_control={"type": "ephemeral"},
system="You are a code review assistant. Be concise.",
messages=[
{
"role": "user",
"content": "Review process() in utils.py for performance issues.",
},
{
"role": "assistant",
"content": "The list comprehension is fine for small inputs. For large inputs, consider a generator to avoid materializing the full list.",
},
{
"role": "user",
"content": "Now review the calling code that invokes process().",
},
# 審查者在會話中途意識到所有建議也必須
# 符合團隊的嚴格型別政策。將指示附加在
# 此處可讓先前的回合保持位元組完全相同,因此
# 前一個請求所快取的前綴仍可從快取中讀取。
{
"role": "system",
"content": "From now on, every suggestion must include explicit type annotations.",
},
],
)
for block in response.content:
if block.type == "text":
print(block.text)此範例使用頂層 cache_control 欄位啟用自動快取。提示快取是選擇性啟用的:如果請求沒有 cache_control 欄位(無論是自動快取或明確斷點),則不會快取任何內容,每個請求都會為完整對話支付一般的輸入 token 價格。啟用快取後,附加系統訊息不會改變已快取的回合,因此攜帶新指令的請求仍會從快取中讀取這些回合,而不是重新處理它們。快取還要求對話達到最小可快取提示長度;像這樣簡短的範例低於該長度,因此 cache_creation_input_tokens 和 cache_read_input_tokens 會保持為 0,直到對話增長為止。
對話中途的系統訊息必須緊接在 user 回合(或以伺服器工具結果結尾的 assistant 回合)之後,並且必須是 messages 中的最後一個項目,或緊接在 assistant 回合之前。攜帶 tool_result 區塊的 user 訊息也算數:在代理迴圈中,您可以將系統訊息放在工具結果之後、Claude 的下一個回合之前。任何其他位置,包括在 assistant 的 tool_use 區塊與回應它的 tool_result 之間,都會傳回 400 錯誤。
在代理迴圈中,系統訊息放在傳遞工具結果的 user 訊息之後。這也是您的應用程式可以轉發使用者在 Claude 工作時輸入的內容的位置,讓新的上下文被吸收而無需重新開始該回合:
[
{ "role": "user", "content": "Run the test suite and fix any failures." },
{
"role": "assistant",
"content": [{ "type": "tool_use", "id": "toolu_01", "name": "run_tests", "input": {} }]
},
{
"role": "user",
"content": [
{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "12 passed, 0 failed" }
]
},
{
"role": "system",
"content": "The user sent the following message while you were working: also update the changelog before you finish."
}
]將系統內容表述為上下文,而非覆寫使用者的命令。陳述事實(「使用者傳來新輸入:X」、「剩餘的 token 預算現在是 Y」),並讓 Claude 據此行動。Claude 經過訓練會抵制看似違背使用者意願的指令,而這種保護機制同樣適用於系統角色,因此「忽略使用者所說的話」之類的措辭不如直接陳述發生了什麼變化來得有效。
此模式用於轉發對話本身終端使用者的輸入。請勿用它來傳遞工具輸出、檢索到的文件或其他第三方內容;請將這些內容保留在 tool_result 區塊中(請參閱限制)。
對話中途的系統訊息與提示快取設計為搭配使用:
cache_control 時才會進行快取,無論是頂層的自動快取欄位,或是內容區塊上的明確斷點。對話中途的系統訊息本身不會建立快取項目,若未啟用快取,就沒有可保留的節省效益。cache_control 放在跨請求保持不變的最後一個區塊上,無論是頂層 system 欄位的末尾、工具定義的末尾,或是訊息歷史中的穩定位置。避免編輯或移除已發送的對話中途系統訊息。與對先前訊息的任何其他變更一樣,這會使從該位置開始的快取失效。如果指令需要演變,請附加新的系統訊息,而不是重寫舊的訊息。連續的系統訊息會被接受並視為單一系統區段,整體遵循相同的放置規則。
system 訊息不能是 messages 中的第一個項目。對於從一開始就應套用的指令,請使用頂層 system 欄位。system 訊息必須緊接在 user 回合(包括攜帶 tool_result 區塊的 user 回合)或以伺服器工具結果結尾的 assistant 回合之後,並且必須位於 assistant 回合之前或作為陣列的結尾。它不能位於 tool_use 區塊與其 tool_result 之間。放置在其他位置會傳回 400 錯誤。tool_result 區塊中,並繼續遵循緩解越獄和提示注入的指引。快取的運作方式、斷點的放置位置,以及如何解讀快取使用量欄位。
當預期的快取命中未發生時,找出兩個請求究竟在何處出現分歧。
訊息結構、多回合對話以及 system 欄位。
撰寫有效的提示和系統指令。
tool_use 和 tool_result 區塊在 messages 陣列中的結構方式。
Was this page helpful?