Wenn du einen langen System-Prompt sendest – RAG-Kontext, einen Tool-Katalog, Agentenregeln, Beispiele –, zahlst du wahrscheinlich bei jedem Aufruf den vollen Eingabepreis. Anthropic reduziert ihn mit Prompt-Caching für den gecachten Teil auf 10 % des Preises. OpenAI macht dasselbe implizit. Die meisten Teams finden den Aufwand von 30 Minuten lohnenswert, weil sich die Eingabekosten zuverlässig um 60–90 % reduzieren lassen.
Kunavo unterstützt beides. Deine eigenen cache_control-Breakpoints werden unverändert durch die Messages API übertragen. Bei den Chat-Completions- und Responses-APIs, deren Format kein entsprechendes Feld zum Senden enthält, setzt Kunavo sie für dich und ergänzt sie um das, was du bereits gesendet hast, ohne das Limit von 4 zu überschreiten. Dieser Beitrag behandelt beide Varianten, die Fallstricke, durch die Caches unbemerkt ungültig werden, und die Überprüfung deiner Trefferquote.
Vorher und nachher
Eine naive Schleife, die denselben System-Prompt mit 18K Token zehnmal sendet:
# 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.Markiere den Systemblock jetzt als cachebar – ein zusätzliches Feld:
# 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)Du hast in dieser Sitzung 78.5 % der Eingabekosten eingespart. Der erste Aufruf ist tatsächlich etwas teurer als die naive Variante (~1.25× Eingabepreis, um den Cache zu schreiben). Die Aufrufe 2 bis 10 kosten 10 % des Preises. Der Break-even liegt bei Aufruf 2; ab Aufruf 3 bist du im Vorteil. Bei Aufruf 10 ist der Unterschied gewaltig.
OpenAI-Stil: nichts zu tun
Das OpenAI-Chat-Completions-Format besitzt kein Feld cache_control, weil OpenAI implizit auf den eigenen Servern cached. Claude tut das nicht – es cached nur, was ein Breakpoint markiert. Wenn du über /v1/chat/completions oder /v1/responses ein Claude-Modell erreichst, setzt Kunavo die Breakpoints daher für dich: einen rollierenden auf der letzten Nachricht, sobald die Konversation mindestens eine Assistentenantwort enthält, danach einen hinter system und einen hinter tools. Alles, was du selbst setzt, bleibt exakt an seiner Position. Kunavo füllt nur leere Positionen und höchstens bis zum Limit von 4. Es muss nichts konfiguriert werden, und dasselbe Modell kostet gleich viel, unabhängig davon, ob du über die Anthropic- oder OpenAI-Route kommst:
# 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.Lies usage.prompt_tokens_details.cached_tokens, um zu sehen, wie viel aus dem Cache bereitgestellt wurde. Je größer der feste Präfix, desto größer die Einsparung. Faustregel: Wenn dein System-Prompt kürzer ist als dein variabler Benutzerinhalt, bringt Caching wenig. Strukturiere den Prompt so um, dass die statischen Teile groß sind und am Anfang stehen.
Caching über mehrere Ebenen – bis zu 4 Breakpoints
Bei Agentenschleifen, in denen sich manche Ebenen schneller ändern als andere, setze mehrere cache_control-Breakpoints. Jeder ist eine Momentaufnahme von allem bis zu dieser Stelle:
# 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.Der Cache-Schlüssel ist der gesamte Präfix. Fügst du an Position N ein Token hinzu, werden alle Breakpoints ab N ungültig. Die Reihenfolge ist wichtig: zuerst die stabilsten Inhalte. Die Regelebene sollte sich selten ändern; die Wissensbasis wird wöchentlich aktualisiert; die Konversation wächst mit jeder Runde.
Häufige Wege, Caching unbemerkt zu unterbrechen
- Das aktuelle Datum oder eine request_id in den Prompt einfügen. Jeder Aufruf erzeugt einen neuen Präfix, die Cache-Trefferquote beträgt 0 %. Hash deine Prompt-Eingaben und vergleiche sie über mehrere Aufrufe hinweg.
- Nichtdeterministische Zusammenstellung des System-Prompts. Wenn du das System aus einem Dictionary aufbaust, ist die Iterationsreihenfolge in einigen Python-Versionen relevant. Sortiere die Schlüssel ausdrücklich.
- Die Cache-Lebensdauer beträgt etwa 5 Minuten. Bei spärlichem Datenverkehr (ein Aufruf alle 10 Minuten) gibt es keine Treffer. Bündele entweder Aufrufe oder akzeptiere den Verlust.
- Das Minimum von 1.024 Token. Unter 1K Token greift Caching im OpenAI-Stil nicht. Fasse kleine statische Fragmente zu einem einzigen längeren Präfix zusammen.
- Tools/Funktionsdefinitionen sind Teil des Präfixes. Ein neu hinzugefügtes Tool im Katalog macht den Cache für alle ungültig. Halte den Tool-Katalog stabil und versioniere ihn.
Trefferquote überprüfen
Caching, das du nicht sehen kannst, ist kein Engineering, sondern Hoffnung. Protokolliere usage bei jedem Aufruf:
# 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.Im Kunavo-Dashboard zeigt die Usage-Seite die Cache-Aufteilung pro Modell und Tag. Wenn cache_read_input_tokens als Anteil der gesamten Eingabe wächst, funktioniert Caching. Bleibt der Wert bei 0 oder schwankt stark, arbeite die obige Liste der Fallstricke durch.
Was es bei Kunavo tatsächlich kostet
Die Cache-Rate jedes Modells ist auf der Preisseite veröffentlicht:
- Anthropic-Modelle: Cache-Lesevorgänge kosten 10% des Eingabepreises — 2.5% on Claude Fable 5.1, 5% on Claude Opus 5.5. Cache-Schreibvorgänge kosten das 1.25-Fache des Eingabepreises – der Fünf-Minuten-Multiplikator von Anthropic – und Kunavo berechnet auch einstündige Schreibvorgänge mit 1.25×, also weniger als Anthropics 2×.
- OpenAI-/Gemini-Modelle: Cache-Lesevorgänge kosten 10% des Eingabepreises (das von den Anbietern veröffentlichte Verhältnis). Cache-Schreibvorgänge kosten bei GPT-5.6 und GPT-6 Astra 1.25× und bei jedem anderen Modell den normalen Eingabepreis.
- Alle Preise für gecachte Anfragen enthalten bereits den Kunavo-Modellrabatt (je nach Modell unter dem Upstream-Listenpreis). Ein Cache-Lesevorgang für Sonnet 4.6 bei Kunavo kostet daher
$3 × 0.40 × 0.10 = $0.12 per 1M tokens. Das ist etwa 25× günstiger als der nicht gecachte Upstream-Preis.
Wann Caching nicht die Antwort ist
Einige Fälle, in denen sich der Aufwand nicht lohnt:
- Kurze Prompts (insgesamt <1K Token). Der Overhead dominiert; lass es einfach bleiben.
- Einmalige Aufgaben ohne wiederholten Datenverkehr. Der erste Aufruf ist etwas teurer – Caching amortisiert sich erst ab Aufruf 2.
- Aufgaben mit viel Ausgabe und wenig Eingabe (kreatives Schreiben, Codegenerierung). Die Eingabe macht bereits nur einen kleinen Teil der Rechnung aus. Konzentriere dich stattdessen auf Obergrenzen für das Ausgabebudget.
Für alles andere – RAG-Chatbots, Agenten mit einem festen Tool-Katalog, Klassifikatoren über einer statischen Bewertungsrichtlinie und Pipelines zur strukturierten Extraktion mit konsistenten Few-Shot-Beispielen – ist Caching die Optimierung mit dem höchsten ROI, die du an einem einzigen Nachmittag ausliefern kannst. Kombiniere es mit den vier weiteren Techniken in unserem Leitfaden zur Kostenoptimierung; eine Kostenreduzierung von 70 % ist ohne Einbußen bei der Ausgabequalität realistisch.
Bereits bei Kunavo? Öffne /app/usage und prüfe die Cache-Spalte für dein größtes Modell. Wenn sie null ist, lässt du Geld liegen. Vollständiger Leitfaden: /docs/caching.