Prompt Caching 2026: Anthropic vs OpenAI vs Gemini — So Sánh Production
So sánh prompt caching 3 nhà cung cấp LLM lớn năm 2026: Anthropic cache_control, OpenAI auto-cache, Gemini CachedContent. Kèm code Python, công thức tính cost, và dashboard monitoring tối thiểu cho production.
Prompt caching là cơ chế của nhà cung cấp LLM cho phép tái sử dụng phần tiền tố (prefix) đã được xử lý sẵn giữa các request, giúp giảm cost input token từ 50% đến 90% và cắt time-to-first-token (TTFT) tới 85% cho các workflow có prompt lặp lại như agent, RAG dài, và system prompt cồng kềnh. Trong năm 2026, ba nhà cung cấp lớn (Anthropic, OpenAI và Google Gemini) đã hội tụ về ý tưởng chung, nhưng cách bật, tính phí, và TTL của mỗi bên khác nhau rõ rệt. Bài viết này là bản so sánh dựa trên thực tế production, kèm code Python chạy được và dashboard tối thiểu mà bạn nên có trước khi rollout.
OpenAI bật cache tự động cho prompt ≥ 1,024 tokens trên gpt-4o, gpt-4o-mini, o1 và o3; không phải cấu hình, cache-hit token được giảm 50%, cache TTL 5–10 phút và tối đa 1 giờ khi off-peak.
Gemini dùng mô hình CachedContent tường minh: bạn tạo cache resource, đặt TTL (mặc định 1 giờ), rồi trả về cache.name ở mỗi request; giảm ~75% giá input cho phần đã cache, tối thiểu 4,096 tokens (Flash) hoặc 32,768 (Pro).
Anthropic tính phụ phí ghi cache (1.25x giá input cho 5m, 2x cho 1h) nhưng đọc cache rẻ 90%; OpenAI không tính phụ phí ghi, đọc giảm 50%; Gemini tính phí lưu trữ theo giờ (không phải per-token đọc rẻ đi).
Sắp xếp prompt theo thứ tự static trước, dynamic sau (system prompt, tools, docs trước, user query sau). Bất kỳ thay đổi byte-level nào ở prefix cũng làm invalidate toàn bộ cache đằng sau nó.
Phải log cache_creation_input_tokens, cache_read_input_tokens, hit rate, và cost delta trong dashboard. Không đo thì không biết cache có thực sự hit hay bạn đang trả tiền ghi hai lần.
Prompt caching là gì và hoạt động thế nào?
Prompt caching là kỹ thuật cache phía server của nhà cung cấp LLM, không phải cache phía client. Khi bạn gửi một request với prefix đã từng xử lý trước đó, nhà cung cấp bỏ qua bước tính KV-cache attention cho phần prefix đó và tái sử dụng state đã lưu trên GPU. Kết quả là: chi phí input token cho phần cache-hit giảm mạnh (50%–90% tùy nhà cung cấp), và TTFT giảm 30%–85% vì mô hình không phải re-prefill.
Có ba trục thiết kế phân biệt implementation của ba nhà cung cấp. Thứ nhất, explicit vs automatic: Anthropic và Gemini yêu cầu bạn đánh dấu tường minh, còn OpenAI thì tự động hóa. Thứ hai, TTL và giá lưu trữ: có bên là 5 phút, có bên là 1 giờ, có bên tính phí theo giờ. Thứ ba, ngưỡng token tối thiểu: thấp nhất là 1,024 (OpenAI, Anthropic Sonnet), cao nhất là 32,768 (Gemini 2.5 Pro).
Cache chỉ khớp theo prefix chính xác từ byte đầu tiên. Thay đổi một dấu cách ở system prompt cũng đủ làm miss toàn bộ cache của mọi tool và document đi sau. Cache đọc song song có hoạt động (nhiều concurrent request cùng prefix sẽ cùng hit), nhưng khi TTL hết, request đầu tiên phải trả phí ghi lại. Đây là lý do bạn cần phân bổ traffic sao cho cache luôn "ấm", không để cửa sổ chết dài hơn TTL.
Điểm cần chú ý: Anthropic có chi phí đọc rẻ nhất nhưng phải trả phụ phí ghi, phù hợp workflow có cache-hit rate cao và ổn định. OpenAI đơn giản nhất (không cần code) nhưng discount thấp hơn. Gemini rẻ khi bạn dùng cache rất nhiều lần trong khoảng lưu trữ đã trả phí (ví dụ RAG với 500K token context được query hàng nghìn lần trong 1 giờ).
Anthropic Prompt Caching: cách setup cache_control
Anthropic yêu cầu bạn đánh dấu các breakpoints bằng cache_control. Tối đa 4 breakpoints mỗi request, mỗi breakpoint bao trùm toàn bộ nội dung trước nó. Thứ tự khuyến nghị: system prompt, tools, documents, conversation history, và user message cuối cùng. Đặt breakpoint sau mỗi cụm ổn định, đừng đặt sau nội dung động.
from anthropic import Anthropic
client = Anthropic()
SYSTEM_PROMPT = "Bạn là AI operations engineer. Trả lời ngắn gọn, có dẫn chứng."
# Tài liệu lớn ít thay đổi, ứng viên hoàn hảo cho cache
RAG_CONTEXT = open("/data/kb/full_manual.md").read() # ~40,000 tokens
response = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
system=[
{
"type": "text",
"text": SYSTEM_PROMPT,
},
{
"type": "text",
"text": RAG_CONTEXT,
# Breakpoint: cache toàn bộ system + RAG_CONTEXT ở trên
"cache_control": {"type": "ephemeral"},
},
],
messages=[
{"role": "user", "content": "Cache hit rate hiện tại bao nhiêu?"}
],
)
usage = response.usage
print(f"cache_creation_input_tokens: {usage.cache_creation_input_tokens}")
print(f"cache_read_input_tokens: {usage.cache_read_input_tokens}")
print(f"input_tokens (uncached): {usage.input_tokens}")
Lần gọi đầu tiên bạn sẽ thấy cache_creation_input_tokens ≈ 40,000 và trả phí 1.25x. Từ request thứ hai trở đi (trong 5 phút), cache_read_input_tokens ≈ 40,000 với phí 0.1x, tiết kiệm khoảng 90% trên phần cache. Để dùng TTL 1 giờ, thêm "ttl": "1h" vào cache_control (yêu cầu bật extended caching trên tài khoản).
Cẩn thận: nếu chèn thêm 1 ký tự vào system prompt, breakpoint đằng sau sẽ miss hoàn toàn. Tôi đã đụng bug này khi ship một agent nội bộ, chỉ vì team thêm timestamp vào system prompt cho "debug". Cost tháng đó tăng gấp 4 lần trước khi ai đó nhận ra. Đây là footgun số một tôi thấy trong review production.
OpenAI Automatic Caching: không cần cấu hình, nhưng…
OpenAI bật cache tự động cho mọi prompt ≥ 1,024 tokens trên các model gpt-4o, gpt-4o-mini, gpt-4.1, o1-preview, o1-mini, o3, o3-mini. Bạn không thêm gì trong request, hệ thống tự phát hiện prefix trùng khớp và trả về cached_tokens trong trường usage. Nghe hay, nhưng thật ra có ba caveat quan trọng.
Caveat 1: cache OpenAI chỉ khớp theo chunk 128 tokens, nên phần cuối prefix có thể bị lệch chunk và không hit. Caveat 2: TTL biến động 5 đến 10 phút giờ cao điểm, tối đa khoảng 1 giờ off-peak, không có SLA. Caveat 3: bạn không kiểm soát được thứ tự đặt content ngoài việc để static content lên đầu. Nếu bạn đặt RAG_CONTEXT sau user message (tôi từng thấy pattern này để "spotlight" context trong một pull request nội bộ), cache miss 100%. Luôn đưa static content lên trước.
Gemini Context Caching: CachedContent API
Gemini theo mô hình resource-oriented: bạn tạo một CachedContent object trên server, nhận về một name (dạng cachedContents/abc123), rồi truyền tên đó vào các request tiếp theo. TTL cấu hình được (mặc định 1 giờ), và bạn trả phí lưu trữ theo giờ chứ không phải theo đọc.
from google import genai
from google.genai import types
import datetime
client = genai.Client()
# Bước 1: tạo cache resource một lần
cache = client.caches.create(
model="gemini-2.5-pro",
config=types.CreateCachedContentConfig(
display_name="rag-knowledge-base-v1",
system_instruction="Bạn là AI operations engineer...",
contents=[open("/data/kb/full_manual.md").read()], # ≥ 32,768 tokens
ttl=datetime.timedelta(hours=2),
),
)
print(f"Cached: {cache.name}, tokens: {cache.usage_metadata.total_token_count}")
# Bước 2: mọi request tiếp theo trong 2h dùng cached_content
resp = client.models.generate_content(
model="gemini-2.5-pro",
contents="Cache hit rate hiện tại bao nhiêu?",
config=types.GenerateContentConfig(cached_content=cache.name),
)
meta = resp.usage_metadata
print(f"cached_content_token_count: {meta.cached_content_token_count}")
print(f"prompt_token_count: {meta.prompt_token_count}")
Gemini phù hợp cho use case fat context RAG hoặc video/audio đã chunk sẵn (Gemini hỗ trợ cache đa modal). Điểm mạnh: bạn kiểm soát TTL và có thể update hoặc delete cache tường minh qua API (client.caches.update, client.caches.delete). Điểm yếu: ngưỡng 32,768 tokens của Pro model loại bỏ nhiều use case agent tool prompt nhỏ. Nếu prompt của bạn dưới ngưỡng, cache sẽ trả lỗi INVALID_ARGUMENT.
Khi nào nên dùng prompt caching và khi nào không?
Prompt caching mang lại giá trị lớn nhất khi bạn có prefix ổn định và tần suất request cao. Các use case điển hình:
RAG với knowledge base cố định: nạp toàn bộ chương manual, spec, hoặc code base vào cache; user query thay đổi ở đuôi. Có thể tiết kiệm 70 đến 90% cost input.
Agent với tool prompt cồng kềnh: hệ thống 15 đến 30 tool definitions dễ vượt 5,000 tokens; cache chúng để mỗi vòng agent loop chỉ trả phí đọc.
Few-shot prompting với exemplars nặng: 20 ví dụ chi tiết cho classification/extraction có thể vượt 10,000 tokens; cache toàn bộ block exemplars.
Conversation dài đã compact: đặt cache breakpoint sau phần history đã summary hóa, để mỗi turn mới chỉ tính phí trên user message và assistant response.
Còn khi nào KHÔNG nên dùng cache? Prompt của bạn dưới ngưỡng tối thiểu (dưới 1,024 tokens ở Anthropic/OpenAI). Traffic quá thấp (dưới 1 request/phút thì cache TTL 5 phút sẽ expire hầu hết). Hoặc prefix thay đổi mỗi request (personalization ở đầu prompt là anti-pattern kinh điển). Với các use case dynamic-first, bạn tốn phí ghi cache mà không bao giờ đọc lại, đây là kịch bản "lỗ đôi" mà không có dashboard bạn sẽ không thấy.
Breakeven của Anthropic là N ≥ 2 (nghĩa là phải có ít nhất 1 cache hit trong 5 phút mới có lời). Với OpenAI, breakeven là N = 1 vì không có phụ phí ghi, mọi cache hit đều lãi ròng 50%. Với Gemini, cần tính thêm phí lưu trữ theo giờ (khoảng $1.00/M tokens/giờ với Pro tại thời điểm viết); công thức thay đổi thành:
Nguyên tắc của tôi: nếu bạn không chắc có nhiều hit hay không, thử cache một tuần trên 5% traffic, đo cached_tokens / total_input_tokens, rồi so sánh với cost baseline. Nếu hit rate dưới 40%, gỡ cache hoặc restructure prompt. Tham khảo thêm phần đánh giá và metric ở bài đánh giá RAG với RAGAS và DeepEval để tích hợp cache metric vào eval harness. Nếu bạn đang chọn giữa function calling và structured outputs cho tool layer, bài so sánh function calling và structured outputs có thêm gợi ý về cách cache tool schema.
Dashboard tối thiểu để monitor prompt caching production
Đây là dashboard tôi luôn build trước khi rollout cache lên traffic thật. Tối thiểu 6 tile, refresh mỗi phút:
Cache hit rate = cache_read_tokens / (cache_read_tokens + cache_creation_tokens + uncached_input_tokens). Mục tiêu trên 60% sau tuần đầu.
Cost delta ($/giờ) = cost_uncached_baseline − cost_actual. Vẽ line chart 7 ngày; nếu delta âm liên tục 24h thì cache đang lỗ, rollback ngay.
TTFT p50/p95/p99 tách theo cache_hit vs cache_miss. Hit thường nhanh hơn miss 2 đến 5 lần; nếu không thấy chênh, cache không thực sự hit.
Cache creation tokens/giờ. Nếu tăng vọt bất thường, có thể prefix bị invalidate do bug (thay đổi whitespace, timestamp trong system prompt…).
Số request per cached prefix (histogram). Phân phối lệch phải là tốt (nhiều request hit cùng prefix); phân phối phẳng nghĩa là mỗi request có prefix riêng, gỡ cache.
Error rate của cache API. Gemini có thể trả NOT_FOUND nếu cache expired trước khi request tới; log để tự động fallback tạo cache mới.
Log dưới dạng structured JSON để filter cho dễ. Trường bắt buộc: request_id, model, provider, cache_creation_tokens, cache_read_tokens, uncached_input_tokens, output_tokens, ttft_ms, total_latency_ms. Tôi push mọi request qua middleware Python asyncio và ghi ra ClickHouse cho query nhanh. Với setup này, sau 24 giờ tôi có thể trả lời câu hỏi "cache đã tiết kiệm bao nhiêu $ hôm nay?" trong 300ms, thứ mà không có sẽ khiến bạn đoán mò khi CFO hỏi.
Câu hỏi thường gặp
Prompt caching có giữ nguyên chất lượng output không?
Có. Cache tái sử dụng KV-cache attention state đã tính, không thay đổi output logits. Output với cache hit và không cache là bit-identical ở cùng seed và temperature=0. Nếu bạn thấy khác biệt, đó là do non-determinism của inference chứ không phải do caching.
Anthropic prompt caching có tính phụ phí không?
Có, nhưng chỉ ở bước ghi cache: 1.25x giá input token cho TTL 5 phút, 2x cho TTL 1 giờ. Bước đọc cache rẻ hơn 90% (0.1x giá input). Nghĩa là bạn cần ít nhất 2 cache hit trong TTL để có lời so với không cache.
OpenAI prompt caching có cần code thêm gì không?
Không cần cấu hình gì. Cache tự động bật cho prompt ≥ 1,024 tokens trên gpt-4o, gpt-4o-mini, o1, o3. Đảm bảo static content (system prompt, RAG context) nằm ở đầu prompt và không thay đổi giữa các request. Kiểm tra usage.prompt_tokens_details.cached_tokens để biết có hit hay không.
Gemini context caching khác gì với prompt caching thông thường?
Gemini dùng mô hình resource: bạn tạo CachedContent object có TTL, nhận về name, rồi truyền vào request. Bạn trả phí lưu trữ theo giờ (khoảng $1/M tokens/giờ với Pro) chứ không phải phí đọc rẻ hơn. Phù hợp cho fat context 100K+ tokens được query nhiều lần trong 1 đến 24 giờ.
Làm sao monitor cache hit rate cho LLM production?
Log cache_read_input_tokens, cache_creation_input_tokens, và input_tokens (uncached) từ mỗi response vào structured logging (ClickHouse, BigQuery, hoặc Postgres). Tính hit rate = read / (read + creation + uncached). Vẽ dashboard với TTFT tách theo hit/miss để phát hiện anomaly.
Có thể dùng prompt caching với streaming không?
Có, cả ba nhà cung cấp đều hỗ trợ cache với streaming response. Metric usage (cache_read_tokens, v.v.) được trả về ở event cuối của stream. Nhớ tổng hợp usage sau khi stream kết thúc, đừng cố lấy giữa chừng.
So sánh LangGraph 0.3, CrewAI 0.86 và AutoGen 0.4 trên các tiêu chí thực chiến: state management, human-in-the-loop, chi phí token, observability. Kèm benchmark thực tế 500 email hỗ trợ khách hàng và khuyến nghị theo từng use case production.
Function Calling và Structured Outputs khác nhau ở ngữ nghĩa và cost. Bài viết chia nhỏ cả hai theo hướng schema-first, đánh giá trước deploy, và ghi nhận khác biệt OpenAI vs Anthropic Claude.