Prompt Caching deep — kỹ thuật giảm 90% phí AI mà ít dev biết tận dụng

Anthropic prompt caching launch tháng 8/2024 — cache prefix tĩnh, request thứ 2 chỉ tính 10% giá input. Hiểu 4 cache breakpoint, TTL 5 phút vs 1 giờ, hit rate optimization, pitfalls phổ biến để tận dụng max saving 80-95% cho production AI app.

11 phút đọcCập nhật 2026-05-23
Nghe bài viết
Để Claude đọc bài cho bạn — vừa nghe vừa làm việc khác
Mục lục bài viết(32)
Sơ đồ memory hierarchy — concept cache layers từ CPU register tới disk

Memory hierarchy trong máy tính — register (nhanh nhất, đắt nhất) → L1/L2/L3 cache → RAM → SSD → HDD. Prompt caching trong LLM follow concept tương tự: cache intermediate attention state ở server, request lặp lại re-use → giảm 90% compute. Saving compound khi volume scale — production app có thể tiết kiệm $1000s/tháng từ caching đúng cách. Nguồn: Wikimedia Commons (CC BY-SA 4.0).

Hiểu đơn giản nhất

Bạn build AI chatbot. System prompt 5000 token (boilerplate, instruction, brand voice). Mỗi user query, gửi full system prompt + user message → AI process.

Không caching:

Request 1: process 5000 system + 200 user → cost $0.0165
Request 2: process 5000 system + 200 user → cost $0.0165 (lại process)
Request 3: process 5000 system + 200 user → cost $0.0165
...
Request 1000: total $16.50

5000 token cùng nhau process 1000 lần = waste compute.

Với prompt caching:

Request 1: process 5000 system + 200 user → cache 5000 → cost $0.021 (1.25x write)
Request 2: 5000 cached, only 200 user new → cost $0.003 (only user paid full)
Request 3: same as request 2 → cost $0.003
...
Request 1000: total $3.02 (vs $16.50 no cache) = save 82%

5000 token process 1 lần, reused 999 lần.

Cách hoạt động

LLM dùng "attention mechanism" tính relationship giữa token. Tính 5000 token là expensive (O(n²) complexity). Caching = lưu intermediate attention state ở server. Request sau:

  1. Server check hash của prefix
  2. Nếu match cache → load intermediate state → skip recompute
  3. Chỉ process token mới (user message, sau breakpoint)
  4. Bill 10% giá normal cho cached portion
Phần promptNo cache costCached cost
Write cache (lần 1)1.0x base input1.25x base input
Cache read (lần 2+)1.0x base input0.1x base input
Output1.0x base output1.0x base output (unchanged)

Saving 90% on cached portion. Net 80-85% with write overhead.

Tại sao bạn cần biết

  • AI bill production blow up khi scale. 1000 user/ngày × system prompt 5000 token = $200/ngày = $6000/tháng. Caching = $1000/tháng. Diff $5000/tháng = $60k/năm.
  • Setup chỉ 1 flag trong code. cache_control: { type: "ephemeral" } — 5 dòng config saves 80%.
  • OpenAI auto-caching nhưng saving lower. Anthropic explicit caching cho higher control + higher saving.
  • Critical cho RAG. RAG inject 10-50k context mỗi query → caching RAG context = massive saving.
  • Tool use definitions cũng cache-able. 30+ tool defs (5-10k token) cached → save substantial cho agent app.

4 Cache breakpoint patterns

Pattern 1: System prompt only

Simplest setup:

const message = await client.messages.create({
  model: "claude-sonnet-4-5",
  system: [
    {
      type: "text",
      text: longSystemPrompt,  // 5000 token boilerplate
      cache_control: { type: "ephemeral" }
    }
  ],
  messages: [{ role: "user", content: "Hello" }]
});

System cached, messages variable per request. Saving 90% on system token.

Pattern 2: System + Tool definitions

Agent với many tools:

const message = await client.messages.create({
  system: [
    { type: "text", text: systemPrompt, cache_control: { type: "ephemeral" } }
  ],
  tools: [
    { name: "tool1", ..., cache_control: { type: "ephemeral" } },
    { name: "tool2", ... },
    // ... 30 more tools
  ],
  messages: [...]
});

System + tools both cached (2 breakpoint). Tool definitions don't change between requests — perfect cache candidate.

Pattern 3: System + RAG context

RAG chatbot:

const message = await client.messages.create({
  system: [
    { type: "text", text: systemPrompt, cache_control: { type: "ephemeral" } }
  ],
  messages: [
    {
      role: "user",
      content: [
        {
          type: "text",
          text: ragContext,  // 30k token retrieved docs
          cache_control: { type: "ephemeral" }
        },
        { type: "text", text: userQuery }
      ]
    }
  ]
});

3 breakpoint: system + RAG context + user query. RAG context retrieved fresh nhưng same retrieval pattern over 5 phút → cached.

Pattern 4: Multi-turn conversation

Long chat:

const message = await client.messages.create({
  system: [{ type: "text", text: systemPrompt, cache_control: { type: "ephemeral" } }],
  messages: [
    { role: "user", content: "Turn 1 query" },
    { role: "assistant", content: "Turn 1 response" },
    { role: "user", content: "Turn 2 query" },
    { role: "assistant", content: "Turn 2 response", cache_control: { type: "ephemeral" } },
    // ... cached up to turn 2
    { role: "user", content: "Turn 3 query" }  // New, not cached
  ]
});

Cache up to specific turn. Turn N+1 reads cache, chỉ process turn mới.

TTL — 5 phút vs 1 giờ extended

Default ephemeral (5 phút)

cache_control: { type: "ephemeral" }
  • TTL 5 phút sau last access
  • Cost write: 1.25x base
  • Free
  • Fit: chatbot real-time (user gửi liên tục)

Extended 1 giờ (Claude 3.5+)

cache_control: { type: "ephemeral", ttl: "1h" }
  • TTL 1 giờ
  • Cost write: 2x base
  • Fit: batch processing, eval, scheduled task

Quyết định

Request frequency > TTL → cache hit
Request frequency < TTL → cache miss (waste write cost)

5 phút TTL:
  - User chat 1 query / 30s-2min → hit good ✓
  - Cron job mỗi giờ → miss ✗

1 giờ TTL:
  - Cron job mỗi 30 phút → hit ✓
  - Daily batch → miss ✗ (consider không cache)

Hit Rate optimization — 7 tactic

Tactic 1: Move dynamic out of cache portion

// BAD: dynamic content trong system → invalidate cache
system: `You are bot. Current time: ${new Date()}. User: ${userId}.`
 
// GOOD: static system + dynamic in messages
system: `You are bot. ...`  // ← cacheable
messages: [
  { role: "user", content: `Time: ${new Date()}. UserID: ${userId}. Query: ${query}` }
]

Tactic 2: Standardize tool definitions

Đừng pass tools array khác order/version giữa request. Cache hash based on EXACT sequence:

// BAD: regenerate tools list mỗi request (object reference khác)
tools: regenerateTools(...)
 
// GOOD: const reference shared
const TOOLS = [...]; // Singleton
tools: TOOLS

Tactic 3: Batch similar request

Group user request từ similar context để hit cùng cache:

// BAD: round-robin different user
processRequests([user1, user2, user1, user3, user2]); 
// → cache thrash
 
// GOOD: batch by user
processRequests([user1, user1, user1, user2, user2, user3]);
// → user1 hit cache 3 lần

Tactic 4: Pre-warm cache

Daily cron job pre-warm cache cho upcoming heavy hour:

// 8am cron: pre-warm before 9am peak
await client.messages.create({
  system: [{ type: "text", text: systemPrompt, cache_control: ... }],
  messages: [{ role: "user", content: "warmup" }],
  max_tokens: 10
});

Cost: $0.05/warmup. Benefit: first user 9am hit cache instead of miss.

Tactic 5: Smaller cached portion

Cache phải > min size (1024-2048 token). Nếu prefix < min → split:

// BAD: prefix 800 token < min → no cache
system: "Short system prompt 800 token..."
 
// GOOD: extend with boilerplate to > min
system: "Short system + brand voice + examples 3000 token..."

Padding với useful content (examples, guidelines) > 1024 → cache enabled.

Tactic 6: Monitor cache metrics

Response headers từ Anthropic API:

{
  "usage": {
    "input_tokens": 200,                  // Total input
    "cache_creation_input_tokens": 0,    // Write cost
    "cache_read_input_tokens": 5000,     // Read benefit
    "output_tokens": 500
  }
}

Hit rate calculation:

const hitRate = usage.cache_read_input_tokens / 
  (usage.cache_read_input_tokens + usage.cache_creation_input_tokens);

Target > 70% hit rate.

Tactic 7: TTL match request pattern

Plot histogram request gap → choose TTL.

< 5 phút between requests: ephemeral default
5-60 phút: extended 1h ($)
> 1 hour: probably skip caching

Pitfalls phổ biến

1. Cache key bao gồm dynamic content

Invalidate every request. Detection: monitor cache_read_input_tokens luôn 0.

2. Min size không đủ

< 1024 (3.x) / 2048 (4.x) token cached portion = ignored. Detection: cache header consistently 0.

3. Multi-region inconsistency

Anthropic deploy multi-region. Cache per-region. User route khác region → cache miss. Fix: pin client to single region.

4. Cache TTL hết giữa session

User idle 6 phút mid-conversation → cache miss next turn. Fix: extend TTL 1h cho long-session.

5. Tools list không deterministic order

// BAD: random order each call
tools: shuffle(toolList)
 
// GOOD: sorted consistent order
tools: [...toolList].sort((a, b) => a.name.localeCompare(b.name))

6. System prompt template variable

// BAD: template substitution trong system
system: `Bot for ${tenantName}, day ${dayOfWeek}.`
 
// GOOD: parameterize via messages
system: "Bot per tenant + day"
messages: [{ role: "user", content: `Tenant: ${tenantName}, Day: ${dayOfWeek}. Query: ...` }]

7. Cache cho 1-shot script

// One-time script — không cần cache (no reuse)
node generate-report-once.js  // KHÔNG add cache_control

Write cost 1.25x cho no benefit.

Ví dụ thực tế: vietcodex.com wiki gen caching

// Wiki content generation pipeline
const SYSTEM_PROMPT = `
You are VietCodex wiki writer...
[Brand voice 1000 token]
[Vietnamese style guide 1500 token]
[Cross-link strategy 1000 token]
[Schema requirements 800 token]
[FAQ format guide 500 token]
[Example output 700 token]
`;  // Total ~5500 token
 
const TOOL_DEFS = [
  { name: "search_wikimedia", ... },
  { name: "verify_url", ... },
  { name: "check_cross_link", ... },
  // ... 8 tools, ~3000 token total
];
 
// Generate 1 article
async function generateArticle(topic: string) {
  return client.messages.create({
    model: "claude-sonnet-4-5",
    system: [{ type: "text", text: SYSTEM_PROMPT, cache_control: { type: "ephemeral" } }],
    tools: [
      ...TOOL_DEFS.slice(0, -1),
      { ...TOOL_DEFS.at(-1), cache_control: { type: "ephemeral" } }  // breakpoint after tools
    ],
    messages: [
      { role: "user", content: `Write wiki article on: ${topic}` }
    ],
    max_tokens: 6000
  });
}
 
// Generate 20 article session
for (const topic of topics) {
  await generateArticle(topic);
}
 
// Result:
// Article 1: $0.015 (write) + $0.090 output = $0.105
// Article 2-20: $0.003 (read) + $0.090 output = $0.093 each
// Total 20 article: $0.105 + 19 × $0.093 = $1.873
 
// Without caching:
// Each article: 5500 × $3/M + 3000 × $3/M + 6000 × $15/M = $0.0165 + $0.009 + $0.090 = $0.1155
// Total: 20 × $0.1155 = $2.31
 
// Saving: $2.31 - $1.873 = $0.44 (19%)

Modest saving cho 20 article session. Caching shines khi volume scale — production chatbot 10k query/ngày saving compound massive.

Cái gì có thể sai

Vấn đềTriệu chứngCách fix
Cache miss luôncache_read_input_tokens = 0Check dynamic content trong cached portion
Cache size too smallCache flag silent ignoredVerify > 1024 (3.x) or 2048 (4.x) token min
TTL hết quá sớmHit rate < 30%Extend TTL 1h hoặc reduce request gap
Write cost > savingHit rate < 20%Don't cache nếu volume thấp
Tools order randomCache hash inconsistentSort tools deterministic
Multi-region cache missUser routing khác regionPin region trong client config
Long output không cacheOutput không cacheableOutput luôn full price, expected
Stream interrupt mid-cacheAborted before cache writeOK — cache write only on success

Tóm tắt 1 dòng

Prompt caching (Anthropic) = cache prefix tĩnh, request thứ 2+ chỉ trả 10% giá input. Saving 80-90% on cached portion với 1 flag config. 4 breakpoint max: system + tools + RAG context + history. Min cache size 1024-2048 token. TTL default 5 phút ephemeral (free), extended 1 giờ (2x write cost). Hit rate target > 70% production. Pitfall: dynamic content trong cached portion = invalidate, non-deterministic tool order, size below min. OpenAI có auto-caching saving 50%, Anthropic explicit saving 90% — Anthropic win cho production high-volume.

Đọc tiếp

Câu hỏi thường gặp

Prompt caching khác browser cache thế nào?
Browser cache: lưu HTML/CSS/JS file ở browser (client side), TTL theo header. Prompt cache: lưu intermediate state của LLM (key-value attention) ở server (Anthropic side), TTL 5 phút mặc định, 1 giờ tier 'extended'. Khác mục đích: browser cache giảm bandwidth, prompt cache giảm LLM compute cho re-process same prefix. Tương đồng: cả 2 invalidate khi content thay đổi. Prompt cache transparent — bạn không thấy 'cache hit' thật, chỉ thấy bill giảm 90% trên cached portion.
Cache breakpoint là gì? Có max bao nhiêu?
Cache breakpoint = vị trí trong prompt bạn mark 'cache trở về trước'. Anthropic support 4 breakpoint max per request. Khi gửi request: prompt được chia thành sections theo breakpoint. Section đứng trước breakpoint được cache. Pattern: (1) System prompt — breakpoint #1; (2) Tool definitions — breakpoint #2; (3) Long context (RAG docs) — breakpoint #3; (4) Conversation history — breakpoint #4. Min cache size: 1024 token (Claude 3.x), 2048 token (Claude 4.x). Section dưới min không cache.
TTL 5 phút vs 1 giờ extended — chọn cái nào?
Default 5 phút (`ephemeral`): free, fit cho conversational AI có user gửi liên tiếp. Extended 1 giờ: cost 2x base write, fit cho periodic batch (eval, scheduled task, batch processing). Quy tắc: (1) User-facing chatbot real-time → 5 phút (turn 30s-2min); (2) Internal automation chạy giờ → 1 giờ; (3) Daily batch task → consider not caching nếu < 1 lần/giờ. Calculate: nếu request gap > TTL → cache miss → no saving. Need request frequency > TTL period.
Hit rate dưới bao nhiêu thì không lợi caching?
Break-even point: cache hit rate > ~20% mới có saving. Lý do: write cache cost 1.25x base, hit save 0.9x base. Math: 1 write + 4 hit = 1.25 + 4×0.1 = 1.65x. So với no cache: 5×1 = 5x. Saving = 67%. Nếu hit rate < 20% (1 write + 0 hit = 1.25x vs 1x no cache) → caching ĐẮT hơn. Monitor hit rate qua API response header `cache_read_input_tokens` vs `cache_creation_input_tokens`. Target: 70%+ hit rate cho production saving substantial.
Cache có invalidate khi tôi đổi 1 từ trong system prompt?
Có — cache hash-based. Đổi 1 ký tự trong prefix = cache miss → re-write. Implication: (1) Đừng inject dynamic content (timestamp, user ID) vào system prompt cached portion; (2) Move dynamic to messages sau breakpoint; (3) Tránh feature flag toggle trong system prompt. Pattern correct: system prompt = static boilerplate. Per-user context → messages section sau breakpoint. Per-request data → user message.
OpenAI có caching không? Khác Anthropic?
OpenAI launched automatic caching Q4 2024 — KHÔNG cần flag, auto-detect repeated prefix. Saving ~50% off input. Pros: zero code change. Cons: less control (không guarantee cache, không chọn breakpoint). Anthropic explicit caching: cần `cache_control` flag, kiểm soát rõ ràng, saving 90% (higher). Quy tắc: Anthropic explicit cho production high-volume (more saving). OpenAI auto cho prototype/casual use. Gemini Caching Pro launched 2024 cũng explicit, similar Anthropic pattern.
Caching có ảnh hưởng output quality không?
KHÔNG. Cache lưu intermediate computation, output identical với non-cached. Anthropic guarantee bit-for-bit same output cho same input. Caching purely optimization, không thay đổi behavior. Edge case: nếu temperature > 0 (stochastic) → output có thể khác giữa run dù cache hit/miss — đó là temperature random, không phải cache issue. Production tip: cache không ảnh hưởng eval — eval score giống nhau cached vs non-cached.