如果你正在送出一段很長的系統提示 — RAG 情境、工具 目錄、代理規則、範例 — 那你很可能每次呼叫都在支付全額的輸入 費用。Anthropic 的提示快取能把已快取部分的費用砍到 原費率的 10%。OpenAI 也以隱含的方式做了同樣的事。 多數團隊都覺得這 30 分鐘的功夫很值得,因為它能可靠地把輸入 成本那一行砍掉 60~90%。
Brievio 把這兩種風格原封不動地轉送過去,對應的是真正的 模型。Anthropic 風格的 cache_control 適用於 Messages API;OpenAI 風格的 自動快取則適用於 Chat Completions API。這篇文章會走過兩者、那些 會悄悄讓快取失效的陷阱,以及該怎麼驗證你的命中率。
對照前後
一個天真的迴圈,把同一段 18K 權杖的系統提示送了十次:
# 多數人一開始的寫法:每一次呼叫都得重新為整段提示付費。
import anthropic
client = anthropic.Anthropic(
api_key="sk-brievio-...",
base_url="https://api.brievio.com",
)
SYSTEM = open("system-prompt.md").read() # 18,000 個權杖的規則 + 範例
# 一次工作階段裡有 10 個使用者問題。每次呼叫都送出這 18K 權杖的系統區塊。
for question in questions:
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=600,
system=SYSTEM,
messages=[{"role": "user", "content": question}],
)
# 每次呼叫的成本(僅輸入):18,000 × $3 / 1M = $0.054
# 10 次呼叫:光是輸入就要 $0.54。現在把系統區塊標記成可快取 — 只多一個欄位:
# 解法:把靜態前綴標記成可快取。第一次呼叫之後,約 5 分鐘內的
# 後續呼叫,對已快取的部分只需支付 10% 的輸入費率。同樣的答案,便宜 89%。
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=600,
system=[
{
"type": "text",
"text": SYSTEM,
"cache_control": {"type": "ephemeral"}, # 標記為可快取
}
],
messages=[{"role": "user", "content": question}],
)
# 第一次呼叫(寫入快取): 18,000 × $3 / 1M = $0.054
# 第 2~10 次(命中快取): 18,000 × $0.30 / 1M = $0.0054 每次
# 合計:$0.054 + 9 × $0.0054 = $0.103 (原本 $0.54 — 省了 81%)你剛剛在這次工作階段上省下了 81% 的輸入成本。第一次呼叫其實比 天真版本稍微貴一點(約 1.25 倍輸入費率以寫入 快取)。第 2 到第 10 次呼叫只需支付 10% 的費率。損益平衡點在 第 2 次呼叫 — 到了第 3 次你就已經划算了。到第 10 次,那已是 壓倒性的勝利。
OpenAI 風格:什麼都不用做
如果你用的是 OpenAI SDK,Chat Completions 會自動快取 任何超過 1,024 個權杖之提示的前綴。沒有旗標、沒有設定。Brievio 背後的同一個模型,無論你走的是 Anthropic 還是 OpenAI 路線,都會 在以下情況拿到折扣:
# OpenAI Chat Completions 風格 — 對 ≥1024 個權杖的提示會自動快取。
# 沒有旗標要設。「usage」物件會告訴你哪些被快取了。
from openai import OpenAI
client = OpenAI(
api_key="sk-brievio-...",
base_url="https://api.brievio.com/v1",
)
resp = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[
{"role": "system", "content": LONG_SYSTEM_PROMPT}, # >1024 個權杖
{"role": "user", "content": "Latest question…"},
],
)
# 在回應裡:
# resp.usage.prompt_tokens_details.cached_tokens → 17,800
# resp.usage.prompt_tokens → 18,200
# 17.8K/18.2K = 98% 的輸入來自快取。帳單會自動反映這一點。讀取 usage.prompt_tokens_details.cached_tokens 就能看到 有多少是從快取提供的。固定前綴越大 = 省得越多。經驗法則是: 如果你的系統提示比你的變動使用者內容還短,快取就發揮不了 多少作用。請把提示重新塑形,讓靜態部分既大又放在最前面。
多層快取 — 最多 4 個中斷點
對於某些層級變動得比其他層級快的代理迴圈,請設定多個 cache_control 中斷點。每一個都是到該點為止 所有內容的快照:
# Anthropic 每個請求最多支援 4 個快取中斷點 — 善用它們,
# 即使後面的層級有變動,也能讓快取保持熱度。
client.messages.create(
model="claude-sonnet-4-6",
max_tokens=600,
system=[
{"type": "text",
"text": ROLE_AND_RULES, # 約 3,000 個權杖
"cache_control": {"type": "ephemeral"}}, # 中斷點 1
{"type": "text",
"text": LARGE_KNOWLEDGE_BASE, # 約 15,000 個權杖,很少變動
"cache_control": {"type": "ephemeral"}}, # 中斷點 2
],
messages=[
{"role": "user",
"content": [
{"type": "text",
"text": CONVERSATION_HISTORY, # 每一輪都在增長
"cache_control": {"type": "ephemeral"}}, # 中斷點 3
{"type": "text", "text": new_question},
]},
],
)
# 當 CONVERSATION_HISTORY 變動時,中斷點 1+2 仍會命中快取。
# 只有中斷點 3 + 新問題需要支付全額輸入費率。快取鍵是整段前綴。在位置 N 加進一個權杖,位於 N 或其後的 每一個中斷點都會失效。順序很重要: 最穩定的內容放最前面。規則層應該很少變動;知識庫 每週更新;對話則每一輪都在增長。
會悄悄破壞快取的常見做法
- 把目前的日期或 request_id 放進提示。 每次呼叫都是一段新前綴,快取命中率是 0%。請對你的提示 輸入做雜湊,並跨呼叫做比較。
- 不具確定性的系統提示組裝方式。如果你 從一個 dict 來建構系統提示,在某些 Python 版本中 dict 的 迭代順序是會有影響的。請明確地對鍵排序。
- 快取生命週期約為 5 分鐘。稀疏的流量 模式(每 10 分鐘才一次呼叫)會得到零命中。要嘛把呼叫 批次化,要嘛接受這個損失。
- 1,024 個權杖的最低門檻。低於 1K 權杖, OpenAI 風格的快取不會啟動。請把零碎的靜態片段合併成 一段較長的前綴。
- 工具/函式定義是前綴的一部分。 往目錄裡新增一個工具,會讓所有人的快取都失效。請保持 工具目錄穩定;並為它做版本控管。
驗證命中率
看不見的快取不是工程 — 那只是在碰運氣。請在每一次呼叫上 記錄 usage:
# 永遠要讀取 usage。如果你預期命中快取,cached_tokens 卻是 0,
# 表示哪裡出了問題 — 通常是前綴不具確定性。
resp = client.messages.create(...)
u = resp.usage
print({
"input_uncached": u.input_tokens,
"input_cache_read": u.cache_read_input_tokens,
"input_cache_write": u.cache_creation_input_tokens,
"output": u.output_tokens,
})
# 常見的陷阱:把今天的日期或 request_id 放進系統提示,
# 會悄悄讓快取失效。請對你的輸入做雜湊;並驗證第二次發送相同呼叫時,
# cache_read_input_tokens 不為零。在 Brievio 儀表板裡, 用量頁面會逐模型、逐日顯示 快取的拆分。如果你看到 cache_read_input_tokens 佔 總輸入的百分比逐漸增長,代表快取正在運作。如果它一直卡在 0 或大幅波動,請逐項走過上面那份陷阱清單。
在 Brievio 上實際要花多少
每個模型的快取費率都公布在 定價頁面上:
- Anthropic 模型:快取讀取是輸入費率的 10%。快取寫入按輸入費率計費 — 沒有上游附加費。
- OpenAI/Gemini 模型:快取讀取是輸入費率 的 20%(供應商公布的比例)。
- 所有快取定價都反映 Brievio 的牌價 — 大約比 供應商的官方費率低 15%。所以在 Brievio 上一次 Sonnet 4.6 的快取讀取是
$3 × 0.95 × 0.10 = $0.285 per 1M tokens。比 未快取的輸入費率便宜約 10 倍。
什麼時候快取不是答案
有幾種情況,這份功夫不值得做:
- 短提示(總計 <1K 權杖)。額外開銷會 蓋過效益;就別費這個事了。
- 一次性任務,沒有重複流量。第一次呼叫 會稍微貴一點 — 快取只在第 2 次以後的呼叫才回本。
- 高輸出、低輸入的任務(創意寫作、 程式碼生成)。輸入本來就只佔帳單的一小部分。請改為 把重心放在輸出預算上限上。
至於其他所有情況 — RAG 聊天機器人、有固定工具目錄的代理、 在靜態評分標準上運行的分類器、few-shot 一致的結構化抽取流水線 — 快取都是你能在一個下午內就交付、投資報酬率最高的最佳化。 把它和 我們成本最佳化指南裡的另外四項技巧 搭配起來,在輸出品質完全不必妥協的前提下,降低 70% 的成本 是很實際的。
已經在用 Brievio 了嗎?打開 /app/usage,去看看你最大那個 模型的快取欄位。如果它是零,那你就是把錢留在桌上沒拿。 完整指南: /docs/caching。