Je AI-applicatie draait in productie. Elke API-aanroep stuurt hetzelfde lange systeembericht — duizenden tokens met instructies, persona-definities en few-shot voorbeelden — gevolgd door een kort gebruikersbericht. Het model verwerkt die hele context bij élke request opnieuw. Je maandelijkse factuur loopt op, de latency is hoger dan nodig, en eerlijk gezegd: je betaalt keer op keer voor exact dezelfde berekening. Dat voelt als geld weggooien.
Prompt caching lost dit probleem op. Het is misschien wel de meest onderschatte optimalisatie die je kunt toepassen op LLM-applicaties — geen modelaanpassingen, geen architectuurwijzigingen, en vaak slechts een paar regels code. In deze handleiding leer je hoe prompt caching werkt bij OpenAI, Anthropic en Google, en implementeer je het stap voor stap met werkende Python-code.
Wat Is Prompt Caching en Waarom Maakt Het Zoveel Uit?
Wanneer je een prompt naar een LLM stuurt, verwerkt het model de tekst token voor token. Bij elke laag in het transformer-netwerk worden zogenaamde Key-Value (KV) tensoren berekend — de wiskundige representaties die het model nodig heeft om de relaties tussen tokens te begrijpen. Dit is veruit het meest rekenintensieve deel van het hele inferentieproces.
Prompt caching slaat deze KV-tensoren op na de eerste verwerking. Simpel gezegd: bij volgende requests met dezelfde prefix hoeft het model die berekening niet opnieuw uit te voeren. Het laadt de opgeslagen toestand en gaat verder waar het gebleven was.
Het resultaat spreekt voor zich:
- 50–90% lagere kosten voor input tokens (afhankelijk van de provider)
- Tot 80% lagere latency doordat het model minder rekenwerk verricht
- Identieke output-kwaliteit — er wordt niets weggelaten of vereenvoudigd
Dat laatste punt is belangrijk. Je levert geen kwaliteit in. Het model produceert exact dezelfde output — je betaalt alleen minder voor het rekenwerk dat al eerder is gedaan.
Volgens recent onderzoek overschrijdt 53% van AI-teams hun kostenprognose met 40% of meer tijdens het opschalen. Prompt caching is, zonder overdrijving, de optimalisatie met de hoogste ROI om dit te voorkomen.
Hoe Prompt Caching Technisch Werkt
De kernmechaniek is bij alle providers vergelijkbaar, al verschilt de implementatie nogal. Het basisprincipe in drie stappen:
- Eerste request — Je stuurt een prompt (systeem + gebruiker). Het model verwerkt de volledige prompt en genereert KV-tensoren. De provider slaat deze tensoren op als cache-entry, gekoppeld aan de exacte tokenreeks.
- Volgende request — Je stuurt een prompt met dezelfde prefix (bijvoorbeeld hetzelfde systeembericht). De provider detecteert een prefix-match, laadt de opgeslagen KV-tensoren, en het model hoeft alleen de nieuwe tokens te verwerken.
- Cache-expiratie — Na een bepaalde periode zonder gebruik (typisch 5 minuten tot 24 uur, afhankelijk van de provider) wordt de cache automatisch opgeruimd.
Nu komt het cruciale detail waar veel ontwikkelaars over struikelen: caching werkt op basis van exacte prefix-matching. Elke wijziging in het gecachede deel — zelfs een extra spatie of een aangepaste timestamp — veroorzaakt een cache-miss en dwingt volledige herverwerking af. Dit heeft directe gevolgen voor hoe je je prompts structureert.
De Gouden Regel: Statisch Bovenaan, Dynamisch Onderaan
Om cache-hits te maximaliseren, structureer je prompts altijd zo:
- Tools/functies (volledig statisch)
- Systeembericht (statisch — geen timestamps, request-IDs of gebruikersnamen)
- Few-shot voorbeelden (statisch)
- Context/documenten (variabel per sessie, maar stabiel binnen een sessie)
- Gebruikersbericht (dynamisch per request)
Hoe meer tokens er in het statische prefix zitten, hoe groter de besparing bij elke cache-hit. Klinkt logisch, maar je zou verbaast zijn hoe vaak mensen een timestamp in hun systeembericht proppen en zich dan afvragen waarom caching niet werkt.
OpenAI: Automatische Prompt Caching
OpenAI's implementatie is de meest laagdrempelige: caching werkt volledig automatisch op alle GPT-4o en nieuwere modellen. Je hoeft letterlijk geen code aan te passen — het werkt gewoon.
Hoe het werkt
- Minimale drempel: 1.024 tokens, met cache-stappen van 128 tokens
- Korting: 50% op gecachede input tokens
- Cache-levensduur: 5–10 minuten inactiviteit (tot 1 uur in rustige perioden)
- Uitgebreide retentie: optioneel tot 24 uur met extended caching
- Geen extra kosten voor het gebruik van de cache-functie
Python-implementatie
from openai import OpenAI
client = OpenAI()
# Definieer een lang, statisch systeembericht
SYSTEM_PROMPT = """Je bent een juridisch assistent gespecialiseerd in Nederlands
contractenrecht. Je analyseert contracten op risico's, ontbrekende clausules
en juridische inconsistenties.
Richtlijnen:
- Verwijs altijd naar specifieke artikelen uit het Burgerlijk Wetboek
- Geef risicobeoordelingen op een schaal van 1-5
- Structureer je analyse in categorieën: partijen, verplichtingen,
aansprakelijkheid, beëindiging, geschillenbeslechting
- Gebruik formele juridische terminologie
[Hier volgen uitgebreide voorbeeldanalyses van 2000+ tokens...]
"""
def analyseer_contract(contract_tekst: str) -> str:
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": f"Analyseer dit contract:\n\n{contract_tekst}"}
],
temperature=0.2
)
# Monitor cache-prestaties
usage = response.usage
cached = usage.prompt_tokens_details.cached_tokens
total_input = usage.prompt_tokens
print(f"Totaal input tokens: {total_input}")
print(f"Gecachede tokens: {cached}")
print(f"Cache-hit ratio: {cached / total_input:.1%}")
return response.choices[0].message.content
# Eerste aanroep: cache wordt aangemaakt (geen korting)
result1 = analyseer_contract("Contract A tekst...")
# → Gecachede tokens: 0, Cache-hit ratio: 0.0%
# Tweede aanroep: cache-hit! 50% korting op gecachede tokens
result2 = analyseer_contract("Contract B tekst...")
# → Gecachede tokens: 2048, Cache-hit ratio: 85.3%
Het enige wat je hoeft te doen is het usage-veld in de response monitoren. Het veld prompt_tokens_details.cached_tokens vertelt je precies hoeveel tokens uit de cache zijn gelezen. Makkelijker wordt het niet.
Anthropic Claude: Handmatige Cache-Controle
Anthropic pakt het anders aan. Je krijgt meer controle over wat er gecached wordt via de cache_control parameter. Dat vereist wel codewijzigingen, maar het biedt ook meer voorspelbare besparingen — en een fors hogere korting van 90% op cache-reads. Dat is bijna gratis vergeleken met volledige verwerking.
Specificaties
- Minimale drempel: 1.024 tokens (Claude Sonnet/Opus), 2.048 tokens (Claude Haiku)
- Korting op cache-reads: 90% (slechts 10% van de normale input-tokenprijs)
- Cache-schrijfkosten: 25% toeslag (5-min cache) of 100% toeslag (1-uur cache)
- Cache-levensduur: 5 minuten (standaard) of 1 uur (met
ttl: "1h") - Maximaal 4 cache-breekpunten per request
Python-implementatie
import anthropic
client = anthropic.Anthropic()
# Groot statisch systeembericht met cache-markering
SYSTEM_PROMPT = [
{
"type": "text",
"text": """Je bent een senior data-engineer die SQL-query's optimaliseert.
Je analyseert query-plannen, identificeert bottlenecks en stelt concrete
verbeteringen voor. Je hebt diepgaande kennis van PostgreSQL, MySQL en
BigQuery optimalisatiestrategieën.
[Hier volgen uitgebreide voorbeelden, schema-documentatie en
optimalisatiepatronen van 3000+ tokens...]""",
"cache_control": {"type": "ephemeral"} # 5 minuten cache
}
]
def optimaliseer_query(sql_query: str) -> str:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
system=SYSTEM_PROMPT,
messages=[
{"role": "user", "content": f"Optimaliseer deze query:\n\n{sql_query}"}
]
)
# Gedetailleerde cache-monitoring
usage = response.usage
print(f"Input tokens: {usage.input_tokens}")
print(f"Cache aangemaakt (write): {usage.cache_creation_input_tokens}")
print(f"Cache gelezen (read): {usage.cache_read_input_tokens}")
print(f"Output tokens: {usage.output_tokens}")
return response.content[0].text
# Eerste aanroep: cache wordt geschreven
result1 = optimaliseer_query("SELECT * FROM orders WHERE date > '2024-01-01'")
# → Cache aangemaakt: 3200, Cache gelezen: 0
# Volgende aanroepen: 90% korting op het systeembericht
result2 = optimaliseer_query("SELECT u.name, COUNT(o.id) FROM users u JOIN orders o...")
# → Cache aangemaakt: 0, Cache gelezen: 3200
1-Uur Cache voor Lagere Frequentie
Als je systeembericht minder dan eens per 5 minuten wordt gebruikt, is de standaard TTL te kort. Je cache verloopt dan steeds voordat de volgende request binnenkomt. Sinds 2026 ondersteunt Anthropic een verlengde TTL van 1 uur:
# Verlengde cache voor minder frequente workloads
SYSTEM_PROMPT = [
{
"type": "text",
"text": "Je uitgebreide systeeminstructies hier...",
"cache_control": {
"type": "ephemeral",
"ttl": "1h" # 1 uur cache, schrijfkosten 2x normaal
}
}
]
De 1-uur cache kost 2x de normale input-tokenprijs bij het schrijven, maar als je de cache minstens 3 keer hergebruikt, is het al goedkoper dan zonder caching. In de praktijk haal je dat break-even punt vrij snel.
Meerdere Cache-Breekpunten
Een feature van Anthropic die ik persoonlijk erg handig vind, is de mogelijkheid om tot 4 cache-breekpunten te plaatsen. Dit werkt bijzonder goed wanneer je zowel statische instructies als sessie-specifieke documenten wilt cachen:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
system=[
{
"type": "text",
"text": "Statische systeem-instructies (altijd hetzelfde)...",
"cache_control": {"type": "ephemeral"} # Breekpunt 1
}
],
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": "Groot document dat binnen een sessie stabiel is...",
"cache_control": {"type": "ephemeral"} # Breekpunt 2
},
{
"type": "text",
"text": "De eigenlijke vraag van de gebruiker"
}
]
}
]
)
Op deze manier worden zowel de instructies als het document gecached. Bij vervolgvragen over hetzelfde document profiteer je maximaal van caching — en dat merk je direct in je factuur.
Google Gemini: Expliciet en Impliciet Caching
Google biedt twee varianten: impliciete caching (automatisch, zonder garantie) en expliciete caching (handmatig, met gegarandeerde korting). De expliciete variant is wat mij betreft het interessantst vanwege de enorme korting op nieuwere modellen.
Specificaties
- Impliciete caching: automatisch, geen codewijzigingen, geen kostengarantie
- Expliciete caching: handmatig, gegarandeerde korting, opslagkosten
- Korting (Gemini 2.5+): 90% op gecachede input tokens
- Korting (Gemini 2.0): 75% op gecachede input tokens
- Standaard TTL: 1 uur (aanpasbaar)
Python-implementatie met Expliciete Cache
from google import genai
from google.genai import types
client = genai.Client()
# Stap 1: Maak een cache aan met je statische context
cache = client.caches.create(
model="gemini-2.5-flash",
config=types.CreateCachedContentConfig(
display_name="product-catalogus-analyse",
system_instruction="""Je bent een product-analist die productcatalogi
analyseert op prijsstrategieën, marktpositionering en concurrentievoordelen.
Gebruik de bijgevoegde catalogusdata als referentie.""",
contents=[
types.Content(
role="user",
parts=[types.Part(text="[Grote productcatalogus van 50.000+ tokens...]")]
)
],
ttl="3600s" # 1 uur
)
)
print(f"Cache aangemaakt: {cache.name}")
print(f"Token count: {cache.usage_metadata.total_token_count}")
# Stap 2: Gebruik de cache voor meerdere analyses
from google.genai.types import GenerateContentConfig
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Welke producten hebben de hoogste marge?",
config=GenerateContentConfig(
cached_content=cache.name
)
)
print(response.text)
# Stap 3: Opruimen wanneer je klaar bent
client.caches.delete(name=cache.name)
Het grote voordeel van Google's expliciete caching is dat je de TTL volledig zelf bepaalt en dat de cache los staat van individuele requests. Dat maakt het ideaal voor batchverwerking waarbij je dezelfde context uren achtereen nodig hebt.
Vergelijking: Welke Provider Kies Je?
Goed, dit is de vraag die iedereen stelt. De keuze hangt af van je use case. Hier is een directe vergelijking:
| Kenmerk | OpenAI | Anthropic | Google Gemini |
|---|---|---|---|
| Type | Automatisch | Handmatig | Impliciet + Expliciet |
| Codewijzigingen nodig | Nee | Ja | Nee (impliciet) / Ja (expliciet) |
| Korting cache-reads | 50% | 90% | 75–90% |
| Cache-schrijfkosten | Geen extra | 25–100% toeslag | Standaard tokenprijs + opslag |
| Standaard TTL | 5–10 min | 5 min / 1 uur | 1 uur |
| Max TTL | 24 uur | 1 uur | Onbeperkt (zolang je betaalt) |
| Min. tokens | 1.024 | 1.024–2.048 | Varieert per model |
Kies OpenAI als je minimale implementatie-inspanning wilt en al GPT-4o gebruikt. De 50% korting is minder dan Anthropic, maar het vereist letterlijk nul codewijzigingen. Plug and play.
Kies Anthropic als je maximale kostenbesparing wilt en bereid bent je code aan te passen. De 90% korting op cache-reads is simpelweg de hoogste in de markt.
Kies Google Gemini als je lange cache-levensduren nodig hebt (uren tot dagen) of grote documenten analyseert in batch-workflows. De flexibele TTL is hier echt een pluspunt.
Prompt Caching vs. Semantic Caching: Wat Is het Verschil?
Dit is een veelgemaakte fout die ik regelmatig tegenkom: prompt caching verwarren met semantic caching. Het zijn fundamenteel andere technieken — maar ze vullen elkaar mooi aan.
Prompt caching (provider-niveau) slaat de KV-tensoren van de prompt-prefix op. Het model voert nog steeds inferentie uit voor de nieuwe tokens — je bespaart op de input-verwerking.
Semantic caching (applicatie-niveau) slaat volledige vraag-antwoord-paren op en matcht nieuwe vragen op basis van semantische gelijkenis via embeddings. Bij een hit wordt de LLM helemaal niet aangeroepen — je krijgt direct het gecachede antwoord terug.
De meest effectieve strategie? Combineer beide. Semantic caching vangt herhaalde (of vergelijkbare) vragen op, en prompt caching verlaagt de kosten voor alles wat doorkomt naar het model. Onderzoek toont aan dat deze "double caching"-aanpak een totale kostenbesparing van 60–90% kan opleveren.
Veelgemaakte Fouten en Hoe Je Ze Voorkomt
Na het werken met prompt caching in diverse projecten zijn dit de fouten die je het vaakst tegenkomt (en waar je jezelf mee kunt besparen):
1. Dynamische Content in het Systeembericht
Dit is veruit de meest voorkomende fout. Eén dynamisch element en je cache is waardeloos.
# FOUT: timestamp breekt de cache bij elke aanroep
system_msg = f"Je bent een assistent. Huidige tijd: {datetime.now()}"
# GOED: houd het systeembericht 100% statisch
system_msg = "Je bent een assistent die vragen beantwoordt."
# Verplaats dynamische info naar het gebruikersbericht
2. Volgorde van Content Wijzigen
# FOUT: few-shot voorbeelden in willekeurige volgorde
import random
examples = random.sample(all_examples, 5)
# GOED: altijd dezelfde volgorde
examples = sorted(all_examples, key=lambda x: x["id"])[:5]
3. Cache-Metrics Niet Monitoren
Je kunt niet optimaliseren wat je niet meet. Bouw daarom een simpele monitor:
# Bouw een simpele monitor
class CacheMonitor:
def __init__(self):
self.total_requests = 0
self.total_cached_tokens = 0
self.total_input_tokens = 0
def log_request(self, usage):
self.total_requests += 1
# Werkt voor OpenAI
if hasattr(usage, "prompt_tokens_details"):
cached = usage.prompt_tokens_details.cached_tokens or 0
# Werkt voor Anthropic
elif hasattr(usage, "cache_read_input_tokens"):
cached = usage.cache_read_input_tokens or 0
else:
cached = 0
self.total_cached_tokens += cached
self.total_input_tokens += usage.input_tokens if hasattr(usage, "input_tokens") else usage.prompt_tokens
def report(self):
ratio = self.total_cached_tokens / max(self.total_input_tokens, 1)
print(f"Totaal requests: {self.total_requests}")
print(f"Cache-hit ratio: {ratio:.1%}")
print(f"Geschatte besparing: ~{ratio * 50:.0f}–{ratio * 90:.0f}%")
monitor = CacheMonitor()
4. Te Kort Systeembericht
Prompt caching heeft een minimale tokendrempel. Als je systeembericht korter is dan 1.024 tokens (OpenAI/Anthropic Sonnet) of 2.048 tokens (Anthropic Haiku), wordt er simpelweg niet gecached. Niets. Nul. Overweeg in dat geval om few-shot voorbeelden of referentiedocumentatie aan het systeembericht toe te voegen — dat helpt trouwens vaak ook de output-kwaliteit.
Productiepatroon: RAG met Prompt Caching
Dit is waar het echt interessant wordt. Een van de krachtigste combinaties is prompt caching met RAG-pipelines. In een typische RAG-setup heb je een groot, statisch systeembericht plus opgehaalde documenten die per sessie stabiel zijn. Met Anthropic's meervoudige cache-breekpunten kun je beide lagen cachen:
import anthropic
client = anthropic.Anthropic()
def rag_met_caching(documenten: list[str], vragen: list[str]) -> list[str]:
"""
Verwerk meerdere vragen over dezelfde set documenten.
De systeem-instructies en documenten worden gecached.
"""
# Combineer opgehaalde documenten tot één context-blok
context = "\n\n---\n\n".join(documenten)
antwoorden = []
for vraag in vragen:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=[
{
"type": "text",
"text": """Je bent een kennisassistent. Beantwoord vragen
uitsluitend op basis van de aangeleverde documenten. Citeer relevante
passages. Als het antwoord niet in de documenten staat, zeg dat eerlijk.""",
"cache_control": {"type": "ephemeral"}
}
],
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": f"Documenten:\n\n{context}",
"cache_control": {"type": "ephemeral"}
},
{
"type": "text",
"text": f"Vraag: {vraag}"
}
]
}
]
)
antwoorden.append(response.content[0].text)
# Log cache-prestaties
u = response.usage
print(f"Vraag: {vraag[:50]}...")
print(f" Cache read: {u.cache_read_input_tokens} tokens")
print(f" Nieuwe tokens: {u.input_tokens} tokens\n")
return antwoorden
# Gebruik: 10 vragen over dezelfde documenten
docs = ["Document 1 inhoud...", "Document 2 inhoud...", "Document 3 inhoud..."]
vragen = [
"Wat zijn de belangrijkste conclusies?",
"Welke risico's worden genoemd?",
"Wat is de aanbevolen aanpak?",
# ... meer vragen
]
resultaten = rag_met_caching(docs, vragen)
# Eerste vraag: cache wordt aangemaakt
# Vraag 2-10: 90% korting op systeem + documenten
Bij 10 vragen over dezelfde documentset betaal je de volledige prijs slechts één keer. De overige 9 aanroepen krijgen 90% korting op het hele context-blok. Bij grote documenten praat je dan al snel over duizenden tokens aan besparingen per aanroep.
Kosten Berekenen: Wanneer Loont Prompt Caching?
Laten we een concreet rekenvoorbeeld doorlopen met Anthropic Claude Sonnet (basis: $3/MTok input). Want eerlijk gezegd, het gaat uiteindelijk altijd om de cijfers.
Scenario: 100 API-aanroepen per uur, systeembericht van 4.000 tokens, gebruikersbericht van 200 tokens.
Zonder caching:
- 100 × 4.200 tokens = 420.000 input tokens/uur
- Kosten: 420.000 × $3/MTok = $1,26/uur
Met 5-min caching (90% cache-hit rate):
- 10 cache-writes: 10 × 4.000 × $3,75/MTok = $0,15
- 90 cache-reads: 90 × 4.000 × $0,30/MTok = $0,108
- 100 niet-gecachede tokens: 100 × 200 × $3/MTok = $0,06
- Totaal: $0,32/uur
Dat is een besparing van 75%. En dit wordt alleen maar groter naarmate je systeembericht langer is of je request-frequentie hoger. Bij sommige productie-workloads die ik heb gezien, liep de besparing op tot ver boven de 85%.
Beveiligingsoverwegingen
Even een serieuze noot tussendoor. Prompt caching heeft beveiligingsimplicaties die je moet kennen. Onderzoekers van Stanford hebben aangetoond dat bij sommige providers gecachede data gedeeld wordt tussen gebruikers. Uit timingverschillen (een cache-hit is sneller dan een cache-miss) kunnen aanvallers met tot 99% nauwkeurigheid afleiden welke prompts andere gebruikers versturen.
Sinds februari 2026 isoleert Anthropic caches op workspace-niveau in plaats van organisatieniveau. Dat is een duidelijke verbetering, maar houd rekening met het volgende:
- Verwerk geen gevoelige data (PII, medische gegevens, financiële data) in gecachede prompts zonder de data-residency policy van je provider te begrijpen
- Gebruik aparte workspaces voor verschillende projecten of klanten
- Monitor cache-timing als onderdeel van je beveiligingsaudits
Veelgestelde Vragen
Hoeveel kan prompt caching besparen op LLM-kosten?
De besparing hangt af van je provider en gebruik. OpenAI biedt 50% korting op gecachede tokens, Anthropic biedt 90% korting op cache-reads, en Google Gemini biedt 75–90% korting afhankelijk van het model. In de praktijk realiseren de meeste applicaties een totale kostenbesparing van 50–80% op input tokens, mits de prompts goed gestructureerd zijn met statische content aan het begin.
Moet ik mijn code aanpassen voor prompt caching?
Bij OpenAI niet — caching werkt volledig automatisch op GPT-4o en nieuwere modellen. Bij Anthropic moet je cache_control parameters toevoegen aan je systeem- en gebruikersberichten. Bij Google Gemini kun je kiezen: impliciete caching vereist geen wijzigingen, expliciete caching vereist het aanmaken en refereren van cache-objecten.
Wat is het verschil tussen prompt caching en semantic caching?
Prompt caching werkt op provider-niveau en slaat de interne berekeningen (KV-tensoren) van prompt-prefixen op — het model voert nog steeds inferentie uit voor nieuwe content. Semantic caching werkt op applicatie-niveau en slaat volledige vraag-antwoord-paren op, waardoor de LLM bij een hit helemaal niet wordt aangeroepen. De slimste aanpak? Combineer beide.
Hoe lang blijft een prompt cache actief?
Bij OpenAI verloopt de cache na 5–10 minuten inactiviteit (uitbreidbaar tot 24 uur). Bij Anthropic is de standaard TTL 5 minuten (verlengbaar tot 1 uur). Bij Google Gemini is de standaard TTL voor expliciete caches 1 uur, maar dit is volledig aanpasbaar — je kunt caches dagen of zelfs weken actief houden, al betaal je dan wel opslagkosten.
Kan prompt caching de output-kwaliteit beïnvloeden?
Nee, absoluut niet. Prompt caching beïnvloedt uitsluitend de verwerking van input tokens, niet het generatieproces. De opgeslagen KV-tensoren zijn wiskundig identiek aan wat het model bij volledige verwerking zou berekenen. De output is exact hetzelfde — je betaalt alleen minder voor het rekenwerk dat al eerder is gedaan.