🎁 新用戶 免費註冊,送 10 次呼叫,最高 $1,免綁卡。
Python LLM 提示詞快取:可直接執行的程式碼教學

Python LLM 提示詞快取:可直接執行的程式碼教學

目錄
  1. 0. 環境設定
  2. 1. 可觀察快取狀態的呼叫方式(所有供應商相同)
  3. 2. Anthropic Claude — 明確設定 cache_control 標記
  4. 3. OpenAI GPT-5.x — 自動快取
  5. 4. Google Gemini — 隱式快取
  6. 5. DeepSeek-v4-flash — 磁碟型自動快取
  7. 6. Alibaba Qwen — 有回報命中,但折扣不固定
  8. 7. 跨供應商基準測試(實測日期:2026-05-25)
  9. 8. 上線前檢查清單
  10. 9. 考量 TTL 的設計模式
  11. 8.1 綁定 Session 的工作負載(聊天、IDE 助理)
  12. 8.2 Batch / Cron 的 Heartbeat
  13. 8.3 冷儲存文件
  14. 10. 閘道實際提供的價值
  15. 常見問題

TL;DR — 一套 OpenAI SDK、一個 base_url,就能呼叫所有主流 LLM。本文數據來自 2026-05-25 在 Synthorai 正式閘道上的實測,使用約 7,300 個 token 的固定 system prompt。這個閘道的作用很單純:提供單一 endpoint、單一驗證 header,以及 usage.cost 欄位,省去自行維護各供應商價格表的工作。快取背後的 Transformer 原理請參閱第 1 篇:快取原理;各供應商的設計差異則整理在第 2 篇:供應商比較

系列文章:第 3 篇,共 5 篇 · 前文:第 1 篇 — 快取原理 · 第 2 篇 — 供應商比較與評估 · 下一篇:第 4 篇 — 依使用情境選擇最佳 LLM · 第 5 篇 — LangChain 整合


0. 環境設定

pip install openai
# common.py — reused across every example
import os, time
from openai import OpenAI

oai = OpenAI(
    api_key=os.environ["SYNTHORAI_KEY"],
    base_url="https://synthorai.io/v1",
)

不論後端模型是 GPT、Claude、Gemini、DeepSeek 還是 Qwen,閘道都使用 OpenAI 的 wire format。只要更換 model 欄位,不必更換 SDK。驗證方式為 Authorization: Bearer <key>

公開閘道上支援快取的模型 ID(2026-05 快照)包括:claude-haiku-4-5claude-sonnet-4-5 / 4-6claude-opus-4-5 / 4-6 / 4-7gpt-5.4-minigpt-5.4-nanogpt-5.2gpt-5.5-progemini-2.5-flashgemini-2.5-progemini-3.1-pro-previewdeepseek-v4-flashqwen3-maxqwen3.5-flash。完整的即時清單可透過 GET /v1/models 查詢。


1. 可觀察快取狀態的呼叫方式(所有供應商相同)

不需要額外啟用。只要上游模型支援提示詞快取,閘道就會直接傳回相關 metadata。以下兩個欄位可用來判斷快取結果:

resp = oai.chat.completions.create(
    model="gpt-5.4-mini",
    max_tokens=128,
    messages=[
        {"role": "system", "content": LONG_STABLE_PROMPT},   # ~7K tokens
        {"role": "user",   "content": "First question"},
    ],
)
print(resp.usage.prompt_tokens_details.cached_tokens)   # cache hit count
print(resp.usage.cost)                                  # USD, gateway-computed

cached_tokens 是命中上游 prefix cache 的輸入 token 數。usage.cost 則是閘道計算出的單次呼叫美元成本,不必在本機維護各供應商的費率表。

由快取架構衍生出的兩項原則,適用於所有供應商:

  1. 固定內容放前面,動態內容放後面。 Prefix 會從第 0 個 token 開始比對;開頭只要有一個 byte 不同,整段 prefix 就會失效。
  2. 不要把動態資料放進 system prompt。 目前時間、session ID 與 request UUID 都會使快取失效。

以下只是各供應商對同一模式的實作範例。


2. Anthropic Claude — 明確設定 cache_control 標記

Claude 屬於明確標記型。Anthropic API 不會自動快取;若要命中快取,必須在 systemmessages 陣列中設定最多四個 cache_control 斷點。讀取快取的費率約為一般輸入費率的 10%;寫入快取則為 125%,也就是多 25%。

透過閘道使用 cache_control,最直接的方式是採用官方 anthropic SDK,並將其指向閘道的 Anthropic 原生 endpoint。OpenAI 相容的 /chat/completions 路徑目前不會傳遞 cache_control 標記;Claude 快取必須使用 /v1/messages

import os
from anthropic import Anthropic

anth = Anthropic(
    api_key=os.environ["SYNTHORAI_KEY"],
    base_url="https://synthorai.io/",   # SDK appends /v1/messages
)

msg = anth.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=512,
    system=[
        {"type": "text", "text": SYSTEM_INSTRUCTIONS,
         "cache_control": {"type": "ephemeral"}},       # BP 1: never changes
        {"type": "text", "text": TOOL_DESCRIPTIONS,
         "cache_control": {"type": "ephemeral"}},       # BP 2: rarely changes
        {"type": "text", "text": RETRIEVED_DOCUMENTS},  # changes per call — not cached
    ],
    messages=[{"role": "user", "content": question}],
)

print(msg.usage)
# Usage(input_tokens=18, output_tokens=64,
#       cache_creation_input_tokens=0, cache_read_input_tokens=8123,
#       cost=...)

TTL 選項。 {"type": "ephemeral"} 預設採用 5 分鐘的滑動 TTL,每次命中都會延後到期時間。若工作負載的閒置間隔超過 5 分鐘,可在同一標記上指定 1 小時 TTL:

"cache_control": {"type": "ephemeral", "ttl": "1h"}

分層斷點。 最多四個標記,可分別快取「永遠不變」、「很少變動」與「每項任務變動」的內容。對 prompt 各區段更新頻率不同的 agent 與 RAG 工作負載來說,這是目前最完整的設計。即使最後一層(例如檢索出的文件)每次呼叫都不同,前面的分層仍可命中。

模型選擇。 截至 2026-05,閘道提供的 Claude ID 包括 claude-haiku-4-5claude-sonnet-4-5 / 4-6claude-opus-4-5 / 4-6 / 4-7。Haiku 適合低成本聊天;Sonnet 適合一般用途,並提供最強的 agent 快取模式;Opus 則用於最困難的推理任務。

實測快取命中、寫入與未快取參考數據(2026-05-25,約 7,976 個 token 的 system prompt,max_tokens=64):

模型快取寫入快取讀取未快取參考讀取折扣命中 TTFT(串流)
claude-haiku-4-5$0.00916$0.00086$0.00725−88%1.31 s
claude-sonnet-4-5$0.02713$0.00247$0.02175−89%1.76 s
claude-sonnet-4-6$0.02736$0.00253$0.02198−88%1.81 s
claude-opus-4-5$0.04522$0.00409$0.03624−89%2.08 s
claude-opus-4-6$0.04522$0.00411$0.03625−89%2.55 s
claude-opus-4-7$0.06545$0.00609$0.05259−88%2.30 s

整個系列的折扣幅度都很一致。寫入費用約比未快取高 25%,符合 Anthropic 公布的費率;命中一次即可回本。


3. OpenAI GPT-5.x — 自動快取

只要 request 的 prefix 夠長,OpenAI 就會自動快取。不需要修改程式碼,也不用加標記。

def ask_gpt(question: str):
    t0 = time.perf_counter()
    resp = oai.chat.completions.create(
        model="gpt-5.4-mini",
        max_tokens=64,
        messages=[
            {"role": "system", "content": LONG_STABLE_PROMPT},
            {"role": "user",   "content": question},
        ],
    )
    return resp, time.perf_counter() - t0

r1, t1 = ask_gpt("Which export formats are supported?")
r2, t2 = ask_gpt("How long is the refund window for annual plans?")

print(t1, r1.usage.prompt_tokens_details.cached_tokens, r1.usage.cost)
# 3.63   0       0.00267
print(t2, r2.usage.prompt_tokens_details.cached_tokens, r2.usage.cost)
# 1.23   6400    0.00257

同一段 6,887-token prompt 連續呼叫兩次。第二次呼叫有 93% 的 system prompt 命中快取,總延遲從 3.6 s 降至 1.2 s。此處成本變化不大,因為快取折扣被第一次呼叫較長的 completion 抵銷;§7 提供了更適合跨供應商比較的數據。

gpt-5.4-nano 的折扣更明顯,命中時成本降低 44%。如果聊天 UI 只在意 time-to-first-token,應以串流數據為準:

def ttft(model, question):
    t0 = time.perf_counter()
    stream = oai.chat.completions.create(
        model=model, max_tokens=64,
        messages=[
            {"role": "system", "content": LONG_STABLE_PROMPT},
            {"role": "user",   "content": question},
        ],
        stream=True, stream_options={"include_usage": True},
    )
    for ev in stream:
        if ev.choices and ev.choices[0].delta and ev.choices[0].delta.content:
            return time.perf_counter() - t0     # first content token

快取命中時的實測 TTFT:gpt-5.4-mini0.73 sgpt-5.4-nano1.00 s


4. Google Gemini — 隱式快取

透過閘道呼叫 Gemini 時,快取同樣會自動運作,不需要先建立 cachedContent

r = oai.chat.completions.create(
    model="gemini-2.5-flash",
    max_tokens=128,
    messages=[
        {"role": "system", "content": LONG_STABLE_PROMPT},
        {"role": "user",   "content": "Summarize section 6 in two bullets."},
    ],
)
print(r.usage.prompt_tokens_details.cached_tokens, r.usage.cost)

使用約 7,300 個 token 的 system prompt 測試 gemini-2.5-flash,命中結果為:7,140 個 cached token(97%),成本從 $0.00198 降至 $0.00024,該次呼叫節省 88%

兩個需要注意的問題

  • Gemini 的 *-pro 變體是推理模型。max_tokens 設得太小時,常會看到 completion_tokens=0,因為額度都被隱藏的思考過程用完了。面向使用者的功能應將 max_tokens 提高至 ≥256。
  • 隱式快取的 TTL 很短,官方也未明確公布。在我們的測試中,兩次呼叫相隔 5 s 可以命中;約 10 s 後的第三次呼叫有時會 miss。不要把業務邏輯建立在必定命中的假設上。應檢查 cached_tokens,並在 miss 時正常降級。

5. DeepSeek-v4-flash — 磁碟型自動快取

DeepSeek 的自動快取比其他供應商常見的 GPU 記憶體快取保存得更久。呼叫方式不變:

r1 = oai.chat.completions.create(
    model="deepseek-v4-flash", max_tokens=128,
    messages=[{"role": "system", "content": LONG_STABLE_PROMPT},
              {"role": "user",   "content": "Q1"}],
)
# r1.usage.cost = $0.00091, cached_tokens = 0

r2 = oai.chat.completions.create(
    model="deepseek-v4-flash", max_tokens=128,
    messages=[{"role": "system", "content": LONG_STABLE_PROMPT},
              {"role": "user",   "content": "Q2"}],
)
# r2.usage.cost = $0.00023, cached_tokens = 6784  →  74% saved

快取命中時的串流 TTFT 為 2.93 s。DeepSeek 並不是這組模型中延遲最低的選擇,優勢在於成本,以及快取能在相隔數小時後仍保持可用。


6. Alibaba Qwen — 有回報命中,但折扣不固定

r = oai.chat.completions.create(
    model="qwen3-max", max_tokens=128,
    messages=[{"role": "system", "content": LONG_STABLE_PROMPT},
              {"role": "user",   "content": "Q1"}],
)
print(r.usage.prompt_tokens_details.cached_tokens, r.usage.cost)
# 7040    0.00549

本次測試有一個限制:cached_tokens 回報命中快取(7,040 / 7,234 = 97%),但命中後的 usage.cost 並未下降,仍約為 $0.0055。這表示上游確實命中快取,TTFT 也從 cold 狀態的 3.03 s 降至 1.53 s,但在測試當天,閘道針對此供應商回傳的成本欄位尚未反映快取折扣。若 Qwen 成本是重要考量,請監控 cached_tokens,並暫時以上游定價頁面為準,直到成本數據恢復一致。


7. 跨供應商基準測試(實測日期:2026-05-25)

單次連續測試。固定 system prompt 長度為 7,284 個字元,依 tokenizer 不同約為 6,900–7,300 個 token。max_tokens=64。先執行一次 miss,接著立即執行一次 hit。

以下為自動快取的供應商,不需要標記:

模型Miss 成本Hit 成本成本 ΔMiss 總時間Hit 總時間Hit TTFT(串流)快取命中率
gpt-5.4-nano$0.00131$0.00074−44%2.18 s1.48 s1.00 s5,888 / 6,887 (85%)
gpt-5.4-mini$0.00267$0.00257−4%*3.63 s1.23 s0.73 s6,400 / 6,887 (93%)
gemini-2.5-flash$0.00198$0.00024†−88%2.49 s1.37 s不適用‡7,140 / 7,322 (97%)
gemini-2.5-pro$0.00824$0.00205†−75%2.99 s1.76 s不適用‡6,120 / 7,328 (84%)
deepseek-v4-flash$0.00091$0.00023−74%4.02 s3.71 s2.93 s6,784 / 7,101 (96%)
qwen3-max$0.00553$0.00549−1%§4.80 s2.37 s1.53 s7,040 / 7,234 (97%)

* gpt-5.4-mini 的 miss completion 為 44 個 token,hit 則為 19 個,因此成本差異同時受快取折扣與 completion 長度影響。延遲從 3.63 s 降至 1.23 s,是較明確的指標。 † 這是回報 cached_tokens 的串流呼叫成本;Gemini 的非串流呼叫偶爾會回傳 cached_tokens=null,且成本不會下降。目前閘道的 Gemini metadata 並不一致;有 cached_tokens 時應以該欄位為準。 ‡ Gemini *-pro / *-flash 推理模型在 max_tokens 較小時,常不會輸出任何內容 token,因此該額度下的 TTFT 沒有意義。若要在正式環境量測,請提高 max_tokens。 § 請參閱 §6。上游確實命中快取,延遲也有下降,但測試當天閘道的 qwen3-max usage.cost 欄位並未反映折扣。

Anthropic Claude 採用明確標記,必須透過 cache_control 選擇啟用折扣,因此數據另列一表。實作方式請參閱 §2。以下使用相同 prompt,比較實測快取寫入與讀取:

模型寫入成本讀取成本讀取折扣命中 TTFT(串流)
claude-haiku-4-5$0.00916$0.00086−88%1.31 s
claude-sonnet-4-5$0.02713$0.00247−89%1.76 s
claude-sonnet-4-6$0.02736$0.00253−88%1.81 s
claude-opus-4-5$0.04522$0.00409−89%2.08 s
claude-opus-4-6$0.04522$0.00411−89%2.55 s
claude-opus-4-7$0.06545$0.00609−88%2.30 s

實際數據會隨區域、時段,以及其他租戶的 prefix 是否已在快取中而改變。這只是單次、單日的測試結果,不應視為絕對的效能基準。


8. 上線前檢查清單

上線使用快取的 prompt 前,請確認以下事項:

  1. 固定內容放前面 — system prompt、知識庫、工具 schema 放在 messages 頂端。
  2. 動態內容放後面 — 使用者輸入、檢索文件與時間戳記放在底部。
  3. 不要在 system 放動態變數 — 目前時間、使用者 ID 與隨機種子都會使 prefix 失效。
  4. 每次呼叫都記錄 cached_tokens 如果正式環境的命中率低於 50%,代表 prefix 並不穩定。應檢查未命中的 prompt。
  5. 不要只測一次命中。 TTL 很短;設計時應假設 hit_rate ∈ [0, 1),而不是「一定命中」。

9. 考量 TTL 的設計模式

正式環境最常見的失敗原因不是「忘了開啟快取」,而是「request 根本沒有在 TTL 內到達,所以命中率只有 12%」。

8.1 綁定 Session 的工作負載(聊天、IDE 助理)

這類工作負載的自然呼叫頻率通常遠短於 TTL。只要 prompt 結構正確,快取就會自行維持 warm 狀態,不需要額外設計。

8.2 Batch / Cron 的 Heartbeat

假設每日上午 09:00 執行報表,在 3 分鐘內呼叫模型 50 次。由於快取經過一夜後已是 cold 狀態,09:00 的第一次快取寫入會形成額外成本。可從 08:55 開始,每隔 TTL/2 使用相同 prefix 傳送一次 1-token 的「ping」,保持快取 warm:

def keepalive():
    oai.chat.completions.create(
        model="gpt-5.4-mini",
        max_tokens=1,
        messages=[
            {"role": "system", "content": LONG_STABLE_PROMPT},
            {"role": "user",   "content": "."},
        ],
    )

每次 ping 的成本是輸入 token 數乘以快取費率。以 gpt-5.4-mini 和本文的 7K-token prefix 為例,約為 $0.0026,遠低於讓 batch job 的前 50 次實際呼叫都支付完整 prefill 成本。

8.3 冷儲存文件

如果文件查詢頻率不高,例如整天每小時查詢一次,記憶體內快取大多會處於 cold 狀態。截至本文撰寫時,閘道尚未提供代管的明確快取建立 endpoint。若需要較長 TTL,可使用 deepseek-v4-flash,其磁碟型快取在實測中能跨越數小時間隔;或者不經閘道,直接呼叫 Google 原生的 cachedContent API。


10. 閘道實際提供的價值

聲稱閘道會「替你處理快取」並不準確。快取發生在模型層,閘道只是把現有資訊暴露出來。與分別使用各供應商的原生 SDK 相比,閘道實際增加了三項能力:

  1. 一個 base_url、一個驗證 header,呼叫所有模型。 只要更換 model 欄位,呼叫格式完全不變。messages 陣列相同,usage 欄位結構也相同,不必為五個供應商維護五套 SDK。
  2. 每次呼叫都回傳美元計價的 usage.cost 閘道依目前的上游費率計算成本,並加入每次 response。程式碼不必自行維護價格表,也不用訂閱各供應商的價格變動通知。
  3. 統一的 cached_tokens 欄位。 Anthropic 使用 cache_read_input_tokens 回報快取命中,OpenAI 使用 prompt_tokens_details.cached_tokens,DeepSeek 則使用 prompt_cache_hit_tokens。閘道會統一轉換成 OpenAI 格式,因此 observability 程式碼不必依供應商分支處理。

這就是閘道的完整價值。至於何時該快取、如何安排 prompt 結構,以及該選哪個模型,會在下一篇處理。


下一篇第 4 篇 — 如何依使用情境選擇最佳 LLM:聊天、API 與 AI Agent — 透過決策矩陣,依工作負載選出最合適的模型與快取策略,並附上成本計算。


常見問題

為什麼要用 OpenAI SDK 呼叫非 OpenAI 模型? 閘道對所有供應商都使用 OpenAI 的 wire format。官方 openai SDK 提供型別化 response、自動重試與串流 helper,沒有必要自行實作五套 HTTP client。

串流 response 也支援快取嗎? 支援。傳入 stream_options={"include_usage": True} 後,最後一個 chunk 的 usage 物件會回報快取命中數。串流最能反映延遲改善,因為使用者實際感受到的是 TTFT。

對我的工作負載而言,哪個供應商的快取折扣最大? 依 2026-05 的價格,若命中率達 70% 以上,§7 表格中的 gemini-2.5-flashdeepseek-v4-flash 成本最低;gpt-5.4-mini 的 TTFT 最短。Claude 官方公布的快取折扣為 90%,需要設定最多四個 cache_control 斷點,詳見 §2。應使用自己的 prompt 執行相同測試;這只需一天,不必進行數週的遷移。

什麼時候需要 cache_control 標記? 只有呼叫 Anthropic Claude 時需要,詳見 §2。OpenAI、Gemini、DeepSeek 與 Qwen 的上游都會自動快取足夠長的 prefix,因此不需要標記;對這些供應商傳入該欄位時,會被直接忽略。

這些數據有多新? 數據於 2026-05-25 在公開閘道上實測。請將其視為單一資料點;價格與延遲會隨每次 release cycle 改變。

Anthropic Claude 呢? 閘道支援使用明確 cache_control 標記的 Claude。請搭配 anthropic SDK,並設定 base_url="https://synthorai.io/",SDK 會自動加上 /v1/messages。OpenAI 相容的 /chat/completions 路徑目前不會傳遞這些標記;若要使用 Claude 快取,請採用 §2 所示的 Anthropic 原生路徑。


來源與驗證:所有數據皆於 2026-05-25 使用 openai SDK 2.38.0,針對 https://synthorai.io/v1 實測。供應商定價頁面:Anthropic 提示詞快取 · OpenAI 提示詞快取 · Google Gemini 上下文快取 · DeepSeek KV 快取指南 · Alibaba Bailian 上下文快取

← 返回部落格