事件報告:Bedrock Invoke 上 Claude Code 的提示快取失效
**日期:**2026 年 7 月 4 日至 2026 年 7 月 10 日
受影響版本: v1.91.0 和 v1.91.1
嚴重性: 中等(靜默成本回歸;不影響正確性)
狀態: 已在 v1.91.2 修正
注意: 如果您透過 LiteLLM 在 Amazon Bedrock 上執行 Claude Code,且使用
v1.91.0或v1.91.1,請升級至v1.91.2或更新版本。
摘要
在 7 月 4 日到 7 月 10 日之間,執行 v1.91.0 或 v1.91.1 的代理程式,會在透過 Amazon Bedrock 的 Invoke API 路由 Claude Code 工作階段時,靜默破壞 Anthropic 提示快取。對於回報此問題的客戶而言,暖工作階段的快取命中率從大約 90% 降到 25% 到 45%,而團隊每日支出在相同用量下上升了 2 到 3 倍。請求仍然回傳 200,且完成內容正確;唯一的症狀是快取未命中率與帳單。
原因是:PR #31364 將 role: "system" 中每個 messages 項目移到 Invoke 路徑上的頂層 system 欄位,這會讓工具定義與系統提示之後的每個快取斷點失效。修正已於 7 月 10 日隨 v1.91.2 釋出(#32578、#32831、#32882),並附上在修正前程式碼上會失敗的回歸測試。
這個結果完全由我們承擔。觸發因素是 Claude 新模型與 Claude Code 使用系統訊息方式的一項文件不佳的變更,但客戶之所以使用閘道,正是因為不需要追蹤提供者的怪異行為。忠實轉譯請求(包括其快取語意)是我們的核心工作,而這次我們沒有做好。這篇文章會精確說明發生了什麼事、為什麼我們的測試與審查沒能抓到,以及我們做了哪些改變,避免這類回歸再次釋出。
背景
有三個事實構成這次事件的前提:
- Claude 提示快取是以前綴為基礎:
- 以遞增成本排序的 token 計價為:
- 快取讀取(0.1x)
- 一般寫入(1x)
- 快取寫入(5m ttl 為 1.25x,1h ttl 為 2x)
- 當 Claude Code 發出新請求時,Bedrock 提供者會檢查先前是否有任何請求是目前請求的截斷前綴。如果有,它只會讀取快取到該點為止。
- 以遞增成本排序的 token 計價為:
- 對話中途的系統訊息是新的:
- 在 2026 年 5 月 28 日,Claude Opus 4.8 作為第一個接受
role: "system"項目置於messages之內的模型釋出(文件)。Claude API 文件在 同一天 也記錄了這一點。 - Claude Code(
v2.1.154)於 2026 年 5 月 28 日開始輸出這些項目,但其變更記錄中未提及。 - Bedrock 最晚在 2026 年 6 月 9 日 文件化了相同支援(第一個 archive.org 擷取;該頁面可能早在 5 月 28 日就已出現)。
- 在 2026 年 5 月 28 日,Claude Opus 4.8 作為第一個接受
- Bedrock 有兩個 Anthropic API,規則不同:
- Converse 需要所有系統內容都放在頂層欄位;LiteLLM 自 2024 年 12 月起就已將其提升至那裡(#7037)。
- Invoke 使用原生 Anthropic Messages 格式,其中 Opus 4.8 之前的模型會以 400 錯誤拒絕對話中途的系統項目,而較新的模型則接受它們。
出了什麼問題
- 在 5 月 28 日之後,Bedrock Invoke 上的 Claude Code 工作階段在會話中途開始出現 400 錯誤,前提是同時符合兩件事:
- 模型比 Opus 4.8 還舊
- 模型是以別名提供
- Claude Code 會藉由在模型名稱中尋找像
opus-4-7或sonnet-4-6這類版本子字串來偵測能力。 - 例如,像
bedrock-claude這樣的別名不包含任何這類字串,因此 Claude Code 會假設它具備最新功能集,並且總是輸出對話中途的系統訊息。
- Claude Code 會藉由在模型名稱中尋找像
- 一位企業客戶用本機修補程式繞過了這些 400 錯誤,該修補程式會將
messages中每個系統項目提升到頂層system,模仿 Converse 行為,並請我們上游合併。我們於 7 月 4 日在v1.91.0中以 #31364 形式釋出。 - 這個提升修正了 400 錯誤,但因為總是提升
messages中的系統項目,當 Claude Code 寫入新的對話中途系統訊息時,就會使整個messages快取失效;我們量測到這種情況平均約每 3 回合發生一次。 - 這大幅降低了快取命中率並提高了快取寫入率,導致支出增加。
偵測與回應
7 月 8 日,一位受影響的客戶提供了這個回歸問題的詳細 bug 回報。我們同一天自行端到端重現了它。
三個 PR 修正了這個問題,三者都已於 7 月 10 日隨 v1.91.2 釋出,並經過大量端到端測試;同時也加入了在修正前程式碼上會失敗的回歸測試:
| 日期(2026) | 事件 |
|---|---|
| 5 月 28 日 | Opus 4.8 釋出;Claude Code 開始輸出對話中途的系統訊息 |
| 6 月 27 日 | 客戶的繞過方式上游合併為 #31364 |
| 7 月 4 日 | v1.91.0 隨回歸問題釋出 |
| 7 月 6 日 | 客戶觀察到支出增加 2 到 3 倍且快取命中率崩跌 |
| 7 月 8 日 | 回歸問題回報;找出根本原因;提出修正 |
| 7 月 10 日 | v1.91.2 隨三項修正與回歸測試釋出 |
| 7 月 13 日 | 客戶確認完全恢復 |
為什麼我們的流程沒有抓到這個問題
- 原始修補程式的測試不是端到端。 我們用單輪
curl請求驗證它,看到 400 變成 200,並假設這就是 Claude Code 會使用的形式。事實並非如此。我們沒有追查根本原因(當時我們還不知道對話中途系統訊息的存在)或其對快取的影響,而是把它視為無害的邊緣案例修正。 - 審查缺乏可提出異議的脈絡。 人類審查者看到的是一個小型相容性修補程式、通過的測試,以及對於 Claude Code 為何開始送出這類對話中途系統訊息沒有任何說明;我們的 AI 審查機器人也沒有標示出快取影響。流程中的任何人都沒有足夠資訊把提升與快取失效連起來。
- 成本回歸是靜默的。 每個回應都是 200 且完成內容正確。唯一的訊號是快取讀取 token 數,而我們的 CI 或監控都沒有量測這些數據。
- 文件不完整。 這項功能從未出現在 Claude Code 的變更記錄中,而截至 7 月 13 日,Claude API 文件仍將其描述為僅限 Opus 4.8(未提及 Sonnet 或 Fable 5),而且在 Bedrock 上不可用,這與我們的實測結果相矛盾。
我們正在做的變更
- 我們的 e2e 套件將增加一個腳本化的多輪 Claude Code 工作階段,針對真實 Bedrock 將上下文擴展至約 250k tokens,並斷言快取讀取會單調增加且絕不會崩塌(已在 #32963 開始)。
- 我們將建立每週自動化負載測試,標記支出、快取讀取與寫入、turn 延遲、錯誤率等異常,讓成本與效能回歸在發版前被偵測並修正。
- 更新(7 月 21 日): 已在 #34166 完成。CI 現在每週會以並發的 Claude Code 形式工作階段,針對真實 Anthropic 與 Bedrock Invoke 部署進行測試;若錯誤率、warm-turn 快取讀取、快取寫入量、p95 turn 延遲,或記錄的支出偏離基準,就會使測試失敗。
- 每日自動比對 Anthropic 的 SDK 與文件,提醒我們有任何需要在客戶流量發現之前就先支援翻譯的新功能。
- 我們內部 dogfood LiteLLM,並將為新的請求形態設置監控,例如未知的
anthropic-beta標頭,以及同樣的異常偵測,這會在發版前提醒我們。 - 現在錯誤修正的合併門檻更高:validated 表示已針對真實客戶的流量、其精確的終端使用者應用程式,端到端地重現,且對根本原因有完整理解;合成請求還不夠。
已知限制
- Converse 會在
messages中的任何位置拒絕 system 項目,因此在bedrock_converse上我們仍必須提升,且經由 Converse 路由的 Claude Code 工作階段在每次對話中途出現 system 訊息時仍會失去快取前綴。如果您在 Bedrock 上執行 Claude Code,請將其經由 Invoke 路徑路由(bedrock/invoke/<model>)。我們正與 AWS 提升這項 API 限制。 - 我們正在測試 Vertex AI 和 Azure 路徑是否需要等效的提升,並會在取得更多資訊後更新這篇文章。
- 更新(7 月 21 日): 確實需要,而且 #33807(已於 7 月 20 日合併,將在下一個 stable 版本釋出)已補上這個缺口。我們已在 live 環境驗證,這兩個提供者都與 Bedrock Invoke 一樣,強制執行相同的 per-model 合約,因此兩條路徑現在都會重用具備模型感知的提升邏輯:較舊的模型會回傳 completions 而不是 400,而較新的模型會讓快取前綴保持 byte-identical。live e2e 測試涵蓋兩個提供者。
對每一個因這件事而讓帳單上升的團隊:我們很抱歉。閘道的價值在於,這類提供者變更會由我們吸收,而不是傳遞到您那裡;而上述的測試、監控與流程改善,就是我們打算持續維持這件事的方法。


