Jeder LLM-Aufrufer bekam heute Prompt-Längen-Schutzmechanismen
Ein unbegrenzter Prompt ist ein wartender Kostenverstärkungs-Angriff. RakuAI behandelt Prompt-Längen-Disziplin als Sicherheitsinfrastruktur — im Build erzwungen, nicht dem Gedächtnis überlassen.
Die Runtime ruft LLMs an mehr Stellen auf, als ich verfolgt hatte. Da ist die offensichtliche (der XRAssistantService, der sprachbasierte AR-Experiences antreibt). Da ist die weniger offensichtliche (die NPC-Verhaltensschicht, wo das Gehirn eines Agenten in der Welt teilweise ein LLM-Aufruf ist). Da ist die am wenigsten offensichtliche (Entwicklungszeit-Tools, die sich in den Runtime-Build eingeschlichen haben: Schema-Validatoren, Debug-Analyzer, ein automatischer Playtest-Zusammenfasser).
Jede dieser Stellen wurde in den letzten sechs Monaten unabhängig geschrieben. Jede wurde zur PR-Zeit reviewt. Keine davon hatte, bis zu diesem Wochenende, eine einheitliche Disziplin bezüglich Prompt-Länge.
Dieser Post handelt davon, warum das zu einem Problem wurde, was das Audit fand, und wie die neuen Schutzmechanismen aussehen.
Wie das Problem ans Licht kam
Der Auslöser war eine routinemäßige Kostenüberwachungs-Prüfung. Beim Blick auf die tägliche LLM-API-Ausgabe gab eine bestimmte Entwicklungsumgebung fünfzehnmal so viel aus wie die anderen. Gleiche Agentenanzahl, gleiche Testlast, gleiches Modell. Fünfzehnmal die Kosten.
Die Rückverfolgung des Anstiegs führte zum Playtest-Zusammenfasser-Codepfad. Der Zusammenfasser nimmt eine abgeschlossene Playtest-Session, packt den relevanten Szenenzustand in einen Prompt, sendet ihn an ein Cloud-LLM und bekommt eine strukturierte Analyse der Session zurück. Die Funktion war geschrieben worden, als Szenen klein waren. Der „relevante Szenenzustand” war eine strukturierte Zusammenfassung dessen, was passiert war. Mit der Zeit war die Zusammenfassung gewachsen. Eine bestimmte Entwicklungsumgebung hatte lange Playtests laufen lassen, die enorme Zusammenfassungen erzeugten. Der Zusammenfasser sendete diese Zusammenfassungen ungeprüft an das Modell. Das Modell berechnete pro Token.
Der Fix für diesen einen Aufrufer war offensichtlich. Zusammenfassungslänge deckeln. Bei Bedarf kürzen. Loggen, wenn die Kürzung passiert.
Die tiefere Frage war die, die ich als Nächstes stellte: Wie viele andere Aufrufer in der Runtime haben dieselbe Schwachstelle? Ich habe nachgeschaut. Das Audit war die eigentliche Arbeit.
Was das Audit fand
Elf Stellen in der Runtime rufen ein LLM auf. Von diesen elf:
- Zwei hatten explizite Längenprüfungen und vernünftiges Verhalten bei Überlauf (kürzen, loggen, mit kleinerem Kontext erneut versuchen). Diese waren in Ordnung.
- Fünf hatten überhaupt keine Längenprüfung. Sie sendeten, was auch immer der Aufrufer ihnen übergab.
- Drei hatten eine Längenprüfung, die aber zu großzügig war, um nützlich zu sein (hunderttausend Tokens, weit über jeder vernünftigen Nutzung, aber deutlich unter katastrophal).
- Einer war ein Debug-Pfad, der überhaupt nicht in der Produktions-Binärdatei sein sollte; er hatte eine Längenprüfung, die aber über ein Debug-Flag leicht umgangen werden konnte.
Die fünf ohne Längenprüfung waren die dringenden. Sie betrafen: den Playtest-Zusammenfasser (bereits identifiziert), das NPC-Verhaltensgehirn (potenziell riesig, wenn ein NPC eine komplexe Szene beobachten konnte), den Schema-Validator (könnte eine beliebige Datei erhalten), den Weltzustand-Beschreiber (könnte einen beliebig großen Weltabschnitt beschreiben) und eines der entwicklerseitigen Diagnose-Tools.
Jede dieser Stellen war in einem separaten PR gelandet. Jeder PR war isoliert betrachtet vernünftig gewesen. Die aggregierte Disziplin von „jeder LLM-Aufrufer hat eine Längenobergrenze” war niemandes Job gewesen. Also hatte es niemand gemacht.
Wie die Schutzmechanismen aussehen
Ein kleines Stück Infrastruktur landete Samstagmorgen und wurde über den Tag hinweg auf jeden Aufrufer angewendet.
Ein gemeinsames LLMCallGuard-Utility. Jede Stelle, die mit einem LLM spricht, geht jetzt durch dieses Utility, statt Requests direkt zu konstruieren. Das Utility nimmt eine Prompt-Vorlage, eine Kontext-Payload und ein Zielmodell. Es erzwingt eine Längenobergrenze (konfigurierbar pro Modell, mit sinnvollen Standardwerten basierend auf dem dokumentierten Kontextfenster des Modells). Es loggt die tatsächlich verwendete Prompt-Länge auf INFO-Ebene für den budgetierten Fall, auf WARNING-Ebene, wenn es kürzen muss, und auf ERROR-Ebene, wenn die Kürzung nicht ausreicht, um in die Obergrenze zu passen.
Budgets pro Aufrufer. Jeder LLM-Aufrufer in der Runtime hat jetzt ein explizites Token-Budget pro Aufruf. Das Budget liegt unter dem Kontextfenster des Modells, weil wir Spielraum für die Antwort lassen wollen und laut scheitern wollen, bevor das Modell still scheitert. Die Budgets reichen von ein paar tausend Tokens (der Schema-Validator) bis zu zwanzigtausend Tokens (der Playtest-Zusammenfasser, mit einer echten Obergrenze, die den ursprünglichen Vorfall verhindert).
Telemetrie. Jeder LLM-Aufruf zeichnet jetzt die Prompt-Größe, die Antwortgröße, das Modell, das verbrauchte Budget und die Latenz auf. Die Telemetrie ist das, was mir erlaubt, den nächsten Vorfall zu bemerken, bevor die Rechnung kommt.
Eine Fehlermodus-Hierarchie. Wenn die Payload eines Aufrufers das Budget überschreitet, versucht das Utility eine Abfolge von Fixes der Reihe nach. Zuerst versucht es intelligentes Kürzen (den aktuellsten Kontext bewahren, das älteste fallen lassen, den System-Prompt intakt halten). Zweitens, wenn intelligentes Kürzen immer noch nicht passt, versucht es gröberes Kürzen (ganze Abschnitte fallen lassen). Drittens, wenn keine Kürzung passt, scheitert es laut mit einem klaren Fehler, statt einen übergroßen Request zu senden, den das Modell ablehnen wird. Die Hierarchie bedeutet, dass sich die meisten Fälle graziös erholen, Randfälle auf beobachtbare Weise scheitern und kein Aufrufer jemals eine unbegrenzte Payload sendet.
Eine CI-Prüfung, die Regressionen verhindert. Neuer Code, der mit einem LLM spricht, muss durch LLMCallGuard gehen. Der CI-Scan findet jeden neuen direkten LLM-Aufruf, der das Utility umgeht, und markiert den PR. Das Muster ist dasselbe, das das Sicherheitsaudit vor ein paar Wochenenden für Admin-Endpoints verwendete: Die Disziplin im Build erzwingen, nicht beim Review.
Was ich gelernt habe
Drei Dinge.
Disziplin, die niemandes Job ist, ist Disziplin, die nicht passiert. Die elf LLM-Aufrufer waren jeder für sich zur PR-Zeit vernünftig gewesen. Das kollektive Verhalten war nicht reviewt worden, weil niemand den übergreifenden Belang besessen hat. Der Fix war, den übergreifenden Belang zu einem Stück Infrastruktur zu machen, durch das jeder Aufrufer gehen muss, was die Disziplin unmöglich macht zu vergessen.
Kosten sind ein Sicherheitsbelang. Ich hatte über „unbegrenzte Prompts” als Korrektheits- oder Robustheitsbelang nachgedacht. Der Kostenanstieg in der Entwicklungsumgebung hat mich gelehrt, es als Sicherheitsbelang zu betrachten. Ein Angreifer, der den Inhalt eines LLM-Aufrufs von der Runtime beeinflussen kann, kann beliebige Kosten beim Betreiber verursachen. Dieselben Verteidigungen (Längenobergrenzen, Budget-Durchsetzung, Telemetrie) schützen sowohl vor Robustheitsfehlschlägen als auch vor Kostenverstärkungs-Angriffen.
Audit in einem Rhythmus. Das heutige Audit fand fünf Schwachstellen, die das PR-Review verpasst hatte. Das nächste Audit wird andere finden. Die Disziplin, einen geplanten Audit-Durchgang über einen bestimmten übergreifenden Belang laufen zu lassen, ist der einzige verlässliche Weg, den ich gefunden habe, um die Dinge zu finden, die das Review verpasst.
Was Partner und Entwickler daraus mitnehmen sollten
Wenn du etwas betreibst, das aus Produktionscode ein LLM aufruft, und du nicht jeden Aufrufer auf Prompt-Längen-Disziplin auditiert hast, tu es. Das Audit ist klein. Die Funde sind wahrscheinlich. Die Kosten, es heute zu tun, sind viel geringer als die Kosten, es nach einem Vorfall zu tun.
Wenn du ein KI-Labor bist, das Agenten baut, die andere LLMs aufrufen: Die Metrik, die es zu optimieren gilt, ist „markiert der Agent, wenn er einen unbegrenzten Prompt konstruiert.” Die meisten Agenten tun das nicht. Die, die es tun, sind die, denen ich bei ernsthafter Arbeit vertraue.
Wenn du eine Engine für eine Partnerschaft evaluierst und die Engine mit Cloud-LLMs integriert, frag nach Prompt-Längen-Disziplin. Die richtige Antwort ist „jeder Aufrufer geht durch ein gemeinsames Utility, mit Budgets pro Aufrufer, mit Telemetrie, mit einem CI-Guard.” Die falsche Antwort ist „das Problem hatten wir noch nicht.”
Samstagnachmittag. Jeder LLM-Aufrufer in der Runtime geht jetzt durch denselben Schutzmechanismus. Der nächste Audit-Rhythmus steht im Kalender.
Zurück ans Bauen.
Baue auf einer Runtime, die jeden LLM-Aufruf schützt
RakuAI ist die AI-native spatiale Runtime, die dein Modell in Produktion steuert — mit Prompt-Längen-Budgets, Telemetrie und CI-Durchsetzung direkt an der Grenze eingebaut. Sieh, was disziplinierte Infrastruktur für deinen Stack freischaltet.