Prompt Caching mit der Claude API: Senke deine Input-Kosten, ohne das Modell zu wechseln
Prompt Caching senkt die Kosten großer, stabiler Inputs — dein System-Prompt, Tool-Definitionen, Few-Shot-Beispiele — bei wiederholten Anfragen auf rund 10 % des normalen Input-Preises. Der Mechanismus ist ein Prefix-Match: Setze einen cache_control-Marker an das Ende deines stabilen Inhalts und halte alles Veränderliche danach. Der Fehler, der die Cache-Trefferquote killt, ist es, einen Zeitstempel oder eine UUID in den Prefix einsickern zu lassen.
Jeden Mittwoch. 28.400+ Experten. Kein Füllstoff.
✓ Prüfen Sie Ihr Postfach — klicken Sie auf den Bestätigungslink, um die Anmeldung abzuschließen.
✓ Sie sind angemeldet!
✓ Sie stehen bereits auf der Liste.
Table of contents
Open Table of contents
- Was Prompt Caching wirklich macht
- Die Prefix-Match-Invariante
- Worauf du einen Cache-Marker setzt
- Was du NICHT cachen solltest (stille Cache-Killer)
- So überprüfst du deine Cache-Trefferquote
- Die 1-Stunden-TTL: wann sich die höheren Write-Kosten lohnen
- Pre-Warming: die erste Anfrage günstig machen
- Prompt Caching in agentischen Schleifen
- Wie es auf der Rechnung aussieht
- Das Fazit des Operators
Was Prompt Caching wirklich macht
Jeder Aufruf der Claude API sendet Tokens. Ohne Caching wird jedes Token deiner Anfrage — System-Prompt, Tool-Definitionen, Few-Shot-Beispiele und die User-Nachricht — zum normalen Input-Tarif berechnet. Mit Caching wird ein Prefix dieser Tokens nach der ersten Anfrage auf den Servern von Anthropic gespeichert. Bei folgenden Anfragen, die genau diesen Prefix teilen, zahlst du einen Cache-Read-Preis, statt sie von Grund auf neu zu verarbeiten.
Der Kostenunterschied ist real:
- Cache Write: ~1,25× Basis-Input-Preis (5-Minuten-TTL) oder ~2× (1-Stunden-TTL)
- Cache Read: ~0,1× Basis-Input-Preis
- Break-even: 2 Anfragen bei 5-Minuten-TTL, 3 Anfragen bei 1-Stunden-TTL
Sobald du den Break-even überschritten hast — was bei jedem Agenten, der mehr als ein paar Mal pro Tag läuft, schnell passiert —, ist jeder weitere Cache-Treffer ein Rabatt von ~90 % auf diese Tokens.
Die Prefix-Match-Invariante
Das ist die eine Regel, der alles andere folgt: Der Cache-Schlüssel ist ein Prefix-Match deines gerenderten Prompts.
Die Server von Anthropic speichern den gerenderten Inhalt vom Anfang deines Prompts bis zum cache_control-Marker. Damit es bei der nächsten Anfrage zu einem Cache-Treffer kommt, muss jedes Token vom Anfang des Prompts bis zu diesem Marker identisch sein — Byte für Byte.
Die Render-Reihenfolge für das Prefix-Matching ist: tools → system → messages. Dein tools-Array wird also zuerst gehasht, dann der system-Block, dann die messages der Reihe nach.
Was das in der Praxis bedeutet: Stabiler Inhalt muss zuerst kommen. Wenn dein System-Prompt irgendetwas Dynamisches referenziert — ein aktuelles Datum, eine User-ID, eine Request-Trace-ID — und es vor dem cache_control-Marker erscheint, verfehlt der Cache bei jeder Anfrage, weil sich der Prefix ständig ändert.
Worauf du einen Cache-Marker setzt
Die wirkungsvollsten Ziele sind:
1. Dein System-Prompt
System-Prompts sind in der Regel der größte stabile Block. Eine detaillierte Agenten-Persona, eine Liste von Verhaltensregeln, ein Satz an Anweisungen zum Output-Format — all das ist bei jeder Ausführung desselben Agenten identisch. Markiere es:
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const response = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 1024,
system: [
{
type: "text",
text: `You are a content operations agent for alejandrorioja.com.
Your job is to draft blog posts in Alejandro's voice: direct, practitioner,
first-person, numbered lists, honest caveats. No hedging. No filler.
Every section must earn its place.
[... 2000 more tokens of stable instructions ...]`,
cache_control: { type: "ephemeral" },
},
],
messages: [
{
role: "user",
content: "Draft a post about prompt caching.",
},
],
});Das cache_control: { type: "ephemeral" } auf dem system-Block weist Claude an, alles bis einschließlich dieses Blocks zu cachen. Das messages-Array ist veränderlich — bei jeder Anfrage anders — und bleibt außerhalb der Cache-Grenze.
2. Tool-Definitionen
Wenn dein Agent Tools nutzt, können diese Definitionen umfangreich sein. Ein gut dokumentiertes Tool-Schema mit Beschreibung, Parameternamen und Enum-Werten kann pro Tool 500–1.000 Tokens umfassen. Bei 5 Tools sind das bis zu 5.000 Tokens, die du bei jedem Aufruf erneut verarbeiten lässt:
const response = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 1024,
tools: [
{
name: "search_airtable",
description: "Search the Airtable content queue...",
input_schema: { type: "object", properties: { query: { type: "string" } } },
},
// ... more tools ...
{
name: "post_to_kit",
description: "Schedule a broadcast via the Kit API...",
input_schema: { /* ... */ },
// Mark the last tool to cache the entire tools array
} as Anthropic.Tool & { cache_control: { type: "ephemeral" } },
],
system: "...",
messages: [...],
});Markiere das letzte Tool im Array. Das Prefix-Match deckt das gesamte tools-Array ab diesem Punkt ab.
3. Few-Shot-Beispiele in messages
Wenn du statische Few-Shot-Beispiele als frühe Nachrichten im messages-Array übergibst, können auch diese gecacht werden. Strukturiere sie als die ersten N Nachrichten und markiere den letzten Beispiel-Turn:
const messages: Anthropic.MessageParam[] = [
{
role: "user",
content: [
{
type: "text",
text: "Here are examples of posts in my voice:\n\n[Example 1...]\n\n[Example 2...]",
cache_control: { type: "ephemeral" },
} as Anthropic.TextBlockParam & { cache_control: { type: "ephemeral" } },
],
},
{
role: "assistant",
content: "Understood. I'll follow that voice.",
},
// The actual user turn follows — this is volatile, no cache marker
{
role: "user",
content: actualUserRequest,
},
];Was du NICHT cachen solltest (stille Cache-Killer)
Das sind die Dinge, die stabil aussehen, es aber nicht sind — und sie ruinieren deine Trefferquote im Stillen. Die API warnt dich nicht. Du siehst einfach cache_creation_input_tokens bei jeder Anfrage und fragst dich, warum.
Zeitstempel im System-Prompt. Der mit Abstand häufigste Fehler:
// This invalidates the cache on every request
const system = `You are an agent. Current time: ${new Date().toISOString()}`;Verschiebe Zeitstempel in die User-Nachricht, wo sie hingehören:
// Stable system prompt — cacheable
const system = `You are an agent. Use the current time provided by the user.`;
// Volatile user message — not cached
const userMessage = `Current time: ${new Date().toISOString()}. Run the daily brief.`;Zufällige UUIDs und Trace-IDs. Dasselbe Problem. Wenn du eine Trace-ID zum Logging in den system-Block einfügst, bekommt jede Anfrage einen frischen Prefix.
Nicht-deterministische JSON-Serialisierung. Wenn du ein Objekt in den System-Prompt serialisierst und die Reihenfolge der Schlüssel nicht garantiert ist, kann der gerenderte String abweichen, selbst wenn die zugrunde liegenden Daten gleich sind. Serialisiere mit einer stabilen Schlüsselreihenfolge oder verwende einen Template-String.
Dynamische Few-Shot-Auswahl. Wenn du Few-Shot-Beispiele anhand der aktuellen Anfrage auswählst und sie in den gecachten Prefix legst, hast du den „stabilen” Prefix abfrageabhängig gemacht. Entscheide dich entweder für feste Beispiele in der Cache-Schicht oder verschiebe dynamische Beispiele in den ungecachten Message-Turn.
So überprüfst du deine Cache-Trefferquote
Jede Antwort enthält Usage-Metadaten. Prüfe sie:
const response = await client.messages.create({ /* ... */ });
console.log({
inputTokens: response.usage.input_tokens,
cacheRead: response.usage.cache_read_input_tokens,
cacheWrite: response.usage.cache_creation_input_tokens,
outputTokens: response.usage.output_tokens,
});Bei der ersten Anfrage: cache_creation_input_tokens ist ungleich null, cache_read_input_tokens ist 0. Das ist der Write.
Bei einem Cache-Treffer: cache_read_input_tokens ist ungleich null, cache_creation_input_tokens ist 0. Das ist der Read.
Wenn du bei jeder Anfrage cache_creation_input_tokens siehst, ändert sich dein Prefix. Füge eine Log-Anweisung hinzu, die vor jedem Aufruf die ersten 200 Zeichen deines gerenderten System-Prompts ausgibt — ein wandernder Zeitstempel springt dir sofort ins Auge.
Die 1-Stunden-TTL: wann sich die höheren Write-Kosten lohnen
Die Standard-TTL beträgt 5 Minuten. Wenn dein Agent mit niedriger Frequenz läuft — seltener als einmal alle 5 Minuten —, zahlst du bei den meisten Anfragen Cache-Write-Kosten, ohne Reads zu bekommen.
// Opt into a 1-hour TTL
cache_control: { type: "ephemeral", ttl: "1h" }Der 1-Stunden-Write kostet ~2× Basis-Input-Preis statt 1,25×. Die Rechnung: Wenn du den Cache 3 Mal oder öfter pro Stunde triffst, spart die 1-Stunden-TTL Geld. Wenn dein Agent einmal täglich läuft (wie mein Daily Brief), hilft selbst die 1-Stunden-TTL nicht — du zahlst jedes Mal Write-Kosten. In diesem Fall ist der Nutzen des Cachings bescheiden, es sei denn, der System-Prompt ist riesig.
Mein Daily-Brief-Agent hat einen 3.000-Token-System-Prompt, läuft aber einmal täglich. Caching hilft nicht. Mein Newsletter-Agent läuft während des Entwurfs dutzende Male pro Session — Caching spart erheblich.
Pre-Warming: die erste Anfrage günstig machen
Wenn du einen bekannten Traffic-Spike erwartest — einen Batch-Job, einen API-Launch —, kannst du den Cache mit einer kostengünstigen Dummy-Anfrage vorwärmen:
// Pre-warm: write the cache at near-zero output cost
await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 1, // minimal output
system: [{ type: "text", text: stableSystemPrompt, cache_control: { type: "ephemeral" } }],
messages: [{ role: "user", content: "ping" }],
});
// Now the real requests read from cacheDas ist vor allem bei der Batch-Verarbeitung nützlich, wenn du viele parallele Anfragen hochfährst und willst, dass jede einen warmen Cache trifft, statt um das Schreiben zu konkurrieren.
Prompt Caching in agentischen Schleifen
In einer mehrstufigen agentischen Schleife wächst der Gesprächsverlauf mit jedem Turn. Der Cache ist clever genug, um damit umzugehen: Er nutzt ein Lookback-Fenster von 20 Blöcken und findet den längsten passenden Prefix innerhalb der letzten 20 Content-Blöcke.
Die praktische Konsequenz: Halte deinen stabilen Inhalt (System-Prompt, Tool-Definitionen) oben verankert. Der wachsende Gesprächsverlauf am Ende des messages-Arrays bricht das Prefix-Match für die stabilen Blöcke nicht — sie stehen vor dem veränderlichen Inhalt, und das Prefix-Match beginnt von oben.
In der Praxis strukturieren meine Agenten die Turns so:
System (cached) → Tools (cached) → Few-shot (cached) → Turn 1 → Turn 2 → ... → Current turnDer Cache deckt alles bis zum Few-Shot-Marker ab. Der wachsende Turn-Verlauf danach wird jedes Mal neu verarbeitet, aber das ist in Ordnung — diese Tokens sind session-spezifisch und im Vergleich zum stabilen Prefix klein.
Wie es auf der Rechnung aussieht
Nimm einen hochfrequenten Agenten: 100 Aufrufe pro Tag, 4.000-Token-System-Prompt, Sonnet-Preise.
Ohne Caching:
- 100 × 4.000 Tokens × $3/1M = $1,20/Tag
Mit Caching (5-Minuten-TTL, angenommen 50 Aufrufe/Stunde zu Spitzenzeiten):
- 1 Write pro 5 Minuten × $3,75/1M × 4.000 Tokens = ~$0,02/Tag an Writes
- ~98 Reads/Tag × $0,30/1M × 4.000 Tokens = $0,12/Tag an Reads
Das ist eine Reduktion von rund 90 % auf diese Input-Tokens. Im großen Maßstab — 1.000 Aufrufe pro Tag — summiert sich der Unterschied weiter. Und das kommt noch obendrauf zu allen Einsparungen aus dem Modell-Routing à la Haiku-vs-Sonnet-Rechnung: Caching funktioniert auf jeder Stufe.
Das Fazit des Operators
Prompt Caching ist die einfachste Kostenoptimierung in der Claude API: ein zusätzliches Feld an den Content-Blöcken, die du ohnehin schon schreibst. Die Einschränkung ist Disziplin rund um die Prefix-Stabilität — nichts Dynamisches vor dem Cache-Marker. Wenn du deinen System-Prompt, deine Tools und alle statischen Beispiele frei von veränderlichem Inhalt hältst, zahlst du bei jedem Cache-Treffer ~10 % der normalen Input-Kosten. Für hochfrequente Agenten mit großen, stabilen Prompts ist das ein größerer Hebel als der Wechsel der Modellstufe.
Verwandt: AI Agent Cost Math: When Haiku Beats Sonnet · Event-Triggered vs Scheduled Agents · The 5 AI Tools I Actually Use to Run My Business
Jeden Mittwoch. 28.400+ Experten. Kein Füllstoff.
✓ Prüfen Sie Ihr Postfach — klicken Sie auf den Bestätigungslink, um die Anmeldung abzuschließen.
✓ Sie sind angemeldet!
✓ Sie stehen bereits auf der Liste.
Holen Sie sich das KI-Playbook in Ihr Postfach
Jeden Mittwoch. 28.400+ Experten. Kein Füllstoff.
Prüfen Sie Ihr Postfach.
Wir haben Ihnen eine Bestätigungs-E-Mail geschickt — klicken Sie auf den Link, um Ihre Anmeldung abzuschließen. Prüfen Sie den Spam-Ordner, falls sie nicht innerhalb einer Minute ankommt.
Sie sind angemeldet.
Willkommen — die nächste Ausgabe landet bald in Ihrem Postfach.
Sie stehen bereits auf der Liste — halten Sie jeden Mittwoch Ausschau.