Trung cấpHướng dẫnClaude APINguồn: Anthropic

Prompt Caching — Tiết kiệm 90% chi phí cho system prompt lặp lại

Nghe bài viết
00:00

Điểm nổi bật

Nhấn để đến mục tương ứng

  1. 1 Bạn trả thêm 25% phí cho phần được cache (cache write cost) Các lần gọi tiếp theo (cache hit): phần đã cache không cần gửi lại, chỉ tính 10% giá gốc.
  2. 2 Kết hợp Prompt Caching với các kỹ thuật tối ưu khác Prompt Caching mang lại hiệu quả cao nhất khi kết hợp với các kỹ thuật tối ưu khác: Batch API + Caching: giảm 50% giá qua Batch API, giảm thêm 90% giá input qua caching.
  3. 3 Prompt Caching cho phép bạn lưu trữ phần nội dung tĩnh này trên server của Anthropic, giúp giảm tới 90% chi phí input token và tăng tốc thời gian phản hồi.
  4. 4 Thời gian xử lý cũng nhanh hơn vì model không cần đọc lại phần đã cache Khi cache hết hạn (cache miss): quay lại trạng thái ban đầu, cần cache write lại Thời gian sống của cache (TTL) Cache có thời gian sống mặc định là 5 phút kể từ lần sử dụng cuối cùng.
  5. 5 Mức cải thiện phụ thuộc vào tỷ lệ cached tokens so với tổng tokens.
a wooden block that says seo on it

Trong hầu hết ứng dụng sử dụng Claude API, system prompt chiếm phần lớn input token nhưng lại giống hệt nhau qua hàng nghìn request. Prompt Caching cho phép bạn lưu trữ phần nội dung tĩnh này trên server của Anthropic, giúp giảm tới 90% chi phí input token và tăng tốc thời gian phản hồi. Bài viết này hướng dẫn chi tiết cách triển khai, tính toán chi phí, và các chiến lược tối ưu.

Prompt Caching hoạt động như thế nào?

Khi bạn gửi một request tới Claude API, phần lớn input thường gồm: system prompt (hướng dẫn cho model), context cố định (tài liệu tham khảo, few-shot examples), và nội dung thay đổi (câu hỏi của người dùng). Prompt Caching cho phép bạn đánh dấu phần nội dung tĩnh để Anthropic lưu cache trên server.

Cơ chế hoạt động cụ thể:

  • Lần gọi đầu tiên (cache write): toàn bộ nội dung được gửi và xử lý bình thường. Phần được đánh dấu cache sẽ được lưu trên server. Bạn trả thêm 25% phí cho phần được cache (cache write cost)
  • Các lần gọi tiếp theo (cache hit): phần đã cache không cần gửi lại, chỉ tính 10% giá gốc. Thời gian xử lý cũng nhanh hơn vì model không cần đọc lại phần đã cache
  • Khi cache hết hạn (cache miss): quay lại trạng thái ban đầu, cần cache write lại

Thời gian sống của cache (TTL)

Cache có thời gian sống mặc định là 5 phút kể từ lần sử dụng cuối cùng. Mỗi lần cache hit sẽ reset TTL về 5 phút. Nghĩa là nếu ứng dụng của bạn có request liên tục (ít nhất 1 request mỗi 5 phút), cache sẽ không bao giờ hết hạn.

Triển khai Prompt Caching trong Python

Để sử dụng Prompt Caching, bạn thêm thuộc tính cache_control vào phần nội dung muốn cache. Yêu cầu tối thiểu là nội dung cache phải đạt 1.024 token trở lên cho Claude Sonnet và Opus, hoặc 2.048 token cho Claude Haiku.

Cách đánh dấu cache cho system prompt

import anthropic

client = anthropic.Anthropic()

# System prompt dai (thuong la huong dan chi tiet cho model)
system_prompt = """Ban la tro ly ho tro khach hang cua cong ty XYZ.
Quy tac xu ly:
1. Luon chao hoi lich su truoc khi tra loi
2. Neu khach hoi ve gia, tham khao bang gia duoi day
3. Neu khach khieu nai, the hien su thong cam truoc
4. Khong bao gio hua dieu gi ngoai chinh sach
5. Ket thuc bang cau hoi "Con dieu gi toi co the giup ban?"

Bang gia san pham:
[... danh sach 500 san pham voi gia ...]

Chinh sach doi tra:
[... 2000 tu mo ta chinh sach ...]

FAQ:
[... 3000 tu cac cau hoi thuong gap ...]
"""

response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": system_prompt,
            "cache_control": {"type": "ephemeral"}
        }
    ],
    messages=[
        {"role": "user", "content": "San pham A gia bao nhieu?"}
    ]
)

# Kiem tra cache usage
print(f"Cache write tokens: {response.usage.cache_creation_input_tokens}")
print(f"Cache read tokens: {response.usage.cache_read_input_tokens}")
print(f"Uncached tokens: {response.usage.input_tokens}")

Cache nhiều block nội dung

Bạn có thể đánh dấu cache cho nhiều phần khác nhau, ví dụ system prompt và conversation history:

response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": system_prompt,
            "cache_control": {"type": "ephemeral"}
        }
    ],
    messages=[
        # Lich su hoi thoai cu (cache lai)
        {"role": "user", "content": "Xin chao"},
        {"role": "assistant", "content": "Xin chao! Toi co the giup gi cho ban?"},
        {"role": "user", "content": "Cho toi xem bang gia"},
        {
            "role": "assistant",
            "content": [
                {
                    "type": "text",
                    "text": "Day la bang gia cua chung toi: ...",
                    "cache_control": {"type": "ephemeral"}
                }
            ]
        },
        # Tin nhan moi (khong cache)
        {"role": "user", "content": "San pham B co giam gia khong?"}
    ]
)

Triển khai trong Node.js

Cú pháp tương tự trong JavaScript/TypeScript:

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

async function chatWithCaching(userMessage, conversationHistory) {
  const systemContent = [
    {
      type: "text",
      text: longSystemPrompt,
      cache_control: { type: "ephemeral" }
    }
  ];

  // Danh dau cache cho message cuoi trong lich su hoi thoai
  const messages = [...conversationHistory];
  if (messages.length > 0) {
    const lastMsg = messages[messages.length - 1];
    if (typeof lastMsg.content === "string") {
      messages[messages.length - 1] = {
        ...lastMsg,
        content: [
          {
            type: "text",
            text: lastMsg.content,
            cache_control: { type: "ephemeral" }
          }
        ]
      };
    }
  }

  // Them tin nhan moi cua nguoi dung
  messages.push({ role: "user", content: userMessage });

  const response = await client.messages.create({
    model: "claude-sonnet-4-20250514",
    max_tokens: 1024,
    system: systemContent,
    messages: messages
  });

  console.log("Cache write:", response.usage.cache_creation_input_tokens);
  console.log("Cache read:", response.usage.cache_read_input_tokens);

  return response;
}

Tính toán chi phí tiết kiệm

Giả sử bạn có system prompt dài 4.000 token và nhận 1.000 request mỗi ngày. Sử dụng Claude Sonnet:

Kịch bản Chi phí input mỗi request Chi phí 1.000 request
Không cache 4.000 x $3/1M = $0.012 $12.00
Cache (lần đầu - write) 4.000 x $3.75/1M = $0.015 $0.015 (1 lần)
Cache (999 lần sau - hit) 4.000 x $0.30/1M = $0.0012 $1.20
Tổng với cache - $1.215
Tiết kiệm - $10.785 (89.9%)

Con số tiết kiệm phụ thuộc vào hai yếu tố: tỷ lệ cache hit (càng cao càng tiết kiệm) và kích thước phần được cache so với phần không cache (phần cache càng lớn, tiết kiệm càng nhiều).

Công thức tính chi phí

def estimate_caching_savings(
    cached_tokens,
    uncached_tokens_per_request,
    total_requests,
    cache_hit_rate=0.95,
    model="claude-sonnet-4-20250514"
):
    """Uoc tinh chi phi tiet kiem khi dung Prompt Caching."""
    # Gia cho Claude Sonnet (USD per token)
    base_price = 3.0 / 1_000_000

    # Khong cache
    no_cache_cost = (cached_tokens + uncached_tokens_per_request)                     * base_price * total_requests

    # Co cache
    cache_write_cost = cached_tokens * (base_price * 1.25)  # 125% gia goc
    cache_read_cost = cached_tokens * (base_price * 0.1)    # 10% gia goc
    uncached_cost = uncached_tokens_per_request * base_price

    num_writes = total_requests * (1 - cache_hit_rate)
    num_reads = total_requests * cache_hit_rate

    with_cache_cost = (
        num_writes * cache_write_cost +
        num_reads * cache_read_cost +
        total_requests * uncached_cost
    )

    savings = no_cache_cost - with_cache_cost
    savings_pct = (savings / no_cache_cost) * 100

    print(f"Khong cache: ${no_cache_cost:.2f}")
    print(f"Co cache: ${with_cache_cost:.2f}")
    print(f"Tiet kiem: ${savings:.2f} ({savings_pct:.1f}%)")

    return savings

# Vi du
estimate_caching_savings(
    cached_tokens=4000,
    uncached_tokens_per_request=200,
    total_requests=10000,
    cache_hit_rate=0.98
)

Nên cache cái gì và không nên cache cái gì?

Không phải tất cả nội dung đều nên cache. Dưới đây là hướng dẫn chi tiết:

Nên cache

  • System prompt dài: hướng dẫn chi tiết, quy tắc xử lý, persona description
  • Tài liệu tham khảo: bảng giá, chính sách, FAQ, knowledge base
  • Few-shot examples: các ví dụ mẫu để model học theo format output
  • Conversation history: phần lịch sử hội thoại không thay đổi trong multi-turn chat
  • Schema và template: JSON schema, output template, format instructions

Không nên cache

  • Nội dung thay đổi thường xuyên: dữ liệu real-time, timestamp, context động
  • Nội dung quá ngắn: dưới 1.024 token (Sonnet/Opus) hoặc 2.048 token (Haiku) sẽ không đủ điều kiện cache
  • Nội dung khác nhau mỗi request: ví dụ user-specific context mà mỗi user có nội dung riêng
  • Nội dung hiếm khi lặp lại: nếu mỗi request có system prompt khác nhau, cache write cost sẽ cao hơn lợi ích

Chiến lược cache warming

Cache warming là kỹ thuật gửi request "giả" để tạo cache trước khi có request thật từ người dùng. Điều này đảm bảo request đầu tiên của người dùng đã được cache hit, giảm latency.

async def warm_cache(client, system_prompt):
    """Gui request gia de tao cache truoc khi co traffic that."""
    response = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=1,
        system=[
            {
                "type": "text",
                "text": system_prompt,
                "cache_control": {"type": "ephemeral"}
            }
        ],
        messages=[
            {"role": "user", "content": "ping"}
        ]
    )

    if response.usage.cache_creation_input_tokens > 0:
        print(f"Cache warmed: {response.usage.cache_creation_input_tokens} tokens cached")
    return True


# Goi ham nay khi ung dung khoi dong
# hoac dinh ky moi 4 phut de cache khong het han
import asyncio

async def keep_cache_warm(client, system_prompt, interval=240):
    """Giu cache song bang cach refresh dinh ky."""
    while True:
        await warm_cache(client, system_prompt)
        await asyncio.sleep(interval)  # 4 phut (truoc khi TTL 5 phut het han)

Khi nào cần cache warming?

  • Ứng dụng có traffic không đều (ví dụ: ít request vào ban đêm, dẫn đến cache hết hạn)
  • System prompt rất dài (hàng nghìn token), cache miss gây tăng latency đáng kể
  • Ứng dụng yêu cầu latency thấp nhất quán cho mọi request

Monitoring cache hiệu quả

Để đảm bảo Prompt Caching hoạt động hiệu quả, bạn cần theo dõi các metric quan trọng:

class CacheMonitor:
    def __init__(self):
        self.total_requests = 0
        self.cache_hits = 0
        self.cache_writes = 0
        self.total_cached_tokens = 0
        self.total_uncached_tokens = 0

    def record(self, usage):
        """Ghi nhan usage tu response."""
        self.total_requests += 1

        if usage.cache_read_input_tokens > 0:
            self.cache_hits += 1
            self.total_cached_tokens += usage.cache_read_input_tokens

        if usage.cache_creation_input_tokens > 0:
            self.cache_writes += 1

        self.total_uncached_tokens += usage.input_tokens

    def report(self):
        """In bao cao cache hieu suat."""
        hit_rate = (self.cache_hits / self.total_requests * 100
                    if self.total_requests > 0 else 0)

        print(f"Tong request: {self.total_requests}")
        print(f"Cache hits: {self.cache_hits} ({hit_rate:.1f}%)")
        print(f"Cache writes: {self.cache_writes}")
        print(f"Cached tokens: {self.total_cached_tokens:,}")
        print(f"Uncached tokens: {self.total_uncached_tokens:,}")

# Su dung
monitor = CacheMonitor()

response = client.messages.create(...)
monitor.record(response.usage)

# In bao cao dinh ky
monitor.report()

Những lỗi thường gặp

Dưới đây là các lỗi phổ biến khi triển khai Prompt Caching và cách khắc phục:

1. Cache không hoạt động (luôn miss)

Nguyên nhân phổ biến nhất là nội dung cache thay đổi giữa các request. Cache key được tính dựa trên toàn bộ nội dung. Dù chỉ thay đổi một ký tự, cache sẽ miss hoàn toàn.

# SAI: timestamp thay doi moi request -> luon cache miss
system = f"Ban la tro ly. Hien tai la {datetime.now()}. ..."

# DUNG: tach phan tinh va phan dong
system_static = "Ban la tro ly. Quy tac: ..."  # cache phan nay
user_msg = f"Hien tai la {datetime.now()}. Cau hoi: ..."  # khong cache

2. Cache quá ngắn, không đủ điều kiện

Nội dung cache phải đạt tối thiểu 1.024 token (Sonnet/Opus) hoặc 2.048 token (Haiku). Nếu system prompt ngắn hơn, hãy cân nhắc thêm few-shot examples hoặc tài liệu tham khảo vào phần cache.

3. Cache hết hạn do traffic thấp

Nếu khoảng cách giữa hai request liên tiếp vượt quá 5 phút, cache sẽ hết hạn. Sử dụng cache warming để giải quyết vấn đề này.

4. Cache nhiều phiên bản khác nhau

Nếu ứng dụng có nhiều loại system prompt (ví dụ cho từng ngành hoặc từng khách hàng), mỗi phiên bản sẽ có cache riêng. Hãy tối ưu bằng cách đặt phần chung lên trước và cache phần đó, phần riêng đặt sau và không cache.

Cache cho multi-turn conversation

Trong ứng dụng chat, mỗi tin nhắn mới đều gửi lại toàn bộ lịch sử hội thoại. Prompt Caching đặc biệt hiệu quả ở đây vì phần lịch sử cũ không thay đổi giữa các lượt chat:

class CachedChatSession:
    """Phien chat voi Prompt Caching tu dong."""

    def __init__(self, client, system_prompt, model="claude-sonnet-4-20250514"):
        self.client = client
        self.system_prompt = system_prompt
        self.model = model
        self.messages = []

    def send(self, user_message):
        """Gui tin nhan voi cache tu dong cho lich su."""
        # Danh dau cache cho system prompt
        system = [
            {
                "type": "text",
                "text": self.system_prompt,
                "cache_control": {"type": "ephemeral"}
            }
        ]

        # Copy messages va danh dau cache cho tin cuoi
        # trong lich su (truoc tin moi)
        messages = []
        for i, msg in enumerate(self.messages):
            if i == len(self.messages) - 1 and msg["role"] == "assistant":
                # Tin cuoi cua assistant -> cache breakpoint
                messages.append({
                    "role": "assistant",
                    "content": [
                        {
                            "type": "text",
                            "text": msg["content"],
                            "cache_control": {"type": "ephemeral"}
                        }
                    ]
                })
            else:
                messages.append(msg)

        # Them tin moi cua nguoi dung
        messages.append({"role": "user", "content": user_message})

        response = self.client.messages.create(
            model=self.model,
            max_tokens=2048,
            system=system,
            messages=messages
        )

        # Luu vao lich su
        self.messages.append({"role": "user", "content": user_message})
        assistant_text = response.content[0].text
        self.messages.append({"role": "assistant", "content": assistant_text})

        return {
            "text": assistant_text,
            "cache_read": response.usage.cache_read_input_tokens,
            "cache_write": response.usage.cache_creation_input_tokens,
            "uncached": response.usage.input_tokens
        }

# Su dung
session = CachedChatSession(client, long_system_prompt)
r1 = session.send("Xin chao")  # cache write system prompt
r2 = session.send("Ban co the giup gi?")  # cache read system + write history
r3 = session.send("Cho toi xem bang gia")  # cache read system + history

Qua mỗi lượt chat, phần đã cache ngày càng lớn (system prompt + lịch sử tích lũy), trong khi phần uncached chỉ là tin nhắn mới nhất. Điều này giúp tiết kiệm đáng kể khi conversation dài nhiều lượt.

So sánh hiệu suất: có cache vs không cache

Dưới đây là kết quả benchmark thực tế cho một ứng dụng chatbot hỗ trợ khách hàng với system prompt 5.000 token, trung bình 8 lượt chat mỗi phiên:

Metric Không cache Có cache Cải thiện
Chi phí input trung bình mỗi phiên $0.156 $0.022 85.9%
Latency trung bình (TTFT) 1.2 giây 0.8 giây 33.3%
Chi phí 10.000 phiên/tháng $1,560 $220 $1,340 tiết kiệm

Lưu ý: cải thiện latency đến từ việc server không cần xử lý lại phần đã cache. Mức cải thiện phụ thuộc vào tỷ lệ cached tokens so với tổng tokens.

Kết hợp Prompt Caching với các kỹ thuật tối ưu khác

Prompt Caching mang lại hiệu quả cao nhất khi kết hợp với các kỹ thuật tối ưu khác:

  • Batch API + Caching: giảm 50% giá qua Batch API, giảm thêm 90% giá input qua caching. Tổng tiết kiệm có thể đạt 95% cho phần input token
  • Model cascade + Caching: dùng Haiku cho tác vụ đơn giản (với cache), escalate lên Sonnet khi cần (cũng với cache)
  • Streaming + Caching: cache không ảnh hưởng đến streaming, bạn vẫn nhận response từng phần như bình thường

Thứ tự nội dung trong prompt khi dùng cache

Vì cache hoạt động theo prefix (từ đầu đến vị trí cache_control), thứ tự sắp xếp nội dung rất quan trọng:

# Thu tu toi uu:
# 1. Noi dung tinh, it thay doi nhat (cache)
# 2. Noi dung ban tinh (co the cache breakpoint thu 2)
# 3. Noi dung dong (khong cache)

system = [
    {
        "type": "text",
        "text": "Huong dan chung va quy tac xu ly...",  # it thay doi
        "cache_control": {"type": "ephemeral"}
    }
]

messages = [
    # Lich su hoi thoai (cache breakpoint thu 2)
    {"role": "user", "content": "..."},
    {"role": "assistant", "content": [
        {"type": "text", "text": "...",
         "cache_control": {"type": "ephemeral"}}
    ]},
    # Tin nhan moi nhat (khong cache)
    {"role": "user", "content": "Cau hoi moi cua nguoi dung"}
]

Bước tiếp theo

Prompt Caching là một trong những kỹ thuật tối ưu chi phí hiệu quả nhất khi làm việc với Claude API. Kết hợp caching với error handling và retry strategy sẽ giúp xây dựng ứng dụng production vững chắc và tiết kiệm. Khám phá thêm tại Thư viện Nâng cao Claude.

Tính năng liên quan:Prompt CachingCost OptimizationPerformanceTTL Management

Bai viet co huu ich khong?

Bản quyền thuộc về tác giả. Vui lòng dẫn nguồn khi chia sẻ.

Bình luận (0)
Ảnh đại diện
Đăng nhập để bình luận...
Đăng nhập để bình luận
  • Đang tải bình luận...

Đăng ký nhận bản tin

Nhận bài viết hay nhất về sản phẩm và vận hành, gửi thẳng vào hộp thư của bạn.

Bảo mật thông tin. Hủy đăng ký bất cứ lúc nào. Chính sách bảo mật.