Dùng AI

Prompt caching: giảm chi phí khi gửi lại cùng một ngữ cảnh

Khi mỗi lần gọi API đều gửi lại cùng một đoạn dài, như cả giáo trình hay bộ chỉ dẫn hàng nghìn chữ, bạn trả tiền đọc đoạn đó mỗi lần. Prompt caching cho phép lưu phần đầu chung ấy; lần đầu tốn hơn một chút để ghi, các lần sau đọc lại với giá rẻ hơn nhiều. Bài này giải thích cách hoạt động theo tài liệu của Anthropic, cách đặt prompt để cache trúng, và đoạn Python ước chi phí cho một chatbot giáo trình 200 câu hỏi.

Ý chính
  • Prompt caching lưu phần đầu prompt giống hệt nhau giữa các lần gọi. Lần đầu ghi cache tốn hơn giá thường; các lần sau đọc cache rẻ hơn nhiều.
  • Cache chỉ trúng khi phần đầu giống nhau từng byte. Đặt phần cố định (chỉ dẫn, tài liệu) ở đầu, phần thay đổi (câu hỏi) ở cuối.
  • Thời hạn mặc định 5 phút, tự gia hạn mỗi lần dùng; có lựa chọn 1 giờ với giá ghi cao hơn. Prompt quá ngắn không được cache.
  • Trong ví dụ của bài, chatbot giáo trình 50.000 token trả lời 200 câu hỏi, mỗi lượt khoảng 1.000 token đầu ra kể cả phần suy nghĩ: chi phí với Claude Opus 5.5 ước giảm từ 44,08 USD xuống 6,32 USD. Cache chỉ giảm phần đầu vào, phần đầu ra giữ nguyên.

Bài này dựa trên trang Prompt caching và trang giá trong tài liệu của Anthropic (đọc ngày 11/11/2026, xem lại giá ngày 15/11/2026). Các hãng khác cũng có cơ chế tương tự, với cách bật và mức giá khác nhau.

Cache cái gì

Mỗi lần gọi, mô hình phải đọc toàn bộ prompt trước khi trả lời. Nếu prompt bắt đầu bằng 50.000 token giáo trình giống hệt lần trước, việc đọc lại phần đó là lặp. Prompt caching lưu kết quả xử lý phần đầu ấy để lần sau dùng lại. Theo tài liệu, cache không làm thay đổi câu trả lời; nó chỉ giảm chi phí và thời gian xử lý phần đầu vào.

Thứ tự trong yêu cầu quan trọng. Tài liệu ghi rằng cache bao phủ theo thứ tự: danh sách công cụ, rồi chỉ dẫn hệ thống, rồi các tin nhắn. Một mục cache gồm mọi thứ tính tới khối được đánh dấu. Mọi thay đổi ở khối đó hoặc trước nó tạo ra phần đầu khác, và cache trượt. Vì vậy đổi định nghĩa công cụ làm mất cache của cả chỉ dẫn và tin nhắn phía sau.

Bật cache

Có hai cách. Cách tự động: thêm một trường đánh dấu cache ở cấp yêu cầu, API tự đặt điểm cache ở khối cuối có thể cache, và điểm này dời dần khi hội thoại dài ra. Cách thủ công: đặt đánh dấu cache vào từng khối nội dung, ví dụ khối chứa giáo trình trong chỉ dẫn hệ thống. Tài liệu cho phép tối đa 4 điểm đánh dấu thủ công trong một yêu cầu; bản thân việc đánh dấu không tốn tiền, bạn chỉ trả cho ghi cache, đọc cache và phần đầu vào không cache.

Có ngưỡng tối thiểu. Prompt ngắn hơn ngưỡng sẽ được xử lý bình thường, không báo lỗi, chỉ là không có cache. Với Claude Opus 5.5, Sonnet 5.5 và Haiku 5.5, ngưỡng là 512 token theo bảng trong tài liệu; một số mô hình cũ có ngưỡng cao hơn, tới 4.096 token.

Prompt caching: trả một lần, đọc nhiều lần Giáo trình 50.000 token, 200 câu hỏi 1. Phần chungĐặt ở đầuđánh dấu cache 2. Lần đầuGhi cache1,25 lần giá vào 3. Lần sauĐọc cacherẻ hơn nhiều 4. Kết quả44,08 -> 6,32 USDOpus 5.5, giảm 86% Giá 15/11/2026, câu hỏi cách nhau dưới 5 phút
Prompt caching: trả một lần, đọc nhiều lần 1. Phần chungĐặt ở đầuđánh dấu cache 2. Lần đầuGhi cache1,25 lần giá vào 3. Lần sauĐọc cacherẻ hơn nhiều 4. Kết quả44,08 -> 6,32 USDOpus 5.5, giảm 86% Giá 15/11/2026, câu hỏi cách nhau dưới 5 phút
Hình 1. Prompt caching với giáo trình 50.000 token và 200 câu hỏi: (1) phần chung đặt ở đầu, đánh dấu cache; (2) lần đầu ghi cache, giá bằng 1,25 lần giá đầu vào; (3) các lần sau đọc cache, rẻ hơn nhiều; (4) với Claude Opus 5.5, chi phí ước giảm từ 44,08 xuống 6,32 USD, khoảng 86%. Ước tính theo giá ngày 15/11/2026, giả định câu hỏi cách nhau dưới 5 phút và mỗi lượt khoảng 1.000 token đầu ra kể cả phần suy nghĩ.

Giá và thời hạn

Theo trang tài liệu, cache mặc định sống 5 phút và được gia hạn miễn phí mỗi lần được dùng. Giá ghi cache 5 phút bằng 1,25 lần giá đầu vào thường. Có lựa chọn thời hạn 1 giờ, giá ghi bằng 2 lần, dành cho prompt dùng lại thưa hơn 5 phút một lần nhưng dày hơn mỗi giờ. Giá đọc cache mặc định bằng 0,1 lần giá đầu vào; với Claude Opus 5.5 và Sonnet 5.5 là 0,05 lần.

Cụ thể với Opus 5.5: đầu vào thường 4 USD mỗi triệu token, ghi cache 5 phút 5 USD, ghi cache 1 giờ 8 USD, đọc cache 0,20 USD. Với Haiku 5.5 (prompt tới 100.000 token): đầu vào 0,10 USD, ghi cache 0,125 USD, đọc 0,01 USD. Giá đổi theo thời gian, luôn xem trang giá trước khi tính.

Ước chi phí bằng Python

Đoạn code dưới đây tính chi phí một chatbot hỏi đáp giáo trình: giáo trình 50.000 token đặt trong chỉ dẫn hệ thống, 200 câu hỏi mỗi câu 100 token, mỗi lượt khoảng 1.000 token đầu ra (câu trả lời khoảng 300 token, phần còn lại là phần suy nghĩ của mô hình). Hàm chi_phi tính hai trường hợp: không cache (mỗi câu trả tiền đọc lại cả giáo trình) và có cache (câu đầu ghi cache, 199 câu sau đọc cache). Hàm tao_yeu_cau cho thấy đặt đánh dấu cache ở đâu: trên khối giáo trình, sau chỉ dẫn cố định, trước câu hỏi thay đổi. Hàm doc_usage đọc các trường số token trong phản hồi để biết bao nhiêu phần đầu vào được đọc từ cache. Hàm doc_tra_loi lấy chữ trả lời và báo rõ nếu câu trả lời bị cắt vì chạm max_tokens hay bị từ chối; max_tokens trong yêu cầu để rộng vì phần suy nghĩ của mô hình cũng tính vào đó.

"""Prompt caching: ước chi phí có và không có cache, và tạo yêu cầu có đánh dấu cache cho phần giáo trình.

Giá USD / 1 triệu token theo trang Prompt caching và Pricing của Anthropic, xem lại ngày 15/11/2026
(Haiku 5.5 là giá cho prompt tới 100.000 token). Xem lại trang giá trước khi dùng.
Giả định khi ước: các câu hỏi đến cách nhau dưới 5 phút nên cache không hết hạn giữa chừng.
token_ra là toàn bộ token đầu ra mỗi lượt: phần suy nghĩ của mô hình (tính tiền như token đầu ra, dù không
hiện ra) cộng chữ trả lời. Cache chỉ giảm phần đầu vào, không giảm phần này.
"""

GIA = {  # đầu vào thường, ghi cache 5 phút, đọc cache, đầu ra
    "claude-opus-5-5": (4.0, 5.0, 0.20, 20.0),
    "claude-sonnet-5-5": (2.0, 2.50, 0.10, 10.0),
    "claude-haiku-5-5": (0.10, 0.125, 0.01, 0.50),
}
TOI_THIEU = 512  # số token tối thiểu để được cache với các mô hình trên (theo tài liệu)
# Giả định đầu ra mỗi lượt: câu trả lời khoảng 300 token cộng phần suy nghĩ. Chạy thật thì đọc usage.output_tokens.
TOKEN_RA = 1000


def chi_phi(mo_hinh, so_cau, token_chung, token_rieng, token_ra, dung_cache):
    vao, ghi, doc, ra = GIA[mo_hinh]
    phan_rieng = so_cau * (token_rieng * vao + token_ra * ra)
    if not dung_cache or token_chung < TOI_THIEU:
        return (so_cau * token_chung * vao + phan_rieng) / 1e6
    return (token_chung * ghi + (so_cau - 1) * token_chung * doc + phan_rieng) / 1e6


def tao_yeu_cau(giao_trinh, cau_hoi, mo_hinh="claude-haiku-5-5"):
    """Phần giáo trình đặt trong system và đánh dấu cache_control; câu hỏi đổi mỗi lần nên để sau."""
    return dict(
        model=mo_hinh,
        # Haiku 5.5 suy nghĩ trước khi trả lời, và token suy nghĩ tính vào max_tokens dù không hiện ra, nên để rộng chỗ.
        # max_tokens chỉ là mức trần: bạn trả tiền cho số token thật sự sinh ra.
        max_tokens=16000,
        system=[
            {"type": "text", "text": "Bạn là trợ giảng. Chỉ trả lời dựa trên giáo trình dưới đây."},
            {"type": "text", "text": giao_trinh, "cache_control": {"type": "ephemeral"}},
        ],
        messages=[{"role": "user", "content": cau_hoi}],
    )


def doc_usage(usage):
    """Tỷ lệ token đầu vào được đọc từ cache trong một lần gọi."""
    tong = usage.cache_read_input_tokens + usage.cache_creation_input_tokens + usage.input_tokens
    return usage.cache_read_input_tokens / tong if tong else 0.0


class KhongCoCauTraLoi(Exception):
    """Mô hình dừng mà không đưa ra câu trả lời trọn vẹn."""


def doc_tra_loi(tin):
    """Chữ trả lời trong phản hồi; báo rõ nếu câu trả lời bị cắt giữa chừng, bị từ chối hay không có chữ."""
    if tin.stop_reason in ("max_tokens", "model_context_window_exceeded"):
        raise KhongCoCauTraLoi(f"câu trả lời bị cắt giữa chừng ({tin.stop_reason})")
    if tin.stop_reason == "refusal":
        raise KhongCoCauTraLoi("mô hình từ chối trả lời câu hỏi này")
    chu = "".join(k.text for k in tin.content if k.type == "text")
    if not chu.strip():
        raise KhongCoCauTraLoi("mô hình không trả về chữ nào")
    return chu


def chay_thu():
    dong = ["Giáo trình 50000 token, 200 câu hỏi (mỗi câu 100 token), "
            f"mỗi lượt {TOKEN_RA} token đầu ra (suy nghĩ + câu trả lời):"]
    for mo_hinh in GIA:
        khong = chi_phi(mo_hinh, 200, 50_000, 100, TOKEN_RA, False)
        co = chi_phi(mo_hinh, 200, 50_000, 100, TOKEN_RA, True)
        dong.append(f"  {mo_hinh}: không cache {khong:.2f} USD, có cache {co:.2f} USD, giảm {1 - co / khong:.0%}")
    dong.append(f"Prompt 400 token (dưới {TOI_THIEU}) không được cache: "
                f"{chi_phi('claude-haiku-5-5', 200, 400, 100, TOKEN_RA, True):.4f} = "
                f"{chi_phi('claude-haiku-5-5', 200, 400, 100, TOKEN_RA, False):.4f} USD")
    print("\n".join(dong))
    return dong


if __name__ == "__main__":
    chay_thu()

Kết quả: với Opus 5.5, không cache tốn khoảng 44,08 USD, có cache khoảng 6,32 USD, giảm 86%. Sonnet 5.5 từ 22,04 xuống 3,16 USD. Haiku 5.5 từ 1,10 xuống 0,21 USD, giảm 81%; tỷ lệ giảm thấp hơn vì giá đọc cache của Haiku 5.5 bằng 0,1 lần giá đầu vào, còn Opus 5.5 và Sonnet 5.5 chỉ 0,05 lần. Dòng cuối cho thấy prompt 400 token, dưới ngưỡng 512, có bật cache cũng không đổi gì.

Con số 1.000 token đầu ra mỗi lượt là giả định thứ nhất cần nói rõ. Opus 5.5 không cho tắt chế độ suy nghĩ, Sonnet 5.5 và Haiku 5.5 cũng bật chế độ này theo mặc định, và theo trang Steering thinking của Anthropic, token suy nghĩ được tính tiền như token đầu ra dù bạn không thấy nội dung của nó. Trong một ví dụ chạy thật ở chính trang đó, Opus 5.5 phân tích một đoạn văn khoảng 3.500 token và tốn từ 1.033 đến 1.630 token đầu ra cho mỗi câu hỏi. Cache không giảm phần đầu ra, nên với Opus 5.5 số tiền tiết kiệm vẫn là khoảng 37,76 USD dù đầu ra dài hay ngắn; chỉ tỷ lệ giảm thay đổi. Nếu mô hình không suy nghĩ và mỗi lượt chỉ có 300 token chữ trả lời, mức giảm là 91%. Khi chạy thật, lấy số token đầu ra trong phản hồi thay vào hàm chi_phi để tính lại.

Con số này còn dựa trên giả định thứ hai: các câu hỏi đến đủ dày để cache không hết hạn. Nếu 200 câu rải đều trong một ngày, mỗi câu cách nhau vài phút đến vài chục phút, nhiều lần sẽ phải ghi cache lại. Khi đó tính lại với thời hạn 1 giờ, hoặc chấp nhận tiết kiệm ít hơn.

Đặt prompt cho cache trúng

  • Phần cố định trước, phần thay đổi sau. Chỉ dẫn, tài liệu, ví dụ mẫu ở đầu; câu hỏi của người dùng ở cuối.
  • Đừng chèn thứ hay đổi vào phần đầu. Ngày giờ hiện tại, tên người dùng, mã phiên đặt trong phần đầu sẽ làm mỗi yêu cầu có phần đầu khác nhau.
  • Giữ nguyên danh sách công cụ. Thêm bớt hoặc sửa mô tả một công cụ làm mất cache của mọi thứ phía sau.
  • Đọc số đo. Phản hồi có trường số token ghi cache và đọc cache. Nếu cả hai luôn bằng 0, cache không hoạt động, thường vì prompt dưới ngưỡng hoặc phần đầu thay đổi.

Tài liệu còn lưu ý: một mục cache chỉ dùng được sau khi phản hồi đầu tiên bắt đầu, nên gửi song song nhiều yêu cầu cùng lúc ngay từ đầu sẽ không trúng cache. Gửi một yêu cầu trước, đợi nó bắt đầu trả lời, rồi mới gửi loạt còn lại.

Khi nào cache không đáng

Cache có lợi khi cùng một phần đầu dài được dùng lại nhiều lần trong thời hạn. Nếu mỗi yêu cầu có tài liệu khác nhau, như tóm tắt từng bài báo một lần duy nhất, thì không có gì để đọc lại: bật cache chỉ làm bạn trả thêm 25% cho việc ghi mà không bao giờ đọc. Tương tự, nếu chỉ hỏi hai ba câu rồi nghỉ lâu, phần tiết kiệm nhỏ hơn phần trả thêm. Quy tắc nhẩm với thời hạn 5 phút: phần đầu cần được đọc lại ít nhất một lần trước khi hết hạn thì mới bắt đầu có lời, và càng nhiều lần đọc càng lời. Chạy hàm chi_phi với số câu bằng 1 sẽ thấy có cache còn đắt hơn không cache.

Cache, RAG và hội thoại dài

Với tài liệu vừa trong cửa sổ ngữ cảnh, đưa cả tài liệu vào prompt kèm cache có thể đơn giản hơn dựng hệ thống tìm kiếm; bài RAG là gì bàn về lựa chọn này. Với hội thoại nhiều lượt, cách tự động dời điểm cache theo hội thoại giúp mỗi lượt chỉ trả giá thường cho phần mới. Với agent gọi công cụ nhiều vòng, cache giảm đáng kể chi phí vì mỗi vòng gửi lại cả lịch sử; xem bài chi phí khi dùng agent.

Cẩn thận
  • Đặt ngày giờ hay thông tin người dùng ở đầu prompt rồi thắc mắc vì sao cache không trúng.
  • Bật cache cho prompt ngắn dưới ngưỡng và tưởng là đã tiết kiệm.
  • Tính tiết kiệm mà quên giả định về khoảng cách giữa các lần gọi, hoặc quên token suy nghĩ cũng tính tiền như đầu ra.
  • Gửi song song hàng trăm yêu cầu cùng lúc ngay từ đầu.
  • Dùng giá trong bài mà không xem lại trang giá.

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

Cache có làm câu trả lời khác đi không?

Không. Theo tài liệu, cache chỉ ảnh hưởng chi phí và tốc độ xử lý phần đầu vào.

Người khác có đọc được cache của tôi không?

Theo tài liệu, cache được tách riêng theo tổ chức và theo workspace trên Claude API.

Có cần xóa cache không?

Không. Cache tự hết hạn sau thời hạn nếu không được dùng.

Cache có dùng chung với xử lý theo lô không?

Có thể dùng cùng nhau, nhưng các yêu cầu trong lô chạy không theo thứ tự nên tỷ lệ trúng cache khó đoán hơn. Đo bằng các trường số token trong kết quả.

Học tiếp

Nếu bạn muốn học Python và AI bài bản cùng giảng viên, tham khảo khóa học AI của Big-O Coding.

Muốn học bài bản cùng giảng viên?

Khóa AI – Introduction to Machine Learning: nền tảng Máy học từ thuật toán cơ bản đến Neural Networks và LLM, học bằng Python. Học thử buổi 1 miễn phí.

Xem Khóa AI

Nguồn tham khảo

Chia sẻ: Facebook LinkedIn
Nhắn Zalo tư vấnZalo Gọi 0937 401 483