LLM-Kostenkontrolle für SaaS: Token-Budgets, Caching und Graceful Fallbacks
Ein B2B-SaaS für Notizen, das ich Anfang 2026 entwirren durfte, hatte eine schöne KI-Zusammenfassungsfunktion auf Basis eines Frontier-Modells gebaut und sie mit 19 € pro Platz bepreist. Zwei Monate nach dem Launch bemerkte die Finanzabteilung, dass die Bruttomarge der KI-Tarife auf 38 % gefallen war. Ein Enterprise-Account war auf jeder Rechnung netto negativ. Die Frage des Gründers war die richtige: "Wieso ist LLM-Kostenoptimierung noch kein gelöstes Problem?"
Es ist ein gelöstes Problem. Es ist nur eines, das die meisten Engineering-Teams erst entdecken, nachdem sie ausgeliefert haben, wenn die Nutzung hochschnellt und Kostenberichte in Formen eintreffen, die die Finanzabteilung noch nie gesehen hat. Bis 2026 hat jedes B2B-Produkt mit einer ernstzunehmenden KI-Funktion eine Token-Budget-Geschichte, eine Prompt-Caching-Schicht, eine Model-Routing-Policy und ein Fallback-Runbook für die Tage, an denen der Anbieter einen schlechten Nachmittag hat. Teams, die eines dieser Teile übersprungen haben, sind diejenigen, die ein Quartal später Notfall-Replatformings durchführen.
Dieser Beitrag ist ein praktischer Leitfaden, um die LLM-Unit-Economics unter Kontrolle zu halten: wie man Token-Budgets pro Tarif gestaltet, ohne die Nutzererfahrung zu zerstören, wie man die Einsparungen, die Prompt-Caching verspricht, tatsächlich realisiert, wie man Anfragen über günstige und teure Modelle routet und wie man elegant scheitert, wenn die Kosten hochschnellen oder Anbieter ausfallen.
Die tatsächliche Kostenstruktur einer LLM-Funktion
Bevor man Budgets entwirft, lohnt es sich, ehrlich zu sein, wohin das Geld fließt. Die Rechnung einer typischen RAG-gestützten SaaS-Funktion hat vier Schichten.
Die direkten Inferenzkosten dominieren: Input-Tokens für den System-Prompt, abgerufenen Kontext und Konversationsverlauf; Output-Tokens für die Antwort des Modells. 2026 liegen Frontier-Modelle im Bereich von 10–25 € pro Million Output-Tokens, während Mid-Tier-Modelle (GPT-4.1-mini, Claude Sonnet 4.5, Gemini 2.5 Flash und ihresgleichen) bei 0,50–3 € pro Million Output-Tokens liegen. Die 10- bis 30-fache Lücke zwischen den Stufen ist der am besten ausnutzbare Kostenhebel in deinem Stack.
Die Embedding-Kosten werden von Tutorials meist auf null gerundet, aber in Produktion werden sie zu einem stetigen Tropfen — 0,02–0,10 € pro Million Input-Tokens im großen Maßstab, bezahlt bei jeder Neuindizierung jedes Dokuments, jedes Mal, wenn du die Chunking-Strategie änderst.
Retry- und Tool-Call-Kosten sind der eigentliche stille Killer. Ein einzelner Chat-Turn, der zwei Tool-Calls auslöst, einen Retry auf eine fehlerhafte JSON-Antwort und einen automatischen Kontext-Refresh, kann die Ausgaben gegenüber einem sauberen Turn um das 4- bis 6-Fache vervielfachen. Die meisten Abrechnungs-Dashboards der Anbieter zeigen das nicht. Die Observability deiner eigenen Anwendung muss es tun.
Storage und Infrastruktur — die Vektordatenbank, Caches, Queues, der Observability-Stack selbst — runden die Rechnung ab. Klein als Prozentsatz der Gesamtausgaben in der Frühphase, aber der Teil, der eine Kostenoptimierung unbeschadet überstehen sollte, weil er alles andere günstig macht.
Wenn dein Engineering-Team die LLM-Ausgaben der letzten Woche nicht über diese vier Töpfe pro Funktion und pro Kundentarif aufschlüsseln kann, ist jede Kostenentscheidung danach geraten. Ein fokussiertes Code-Quality-Audit der KI-Schicht findet meist zwei oder drei strukturelle Probleme, die 60 % der ungeklärten Ausgaben innerhalb eines Tages erklären.
Token-Budgets pro Nutzertarif
Der erste Instinkt der meisten Teams ist, die reinen Token-Ausgaben mit einem harten Cutoff zu deckeln. Das funktioniert, um die Plattform zu schützen, aber es ruiniert die Nutzererfahrung. Ein besseres Modell behandelt Budgets als Ressource, die das Produkt sichtbar macht, wie API-Kontingent oder Speicher — sichtbar, vorhersehbar und tarifförmig.
Ein praktikables Design verwendet Budgets pro Nutzer, die aus dem Abrechnungstarif berechnet und in einem festen Rhythmus aufgefrischt werden. Die beiden Designregeln sind nicht verhandelbar: rechne in Geld, nicht in Tokens — Token-Kosten ändern sich jedes Quartal, Preise variieren pro Modell, und die einzige Zahl, die die Finanzabteilung interessiert, ist Euro pro Nutzer — und belaste vor dem Call, erstatte den ungenutzten Anteil bei Abschluss zurück, denn eine nachträgliche Abrechnung lässt einen fehlerhaften Retry-Sturm durch ein Budget brechen, während der Zähler noch hinterherläuft.
Eine minimale Symfony-Implementierung:
// src/Service/LlmBudget.php
final class LlmBudget
{
public function __construct(
private readonly Connection $db,
private readonly Clock $clock,
) {}
public function reserve(string $userId, EurAmount $estimated): Reservation
{
$period = $this->currentPeriodFor($userId);
return $this->db->transactional(function ($tx) use ($userId, $period, $estimated) {
$row = $tx->fetchAssociative(
'SELECT remaining_eur FROM llm_budgets
WHERE user_id = ? AND period_id = ? FOR UPDATE',
[$userId, $period],
);
if ($row === false || $row['remaining_eur'] <= 0) {
throw new BudgetExhaustedException($userId);
}
$tx->executeStatement(
'UPDATE llm_budgets SET reserved_eur = reserved_eur + ?,
remaining_eur = remaining_eur - ?
WHERE user_id = ? AND period_id = ?',
[$estimated->cents(), $estimated->cents(), $userId, $period],
);
return new Reservation($userId, $period, $estimated, $this->clock->now());
});
}
public function settle(Reservation $r, EurAmount $actual): void
{
// Erstatte die Differenz zwischen reserviert und tatsächlich bei Abschluss zurueck.
$delta = $r->estimated->cents() - $actual->cents();
$this->db->executeStatement(
'UPDATE llm_budgets SET reserved_eur = reserved_eur - ?,
spent_eur = spent_eur + ?,
remaining_eur = remaining_eur + ?
WHERE user_id = ? AND period_id = ?',
[$r->estimated->cents(), $actual->cents(), $delta, $r->userId, $r->period],
);
}
}
Auch die Tarifform ist wichtig. Das Muster, das skaliert: Der Free-Tarif erhält ein kleines Monatsbudget (0,50 €), das für eine täglich aktive Demo-Erfahrung ausreicht. Der Standard-Tarif erhält genug Budget für den dokumentierten Anwendungsfall plus 50 % Puffer (typischerweise 5–15 € pro Platz und Monat bei SaaS-Preisen). Der Power-Tarif verdoppelt das und zeigt einen Upgrade-Hinweis statt einer harten Sperre. Enterprise-Kunden erhalten einen nutzungsbasierten Zähler mit Alarmschwelle statt eines Caps. Jeder Tarif ist so konstruiert, dass der nächste Tarif im Moment der Reibung offensichtlich besser erscheint, an keiner Stelle aber bestrafend.
Prompt-Caching, das wirklich Geld spart
Die meisten Teams aktivieren Prompt-Caching, indem sie einem System-Prompt ein Cache-Flag hinzufügen, und nehmen an, die Arbeit sei getan. Echte Einsparungen kommen daher, die Prompt-Struktur für das Caching zu gestalten, nicht einen Schalter umzulegen.
Drei Prinzipien trennen Teams, die über 70 % Einsparung bei gecachten Calls erzielen, von denen, die 5 % erreichen.
Stabile Präfixe, dynamische Suffixe. Der Cache-Key ist faktisch ein Präfix-Hash. Alles, was variiert — User-ID, Zeitstempel, Session-Token, abgerufene Chunks — muss nach dem stabilen Hauptteil des Prompts kommen (System-Anweisungen, Rollendefinitionen, Few-Shot-Beispiele, Glossar). Ein häufiges Anti-Pattern ist das Verschachteln von Nutzerkontext mit System-Anweisungen; das macht den Cache für jede Anfrage zunichte und lässt die Rechnung wieder linear mit dem Token-Volumen wachsen.
Lang genug, um zu zählen. Die meisten Anbieter cachen nur, wenn der gecachte Anteil eine Mindest-Token-Schwelle überschreitet (rund 1024 Tokens bei den großen Anbietern 2026). Teams mit kurzen, knappen System-Prompts zahlen oft den vollen Preis, selbst wenn Caching aktiviert ist. Den Prompt mit hochwertigen Anweisungen und Few-Shot-Beispielen aufzufüllen — was die Qualität ohnehin verbessert — ist meist die richtige Entscheidung.
TTL-Abstimmung. Caches verfallen bei den meisten Anbietern nach einem Leerlauffenster von 5–15 Minuten. Workloads mit stoßartigen Zugriffsmustern profitieren dramatisch; spärliche Long-Tail-Workloads profitieren weit weniger. Wenn deine Verkehrsform spärlich ist, batche: Gruppiere N unabhängige Anfragen in einem kleinen Worker, der sie innerhalb eines einzigen TTL-Fensters verarbeitet. Die Infrastrukturkosten der Queue sind gegenüber den Inferenzeinsparungen vernachlässigbar.
Die praktische Wirkung, in Zahlen, die ich dieses Jahr an realen Workloads gemessen habe: Ein gut strukturierter RAG-Prompt mit 3.000 Tokens System- plus Retrieval-Kontext, aufgerufen von 50 Nutzern in einem 10-Minuten-Fenster, fällt von rund 0,12 € pro Call auf 0,018 € pro Call, sobald der Cache warmläuft. Das ist kein Rundungsfehler — es ist der Unterschied zwischen einer tragfähigen Funktion und einer, die ein Quartal nach dem Launch abseits der Roadmap rausfliegt.
Model-Routing: günstig zuerst, eskalieren bei Fehlern
Die größte einzelne Kosteneinsparung in den meisten KI-Funktionen ist das einfachste Muster: Probiere zuerst das günstige Modell, eskaliere nur dann zum teuren, wenn das günstige nicht gut genug ist.
Die Implementierung hat drei Teile. Einen Router, der das Modell wählt. Eine Qualitätssonde, die erkennt, wann das günstige Modell versagt hat. Eine Eskalationspolicy, die entscheidet, wann ein Retry erfolgt, wann eskaliert wird und wann aufgegeben wird.
Ein minimaler Router für einen Symfony-Messenger-Handler:
final class LlmRoutingHandler
{
public function __invoke(GenerateSummary $msg): void
{
$ladder = ['gpt-4.1-mini', 'gpt-5']; // guenstig -> teuer
$attempts = [];
foreach ($ladder as $model) {
try {
$result = $this->llm->complete($model, $msg->prompt);
} catch (ProviderException $e) {
$attempts[] = ['model' => $model, 'error' => $e->getMessage()];
continue;
}
$quality = $this->qualityProbe->score($result, $msg->expectations);
$attempts[] = ['model' => $model, 'quality' => $quality->value()];
if ($quality->isAcceptable()) {
$this->bus->dispatch(new SummaryReady($msg->id, $result, $model, $attempts));
return;
}
}
$this->bus->dispatch(new SummaryFailed($msg->id, $attempts));
}
}
Die Qualitätssonde ist das tragende Teil. Für strukturierte Outputs ist sie ein JSON-Schema-Validator plus eine Längen-Plausibilitätsprüfung. Für Freiform-Generierungen ist sie meist ein kleiner Klassifikator — ein feinabgestimmtes Embedding-Modell mit kalibrierter Schwelle läuft zu nahezu null Kosten und fängt die häufigsten Fehlermodi günstiger Modelle ab (Verweigerung, halluzinierte Struktur, Sprachdrift, Abschneiden). Für agentische Workflows prüft die Sonde, ob die angeforderten Tool-Calls erfolgt sind und ob sie erfolgreiche Ergebnisse zurückgegeben haben.
Eine nützliche Faustregel aus Produktionsdaten: In gut instrumentiertem SaaS werden 70–85 % der Anfragen vom Mid-Tier-Modell ausreichend bedient. Routing bei dieser Trefferquote gegen eine 10-fache Preislücke ist eine Reduktion der Inferenzausgaben um 60–70 % ohne wahrnehmbaren Qualitätsverlust für die meisten Nutzer. Die verbleibenden 15–30 % der Anfragen werden zum teuren Modell eskaliert, und weil die Eskalation datengetrieben statt pauschal angewandt ist, bleiben die Kosten auch bei Lastspitzen begrenzt.
Graceful Fallbacks für die schlechten Tage
Kostenspitzen und Anbieterausfälle treten häufiger gemeinsam auf, als man denkt. Die Fallback-Schicht ist das, was das Produkt nützlich — und die Rechnung begrenzt — hält, wenn eines von beidem passiert.
Drei Muster verdienen ihren Platz.
Provider-Failover. Jeder ernsthafte Produktions-Stack 2026 routet über mindestens zwei Anbieter — typischerweise OpenAI plus Anthropic, dazu eine selbst gehostete Option für sensible Payloads. Der Router behandelt sie als Leiter für Verfügbarkeit, nicht nur für Kosten. Ein siebenminütiger Anthropic-Ausfall hört auf, ein kundenrelevanter Vorfall zu sein, wenn der Router den Verkehr bereits in den ersten 30 Sekunden erhöhter Fehlerraten zu OpenAI verschoben hat. Die Kosten der zweiten Integration sind beim ersten schlechten Stündchen des Primäranbieters wieder eingespielt.
Statische Fallbacks für hochfrequente Prompts. Manche Produktoberflächen — Onboarding-Touren, Standardzusammenfassungen, Empty-State-Vorschläge, Beispiel-Outputs auf Marketingseiten — brauchen nicht wirklich eine frische Inferenz pro Anfrage. Eine kleine Bibliothek von Varianten vorzugenerieren und sie aus dem Cache auszuliefern, wenn das Budget knapp oder der Anbieter degradiert ist, hält die UX zu null Grenzkosten intakt. Die meisten Teams entdecken nach dem Launch, dass 20–30 % ihrer LLM-Calls ohnehin immer auf derselben Menge an Inputs landeten.
Botschaften zur eleganten Degradation. Wenn ein Budget erschöpft ist und kein statischer Fallback verfügbar ist, muss das Produkt dem Nutzer mitteilen, was passiert ist, und zwar so, dass es nicht wie ein Bug aussieht. "Die KI-Zusammenfassung pausiert für den Rest dieser Abrechnungsperiode — upgrade für unbegrenzt, oder sie setzt sich in drei Tagen zurück" ist eine viel bessere Kundenerfahrung als ein drehender Ladeindikator, und sie konvertiert. Der Fehlerpfad ist eine Produktoberfläche, kein 500er.
Die Fallback-Policy gehört in Code, nicht in ein Runbook. Eine kleine State Machine — provider_healthy, provider_degraded, budget_warning, budget_exhausted, static_only — getrieben von Health-Probes und Budget-Reads, gibt dem Frontend einen vorhersehbaren Vertrag zum Rendern und dem Bereitschaftsdienst einen einzigen Graphen, auf den er schaut, wenn etwas schiefläuft.
Was zuerst ausliefern
Für ein SaaS-Team, das gerade entdeckt hat, dass die LLM-Rechnung des letzten Quartals unangenehm ist, sequenziert sich die Arbeit sauber. Instrumentiere zuerst — Zuordnung pro Funktion, pro Nutzer, pro Modell in dein Data Warehouse. Dann füge geldbezifferte Budgets pro Tarif hinzu, mit Reservierungen und Erstattungen, nicht nur Ausgabenprotokollierung. Dann liefere einen Model-Router mit Qualitätssonde aus, denn das ist die größte einzelne Kosteneinsparung und erfordert kein Prompt-Redesign. Dann gehe zum Prompt-Caching über, sobald die Routing-Daten dir sagen, welche Prompts stabil genug zum Cachen sind. Dann füge Provider-Failover hinzu. Jedes Teil verstärkt das vorherige; das Überspringen des Instrumentierungsschritts macht alles Folgende zu einer Vermutung.
Wenn die KI-Funktion ohne saubere Abstraktionsschicht auf ein bestehendes PHP- oder Symfony-Produkt aufgepfropft wurde, ist dies auch der Moment, eine zu entwerfen — ein einziges LlmGateway, das Budgets, Routing, Caching, Retries und Observability besitzt, während der Rest des Produkts es über eine Schnittstelle aufruft. Diese Art von architektonischer Aufräumarbeit passt gut zu Custom-Software-Entwicklung, denn das KI-Gateway ist genau die Oberfläche, an der Geschäftslogik, Infrastruktur und Preisgestaltung aufeinandertreffen.
Der strategische Rahmen ist einfach. KI-Funktionen, die ohne Kostenstory ausgeliefert werden, sind Kredite, die das Engineering-Team gegen die Marge des nächsten Quartals aufnimmt. Die Teams, die 2026 still gewinnen, sind die, die die LLM-Unit-Economics vom ersten Commit an als erstklassiges Produktanliegen behandeln, nicht als Feuer, das am Ende der Runway gelöscht wird.
Wolf-Tech hilft europäischen SaaS-Teams, KI-Funktionen mit vorhersehbarer Bruttomarge auszuliefern — Token-Budgetierung, Prompt-Caching, Model-Routing, Fallback-Architekturen und Observability über PHP/Symfony-Backends und Next.js-Frontends. Kontaktiere uns unter hello@wolf-tech.io oder besuche wolf-tech.io für eine kostenlose Beratung.

