此功能符合零資料保留(Zero Data Retention,ZDR)的資格,但有有限的技術性保留。請參閱資料保留章節,以了解保留哪些內容及其原因的詳細資訊。
提示快取(prompt caching)可大幅降低延遲和成本,但前提是您的提示開頭必須與最近的請求逐位元組完全相同。重新排序的工具、插入系統提示中的時間戳記,或對先前訊息的編輯,都可能悄悄地使快取失效。若沒有快取診斷,唯一的訊號就是 usage.cache_read_input_tokens 降為零,卻無從得知是什麼發生了變化。
快取診斷填補了這個缺口。傳入您先前回應的 id,API 便會比較這兩個請求,並告訴您它們在何處出現分歧(模型、系統提示、工具或訊息歷史記錄),讓您能夠修正根本原因,而非憑空猜測。
快取診斷目前處於測試版。請在您的 API 請求中包含 beta header(測試版標頭)cache-diagnosis-2026-04-07 以使用此功能。
快取診斷目前僅在 Claude API 上提供,不支援 Amazon Bedrock 或 Vertex AI。
當測試版標頭存在時,API 會儲存每個請求的輕量級指紋(fingerprint),並以回應的 id 作為索引鍵。在您的下一個請求中,將該 id 作為 diagnostics.previous_message_id 傳入。API 會為新請求重建指紋,將其與已儲存的指紋進行比較,並在回應中附加一個 diagnostics 物件,描述第一個分歧點。
此比較針對的是請求結構,與快取是否實際命中無關。請參閱搭配 usage 解讀診斷結果,了解如何將 diagnostics 結果與 usage.cache_read_input_tokens 結合使用。
指紋僅包含雜湊值和 token 數量估計值(絕不包含原始提示內容),保留時間有限,範圍限定於您的組織和工作區,且不會用於任何其他目的。
在每一輪對話中都傳送測試版標頭。在第一輪時,傳入 "previous_message_id": null 以選擇加入此功能,但不與先前的訊息進行比較。在後續輪次中,傳入先前回應的 id。
client = anthropic.Anthropic()
SYSTEM = "You are an AI assistant analyzing a large document. <document>...</document>"
# 第 1 回合:以 previous_message_id=None 選擇加入
r1 = client.beta.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system=SYSTEM,
messages=[{"role": "user", "content": "Summarize section 1."}],
diagnostics={"previous_message_id": None},
betas=["cache-diagnosis-2026-04-07"],
)
# 第 2 回合:參照先前的回應 ID
r2 = client.beta.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system=SYSTEM,
messages=[
{"role": "user", "content": "Summarize section 1."},
{"role": "assistant", "content": r1.content},
{"role": "user", "content": "Now summarize section 2."},
],
diagnostics={"previous_message_id": r1.id},
betas=["cache-diagnosis-2026-04-07"],
)
diagnostics = r2.diagnostics
if diagnostics is None:
print("No divergence detected.")
elif diagnostics.cache_miss_reason is None:
print("Comparison still pending.")
else:
print(f"cache_miss_reason: {diagnostics.cache_miss_reason.type}")在串流回應中,diagnostics 會出現在 message_start 事件上。
# 第 2 回合:串流,參照先前的回應 ID
with client.beta.messages.stream(
model="claude-opus-4-8",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system=SYSTEM,
messages=[
{"role": "user", "content": "Summarize section 1."},
{"role": "assistant", "content": r1.content},
{"role": "user", "content": "Now summarize section 2."},
],
diagnostics={"previous_message_id": r1.id},
betas=["cache-diagnosis-2026-04-07"],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
print()
r2 = stream.get_final_message()
diagnostics = r2.diagnostics
if diagnostics is None:
print("No divergence detected.")
elif diagnostics.cache_miss_reason is None:
print("Comparison still pending.")
else:
print(f"cache_miss_reason: {diagnostics.cache_miss_reason.type}")message_start 事件會攜帶完整的 diagnostics 欄位;請參閱回應格式以了解可能的值。
在多輪對話中,將最新回應的 id 作為 previous_message_id 傳遞到每一輪。第一次迭代傳入 null 以選擇加入;後續每次迭代則傳入先前回應的 id。
回應 Message 上的 diagnostics 欄位有四種可能的狀態:
| 值 | 意義 |
|---|---|
| 欄位不存在 | 請求未包含 diagnostics,或缺少測試版標頭。 |
null | previous_message_id 為 null(第一輪,無可比較對象),或已執行比較且未發現分歧。 |
{"cache_miss_reason": null} | 回應序列化時比較仍在執行中。當回應啟動非常快速時可能發生此情況。請將其視為無定論,並在下一輪檢查。 |
{"cache_miss_reason": {...}} | 附加了 cache_miss_reason。對於 *_changed 類型,這會識別第一個分歧點;previous_message_not_found 和 unavailable 則是未產生比較結果的情況。 |
當 cache_miss_reason 非 null 時,其格式如下:
{
"id": "msg_01Xyz...",
"type": "message",
"role": "assistant",
"content": [{ "type": "text", "text": "..." }],
"usage": {
"input_tokens": 42,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 41850,
"output_tokens": 210
},
"diagnostics": {
"cache_miss_reason": {
"type": "system_changed",
"cache_missed_input_tokens": 41850
}
}
}cache_miss_reason 是以 type 區分的聯集型別(discriminated union)。回應僅報告最早的分歧點,因此請先修正它;後續的分歧可能被隱藏在其後。
| 類型 | 意義 | 應變更的內容 |
|---|---|---|
model_changed | model 與先前的請求不同(例如,路由器、A/B 測試或備援機制選擇了不同的模型)。快取是依模型區分的。 | 在快取的對話中保持模型不變。 |
system_changed | system 參數不同。通常是時間戳記、請求 ID 或其他每次請求不同的值被插入到系統提示中。 | 將系統提示設為位元組穩定的常數,並將動態資料移至快取斷點之後的第一個 user 訊息中。 |
tools_changed | tools 陣列不同:在輪次之間新增、移除或重新排序了工具,或工具的 input_schema JSON 以非確定性方式序列化。 | 在每一輪以固定順序傳送相同的工具清單,並以確定性方式序列化結構描述(例如,對鍵進行排序)。 |
messages_changed | 模型、系統和工具皆相符,但 messages 中較早的項目被更改、重新排序或移除,而非僅附加新內容。通常是對話歷史記錄被截斷或編輯,或助理輪次和 tool_result 區塊在重新傳送時以不同方式重新序列化。 | 將歷史記錄視為僅可附加;逐字回傳助理的 content 和工具結果。 |
previous_message_not_found | 所提供的 previous_message_id 沒有對應的已儲存指紋。這並不代表您的請求有所變更。通常是先前的請求未攜帶測試版標頭、來自不同的工作區,或距離傳送時間已過太久。 | 在每一輪都傳送測試版標頭,並讓連續輪次在時間上保持緊密。 |
unavailable | 此請求無可用的診斷資訊。這包括以下情況:model、system 和 tools 皆相符,但另一個影響提示的請求參數(tool_choice、thinking、context_management、output_config、output_format 或作用中的 anthropic-beta 標頭集合)不同;以及對話非常長,分歧點超出比較範圍的情況。您的請求已正常處理。 | 在快取對話的整個生命週期中,保持影響提示的請求參數不變。若問題持續存在,請套用提示快取頁面中疑難排解常見問題下的手動檢查。 |
四種 *_changed 類型還會攜帶一個 cache_missed_input_tokens 整數:這是對分歧點之後有多少輸入 token 的估計值,讓您了解損失了多少可快取的前綴。它是在 tokenization 之前根據位元組長度推算的,因此請將其視為量級指標,而非計費數字。它可能與 usage.input_tokens 不同(偶爾會超過)。
diagnostics 回答的是「我的請求是否有變更?」,而 usage.cache_read_input_tokens 回答的是「快取是否命中?」。將兩者結合可告訴您應該檢查何處。
此矩陣適用於您傳入實際 previous_message_id 的輪次。在第一輪(previous_message_id: null)時,diagnostics 始終為 null,且 cache_read_input_tokens 通常為零,因為此時正在寫入快取而非讀取;無需進行疑難排解。當 cache_miss_reason 為 null(比較仍在進行中;請在下一輪檢查)或其 type 為 previous_message_not_found 或 unavailable(未產生比較結果)時,此矩陣亦不適用。
| 診斷結果 | 快取讀取 token 數 | 解讀 |
|---|---|---|
null | 高 | 運作符合預期。您的前綴穩定且快取命中。 |
null | 低或零 | 您的請求相符,但快取項目已不再可用。請考慮縮短輪次之間的間隔,或使用 1 小時快取 TTL。 |
cache_miss_reason 為 *_changed 類型 | 低或零 | 您的程式錯誤。請求已變更;請修正 type 所指示的原因。 |
cache_miss_reason 為 *_changed 類型 | 高 | 罕見。變更發生在提示的後段,但較早的 cache_control 斷點仍然命中。值得修正,但影響較小。 |
previous_message_id 查詢的指紋會在短時間後過期。請在時間相近的請求之間執行診斷比較。unavailable 而非精確位置。unavailable,或在比較仍在執行時傳回 cache_miss_reason: null。快取診斷符合 ZDR 資格(合格)。Anthropic 不會為此功能儲存您的提示或 Claude 輸出的原始文字。
為每個請求儲存的指紋僅包含加密雜湊值和 token 數量估計值,以回應的 id 作為索引鍵,範圍限定於您的組織和工作區。指紋會在短時間後過期,且不會用於任何其他目的。
如需了解所有功能的 ZDR 資格,請參閱 API 與資料保留。
Was this page helpful?