Jika Anda mengirim prompt sistem yang panjang — konteks RAG, katalog alat, aturan agen, contoh — kemungkinan besar Anda membayar harga input penuh pada setiap panggilan. Caching prompt Anthropic menurunkannya menjadi 10% dari tarif pada bagian yang di-cache. OpenAI melakukan hal yang sama secara implisit. Sebagian besar tim menganggap 30 menit pengerjaan ini sepadan karena secara konsisten memangkas 60–90% biaya input.
Kunavo menangani keduanya. Titik henti cache_control Anda sendiri diteruskan tanpa perubahan melalui Messages API; pada API Chat Completions dan Responses — yang formatnya tidak memiliki bidang tersebut untuk dikirim — Kunavo menetapkannya untuk Anda, lalu menambahkan titik henti di sekitar apa pun yang Anda kirim tanpa pernah melampaui batas 4. Artikel ini membahas keduanya, hal-hal yang diam-diam membatalkan cache, serta cara memverifikasi tingkat cache hit Anda.
Sebelum dan sesudah
Loop naif yang mengirim prompt sistem 18K token yang sama sebanyak sepuluh kali:
# What most people start with: every call re-pays for the whole prompt.
import anthropic
client = anthropic.Anthropic(
api_key="sk-kn-...",
base_url="https://api.kunavo.com",
)
SYSTEM = open("system-prompt.md").read() # 18,000 tokens of rules + examples
# 10 user questions in a session. Every call sends the 18K-token system block.
for question in questions:
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=600,
system=SYSTEM,
messages=[{"role": "user", "content": question}],
)
# Cost per call (input only): 18,000 × $3 / 1M = $0.054
# 10 calls: $0.54 in input alone.Sekarang tandai blok sistem agar dapat di-cache — satu bidang tambahan:
# The fix: mark the static prefix as cacheable. After the first call,
# subsequent calls within ~5 minutes pay 10% the input rate on the cached
# portion. Same answer, 89% cheaper.
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=600,
system=[
{
"type": "text",
"text": SYSTEM,
"cache_control": {"type": "ephemeral"}, # mark cacheable
}
],
messages=[{"role": "user", "content": question}],
)
# First call (cache write): 18,000 × $3.75 / 1M = $0.0675 (1.25× input)
# Calls 2–10 (cache hit): 18,000 × $0.30 / 1M = $0.0054 each
# Total: $0.0675 + 9 × $0.0054 = $0.116 (was $0.54 — 78.5% saved)Anda baru saja menghemat 78,5% biaya input pada sesi ini. Panggilan pertama sebenarnya sedikit lebih mahal daripada versi naif (~1,25× tarif input untuk menulis cache). Panggilan 2 hingga 10 membayar 10% dari tarif. Titik baliknya ada pada panggilan 2 — pada panggilan 3 Anda sudah unggul. Pada panggilan 10, selisihnya sangat besar.
Gaya OpenAI: tidak perlu melakukan apa pun
Format OpenAI Chat Completions tidak memiliki bidang cache_control, karena OpenAI melakukan caching secara implisit di servernya sendiri. Claude tidak demikian — Claude hanya melakukan caching pada bagian yang ditandai titik henti. Jadi ketika Anda mengakses model Claude melalui /v1/chat/completions atau /v1/responses, Kunavo menetapkan titik henti atas nama Anda: satu titik henti bergulir pada pesan terakhir setelah percakapan memiliki setidaknya satu giliran asisten, lalu satu setelah system dan satu setelah tools. Pesan system atau developer yang dikirim setelah jawaban pertama model tetap berada di dalam percakapan alih-alih diangkat ke system (kecuali titik henti miliknya sendiri meminta cache satu jam). Jika permintaan diakhiri dengan pesan seperti itu, titik henti bergulir diletakkan pada blok tepat sebelum pesan tersebut, dan sisa jatah titik henti diletakkan sebelum pesan-pesan semacam itu yang masih diikuti konten lain, dimulai dari yang paling akhir. Apa pun yang Anda tetapkan sendiri dibiarkan tepat di tempatnya — Kunavo hanya mengisi posisi yang Anda biarkan kosong, dan hanya hingga batas 4. Tidak ada yang perlu dikonfigurasi, dan model yang sama berbiaya sama baik Anda masuk melalui jalur Anthropic maupun OpenAI:
# OpenAI Chat Completions style — Kunavo sets the breakpoints for you.
# No flag to set. The "usage" object tells you what was cached.
from openai import OpenAI
client = OpenAI(
api_key="sk-kn-...",
base_url="https://api.kunavo.com/v1",
)
resp = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[
{"role": "system", "content": LONG_SYSTEM_PROMPT}, # >1024 tokens
{"role": "user", "content": "Latest question…"},
],
)
# In the response:
# resp.usage.prompt_tokens_details.cached_tokens → 17,800
# resp.usage.prompt_tokens → 18,200
# 17.8K/18.2K = 98% of input came from cache. Bill reflects that automatically.Baca usage.prompt_tokens_details.cached_tokens untuk melihat berapa banyak yang disajikan dari cache. Awalan tetap yang lebih besar berarti penghematan lebih besar. Aturan praktisnya: jika prompt sistem lebih pendek daripada konten pengguna yang berubah-ubah, caching tidak banyak membantu. Susun ulang prompt agar bagian statis berukuran besar dan berada di awal.
Caching multilapis — hingga 4 titik henti
Untuk loop agen yang beberapa lapisnya berubah lebih cepat daripada lapisan lain, tetapkan beberapa titik henti cache_control. Masing-masing merupakan snapshot dari segala sesuatu hingga titik tersebut:
# Anthropic supports up to 4 cache breakpoints per request — use them
# to keep the cache hot even as later layers change.
client.messages.create(
model="claude-sonnet-4-6",
max_tokens=600,
system=[
{"type": "text",
"text": ROLE_AND_RULES, # ~3,000 tokens
"cache_control": {"type": "ephemeral"}}, # breakpoint 1
{"type": "text",
"text": LARGE_KNOWLEDGE_BASE, # ~15,000 tokens, rarely changes
"cache_control": {"type": "ephemeral"}}, # breakpoint 2
],
messages=[
{"role": "user",
"content": [
{"type": "text",
"text": CONVERSATION_HISTORY, # grows each turn
"cache_control": {"type": "ephemeral"}}, # breakpoint 3
{"type": "text", "text": new_question},
]},
],
)
# When CONVERSATION_HISTORY changes, breakpoints 1+2 still hit cache.
# Only breakpoint 3 + the new question pay full input rate.Kunci cache adalah seluruh awalan. Menambahkan token pada posisi N membatalkan setiap titik henti pada atau setelah N. Urutan penting: konten paling stabil terlebih dahulu. Lapisan aturan seharusnya jarang berubah; basis pengetahuan diperbarui setiap minggu; percakapan bertambah setiap giliran.
Cara umum merusak caching secara diam-diam
- Memasukkan tanggal saat ini atau request_id ke dalam prompt. Setiap panggilan menjadi awalan baru, sehingga tingkat cache hit adalah 0%. Hash input prompt dan bandingkan hasilnya antar-panggilan.
- Perakitan prompt sistem yang nondeterministik. Jika Anda membangun sistem dari dict, urutan iterasi dict penting pada beberapa versi Python. Urutkan kunci secara eksplisit.
- Masa berlaku cache sekitar 5 menit. Pola lalu lintas jarang (satu panggilan setiap 10 menit) tidak memperoleh hit. Kelompokkan panggilan atau terima kerugiannya.
- Minimum 1.024 token. Di bawah 1K token, caching gaya OpenAI tidak aktif. Gabungkan fragmen statis kecil menjadi satu awalan yang lebih panjang.
- Definisi alat / fungsi merupakan bagian dari awalan. Alat baru yang ditambahkan ke katalog membatalkan cache untuk semua orang. Pertahankan katalog alat agar stabil; beri versinya.
Memverifikasi tingkat cache hit
Caching yang tidak dapat Anda lihat bukanlah rekayasa — itu hanya harapan. Catat usage pada setiap panggilan:
# Always read usage. If cached_tokens is 0 when you expected a hit,
# something's wrong — usually a non-deterministic prefix.
resp = client.messages.create(...)
u = resp.usage
print({
"input_uncached": u.input_tokens,
"input_cache_read": u.cache_read_input_tokens,
"input_cache_write": u.cache_creation_input_tokens,
"output": u.output_tokens,
})
# A common gotcha: putting today's date or a request_id in the system prompt
# silently invalidates the cache. Hash your inputs; verify cache_read_input_tokens
# is non-zero on the 2nd identical call.Di dasbor Kunavo, halaman Usage menampilkan pembagian cache per model per hari. Jika cache_read_input_tokens meningkat sebagai persentase dari total input, caching berfungsi. Jika tetap 0 atau berfluktuasi liar, telusuri daftar masalah di atas.
Biaya sebenarnya di Kunavo
Tarif cache setiap model dipublikasikan di halaman pricing:
- Model Anthropic: pembacaan cache sebesar 10% dari tarif input — 2,5% di Claude Fable 5.1, 5% di Claude Opus 5.5. Penulisan cache sebesar 1,25× tarif input — pengali lima menit Anthropic — dan Kunavo menagih penulisan satu jam dengan 1,25× yang sama, di bawah 2× milik Anthropic.
- Model OpenAI / Gemini: pembacaan cache sebesar 10% dari tarif input (rasio yang dipublikasikan penyedia). Penulisan cache sebesar 1,25× pada GPT-5.6 dan GPT-6 Astra, serta tarif input biasa pada semua model lainnya.
- Semua harga cache sudah mencakup diskon model Kunavo (di bawah harga upstream berdasarkan model). Jadi pembacaan cache Sonnet 4.6 di Kunavo adalah
$3 × 0.40 × 0.10 = $0.12 per 1M tokens. Sekitar 25× lebih murah daripada tarif upstream tanpa cache.
Saat caching bukan jawabannya
Beberapa kasus ketika pengerjaannya tidak sepadan:
- Prompt pendek (<1K token total). Overhead mendominasi; tidak perlu menggunakannya.
- Tugas sekali jalan tanpa lalu lintas berulang. Panggilan pertama sedikit lebih mahal — caching baru terbayar mulai panggilan 2+.
- Tugas dengan output tinggi dan input rendah (penulisan kreatif, pembuatan kode). Input sudah merupakan bagian kecil dari tagihan. Fokuslah pada batas anggaran output.
Untuk hal lainnya — chatbot RAG, agen dengan katalog alat tetap, classifier yang berjalan pada rubrik statis, pipeline ekstraksi terstruktur dengan few-shot konsisten — caching adalah optimasi ROI tertinggi yang dapat Anda terapkan dalam satu sore. Padukan dengan empat teknik lain dalam panduan optimasi biaya kami dan pengurangan biaya 70% realistis tanpa satu pun kompromi pada kualitas output.
Sudah menggunakan Kunavo? Buka /app/usage dan periksa kolom cache untuk model terbesar Anda. Jika nilainya nol, Anda membuang peluang menghemat biaya. Panduan lengkap: /docs/caching.