Arbeitest du mit einem KI-Agenten an einem komplexen Programmierprojekt, gibst du eine Anweisung, der Agent antwortet. Dann die nächste Anweisung – der Agent muss dieselbe riesige Menge Kontext neu verarbeiten. Als müsstest du jedes Mal ein ganzes Buch neu lesen, um einen Satz zu schreiben. Prompt Caching speichert den berechneten Verarbeitungszustand, sodass der Agent nur den neuen Teil einer Anfrage berechnen muss. Dieser Mechanismus ist fragil und hat weitreichende Auswirkungen auf Latenz, Kosten und das Design von Tools und Sitzungen.
Earendil hat die Funktionsweise und Tücken von Prompt Caching für Coding-Agenten analysiert. Large Language Models werden oft als reine Funktionen betrachtet: Text rein, Text raus. Diese Abstraktion ignoriert einen wesentlichen Fakt: Bei einem Coding-Agenten ist der Großteil der Eingabe von Durchlauf zu Durchlauf identisch. Der Agent sendet System-Prompt, Tool-Definitionen, Projektanweisungen, Konversationsverlauf, Tool-Aufrufe und Ergebnisse. Im nächsten Schritt sendet er fast alles noch einmal, plus ein kleines bisschen Neues. Wächst eine Sitzung auf Zehntausende oder Hunderttausende Tokens an, wird es langsam und teuer, den gesamten Prompt für jeden Schritt neu zu berechnen. Prompt Caching macht es wirtschaftlicher, bleibt aber fragil.
Was ein KV-Cache enthält
Ein Transformer arbeitet in zwei Phasen. Während des Prefills liest er die Eingabe-Tokens und berechnet den Aufmerksamkeitszustand. Während des Decodings erzeugt er neue Tokens einzeln. In jeder Attention-Schicht produziert jeder verarbeitete Token einen Key und einen Value. Das sind Arrays von Zahlen, meist Gleitkommazahlen oder quantisierte Werte. Verarbeitet das Modell einen neuen Token, vergleicht es dessen Query mit den früheren Keys, um die Relevanz jedes früheren Tokens zu bestimmen. Daraus entsteht eine gewichtete Mischung der entsprechenden Values. Ein Key ist das, wonach gesucht wird, ein Value die Information, die abgerufen wird – allerdings unscharf, nicht wie ein exakter Lookup. Diese Keys und Values werden aufbewahrt, damit der nächste generierte Token auf alles Vorherige achten kann, ohne die früheren Tokens neu berechnen zu müssen. Dieser gespeicherte Zustand ist der KV-Cache.
Der Cache entspricht einer bestimmten Token-Präfixfolge. Zwei Prompts mit gleicher Bedeutung, aber unterschiedlicher Tokenisierung, teilen sich keinen KV-Cache. Ändert sich ein Token in der Mitte, ist alles danach eine andere Fortsetzung. Prompt Caching verlängert die Lebensdauer dieses Zustands über eine einzelne Generierung hinaus. Beginnt die nächste API-Anfrage des Coding-Agenten mit denselben Tokens, kann das Inferenzsystem die gespeicherte Arbeit für das passende Präfix wiederverwenden und nur das neue Suffix vorausberechnen.
Wo der Cache lebt
Ein Cache muss gespeichert und adressierbar sein. Es gibt zwei grundlegende Ansätze, wie Inferenzsysteme KV-Caches für spätere Anfragen verfügbar machen. Der einfachere ist die Session Affinity. Der Cache bleibt auf oder nahe der GPU, die ihn berechnet hat. Die nächste Anfrage wird an denselben Worker geroutet. Eine Session-ID oder ein Prompt-Cache-Key dient als einfacher Routing-Hinweis. Das vermeidet, einen sehr großen Cache über das Netzwerk zu bewegen. Es ist schnell, wenn es funktioniert, schränkt aber die Planung ein. Der Worker kann überlastet sein, neu starten oder den Eintrag verdrängen. Ein Router kann auch entscheiden, das Balancieren der Flotte sei wichtiger als die Erhaltung eines Session-Caches. Dennoch ist es attraktiv, weil es mit wenig zusätzlicher Infrastruktur auskommt.
Der andere Ansatz ist die Verteilung des Caches. KV-Blöcke können in einer anderen Speicherebene abgelegt oder über mehrere Worker verfügbar gemacht werden. Eine Anfrage ist dann nicht so stark an eine einzelne GPU gebunden. Das verbessert Scheduling-Flexibilität und Wiederherstellbarkeit. Das Verschieben, Indizieren und Behalten von KV-Blöcken ist selbst ein Systemproblem. Implementierungen mischen GPU-Speicher, Host-Speicher, lokalen Speicher, entfernten Speicher, präfixbewusstes Routing und Verdrängungsstrategien auf unterschiedliche Weise.
Cache und Präfixe: Sitzungen sind Bäume, keine Listen
Ein interessanter Punkt: Viele Coding-Agenten – darunter auch Pi, an dem Earendil arbeitet – modellieren Sitzungen als Bäume. Ein Befehl wie /tree kann die aktive Konversation auf einen früheren Punkt zurücksetzen und entlang eines anderen Zweigs fortsetzen. Ein Zurückspulen kann das aktive Suffix verwerfen, ohne es aus der Sitzungsdatei zu löschen. Ein neuer Zweig kann den größten Teil des alten Kontexts teilen, einen kleinen Teil oder praktisch keinen. Alle drei Zweige können dieselbe Pi-Session-ID haben. Aus Sicht des Routers sind sie eine Sitzung. Aus Sicht des Prompt-Caches sind es drei Token-Sequenzen mit nur teilweisem Präfix-Overlap.
Wenn der Cache wiederverwendbare Präfix-Blöcke behält, kann ein Sprung von D nach F möglicherweise root -> C wiederverwenden. Wenn er nur die heißeste Fortsetzung behält, die gemeinsamen Blöcke verdrängt wurden oder die Anfrage anderswo hin geroutet wird, kann der Treffer viel kleiner ausfallen. Ein Sprung zu Z bewahrt möglicherweise nur den System-Prompt und die anfänglichen Tool-Definitionen, obwohl er von A startet. Das genaue Cache-Management hängt stark vom Anbieter ab. Auch der umgekehrte Fall kann eintreten: Ein Fork oder eine neue Sitzung erzeugt eine neue Session-ID, während ein großer Teil identischen Kontexts übernommen wird. Ein Routingsystem, das Caches nach Session-Key isoliert, übersieht möglicherweise diesen nützlichen Overlap.
Explizites vs. automatisches Präfix-Caching
Anbieter-APIs bieten zwei Hauptstile. Anthropics traditionelles Interface nutzt explizite cache_control-Punkte. Der Client markiert Grenzen nach stabilen Teilen der Anfrage, wie dem System-Prompt, Tool-Definitionen oder dem letztmöglichen cachebaren Konversationsinhalt. Der Server kann den Präfix, der an diesen Punkten endet, schreiben oder nachschlagen. Die Grenze ist explizit, aber die Wiederverwendung erfordert, dass der Inhalt davor übereinstimmt. Auch die Preise sind explizit: Man zahlt für Cache-Schreibvorgänge und kann wählen, wie lange der Cache gehalten wird – zu unterschiedlichen Preisen. Andere APIs verwenden automatisches Präfix-Caching: Der Client sendet die Anfrage normal, der Anbieter findet ein wiederverwendbares Präfix ohne clientseitige Haltepunkte. Ein Prompt-Cache-Key oder Session-Header kann das Routing verbessern, macht aber unterschiedliche Präfixe nicht gleich.
Warum Tool-Loadouts Caches zerstören
Ein häufiges und überraschendes Problem: Tool-Definitionen beeinflussen Caches. Sie erscheinen meist vor der Konversation und werden intern in den System-Prompt eingefügt. Ihre Namen, Beschreibungen und JSON-Schemata sind genauso Modelleingabe wie jeder andere Text. Ein Tool hinzufügen, entfernen, sein Schema ändern oder auch nur die Tools in einer anderen Reihenfolge serialisieren – all das kann den ersten Unterschied weit vorne im Prompt platzieren. Dies ist eine häufige Überraschung bei Plugin-Systemen und MCP-ähnlichen Tool-Katalogen.
Tools nur dann zu laden, wenn sie relevant werden, klingt effizient, weil zunächst weniger Schemata gesendet werden. Bei den meisten Modellen invalidiert das neu erweiterte Loadout jedoch die gecachte Konversation, die darauf folgt. Das Sparen weniger Tool-Schema-Tokens kann dazu führen, dass Zehntausende von Konversations-Tokens erneut verarbeitet werden müssen. Einige neuere Modell-APIs unterstützen additives Tool-Laden. Ein Tool kann zu einem bestimmten Tool-Ergebnis innerhalb des Transkripts verfügbar werden, anstatt in die ursprüngliche Tool-Liste eingefügt zu werden. Das alte Präfix bleibt unverändert. Pi unterstützt dies heute für Modelle mit nativen Deferred-Tool-Mechanismen. Wenn eine Erweiterung eine rein additive Änderung mit setActiveTools() vornimmt, zeichnet Pi die hinzugefügten Namen auf dem Tool-Ergebnis auf. Für unterstützte Anthropic-Modelle verwendet es deferred definitions und tool_reference, für unterstützte OpenAI-Modelle entsprechende Tool-Suche-Einträge. Andere Modelle bekommen einen sicheren Fallback: Pi sendet die komplette aktive Tool-Liste bei der nächsten Anfrage, was funktional korrekt ist, aber den Prompt-Cache löschen kann.
Das Wort „additiv“ ist wichtig. Das Entfernen von Tools, das Ersetzen eines Loadouts durch ein anderes oder das Ändern von Prompt-Schnipseln verändert immer noch die frühere Eingabe. Eine Erweiterung, die den System-Prompt neu aufbaut, die Tool-Reihenfolge mischt, Zeitstempel einfügt oder bei jedem Schritt die aktiven Tools ändert, kann unbeabsichtigt das Caching für die gesamte Sitzung zunichtemachen. Erweiterbarkeit bedeutet, dass Pi die Cache-Stabilität nicht für jede Erweiterung garantieren kann. Es kann cache-freundliche Mechanismen bereitstellen; Erweiterungen müssen sie nutzen. Cache-Effizienz ist für viele Erweiterungen nur ein nachträglicher Gedanke – teilweise, weil bei einem Festpreis-Abo die Kosten von Cache-Fehlern nicht so offensichtlich sind.
Unterbrechungen und TTLs
Standard-Lebensdauern einiger wichtiger Prompt-Caches sind kurz. Anthropics fünf Minuten sind kürzer als viele normale Programmieraktivitäten. Wenn man bei der Nutzung von Fable einen Kaffee trinken geht und zehn Minuten später zurückkommt, kostet eine einzelne „sag hallo“-Nachricht mehr Geld als erwartet. Der Benutzer betrachtet eine Programmier-Sitzung als kontinuierlich aktiv, der Inferenz-Anbieter sieht eine Abfolge isolierter Anfragen. Ein langer Build, eine Testsuite, Mittagessen, ein Meeting oder einfach das Anhalten, um einen Diff zu überprüfen – all das kann die Cache-Lebensdauer überschreiten. Die nächste Anfrage enthält denselben Prompt, aber der gespeicherte KV-Zustand ist weg, und das Präfix wird erneut als Input berechnet.
Pi folgt den fünf Minuten Standard, die Anthropic für API-Benutzer empfiehlt. Ein Blick in Claude Codes Codebasis zeigt, dass Anthropic für seine eigenen Abonnement-Benutzer das Cache-Timeout auf eine Stunde erhöht. Die erhöhten Kosten sind für API-Kunden oft nicht gerechtfertigt. Man kann sich aber dafür entscheiden. Einige Anbieter wie Anthropic bieten längere Aufbewahrungskontrollen an. Für unterstützte Direct-APIs können Pi-Benutzer PI_CACHE_RETENTION=long setzen, um diese anzufordern. Das bleibt aber eine Anfrage: Pi kann ein Gateway nicht zwingen, einen Eintrag zu behalten, eine Verdrängung unter Speicherdruck zu verhindern oder einen Cache am Leben zu erhalten, während keine Modellanfrage gestellt wird.
Die Kosten eines Fehlschlags
Preise für ungecachten Input, Cache-Schreibvorgänge und Cache-Lesevorgänge unterscheiden sich. Cache-Lesevorgänge sind meist vergünstigt, weil die teure Prefill-Arbeit bereits erledigt ist. Cache-Schreibvorgänge können einen Aufschlag verlangen, weil der Anbieter verspricht, den Zustand für die spätere Nutzung aufzubewahren. Betrachten Sie eine Coding-Sitzung mit 100.000 Token Historie, gefolgt von einer kurzen neuen Anfrage. Wenn der Cache funktioniert, wird fast die gesamte Historie zum niedrigeren Cache-Lesepreis abgerechnet. Nur das kleine neue Material wird zum regulären Input-Preis verarbeitet und möglicherweise in den Cache geschrieben. Bei einem Cache-Fehler muss der Anbieter die gesamten 100.000 Token Historie erneut zum regulären Input-Preis verarbeiten. Möglicherweise berechnet er auch das Zurückschreiben dieser Historie in den Cache. Deshalb kann eine kurze Anfrage wie „weiter“ nach einem Cache-Ablauf überraschend teuer sein. In einer langen Coding-Sitzung kann das erneute Lesen des alten Inputs mehr kosten als das Generieren der nächsten Antwort.
Prompt Caching schafft nicht offensichtliche Anreize. Der Benutzer möchte hohe Trefferquoten, weil sie Latenz und Kosten senken. Ein Inferenz-Betreiber, der die GPUs besitzt, sollte sie ebenfalls wollen: Weniger Prefill-Arbeit bedeutet mehr Anfragen mit derselben Hardware. Ein gut entworfener Rabatt auf gecachte Tokens kann beide Seiten in Einklang bringen, während gleichzeitig der Anreiz bleibt, Caching-Mechanismen zu optimieren.
Für Coding-Agenten ist Prompt Caching mehr als ein Implementierungsdetail. Es beeinflusst Latenz, Kosten, Tool-Design, Sitzungsdesign und sogar welche Produktfunktionen überhaupt sinnvoll angeboten werden können. Die Fragilität des Caches – durch Tool-Änderungen, Session-Neustarts, Routing-Entscheidungen oder schlichte Zeitüberschreitungen – macht es zu einer zentralen architektonischen Überlegung. Wer einen KI-Agenten entwickelt oder intensiv nutzt, sollte verstehen, wie der Cache auf den jeweiligen Providern und in der eigenen Anwendung funktioniert. Denn diese unscheinbare Optimierung entscheidet über Geschwindigkeit und Kosten jeder Interaktion.
Quelle: earendil.com
