Umgang mit Verkehrsspitzen in Mehr-Agenten-Systemen mithilfe eines dreistufigen Vertragsmodells
Das Aufrechterhalten von Mehr-Agentensystemen bei einem Zehnfachanstieg des Verkehrs: Ein Warteschlangen-Manager, drosselnde Einstellungen pro Tool sowie synchronisierte Richtlinienüberprüfungen, dazu Metriken und eine Demonstration eines Ansturms.
Quellen: Multi-Agent Orchestration in Production: Handling Traffic Spikes at Scale
Ein Agentengraph kann bei 10 Anfragen pro Sekunde reibungslos funktionieren, bricht jedoch bei 100 zusammen. Die Anfragen häufen sich, Richtlinienprüfungen werden übersprungen, Toolaufrufe konkurrieren miteinander, und ein einst zuverlässiges System verwandelt sich in eine Belastung. Die Agenten sind selten die Ursache. Was fehlt, ist eine klare Vereinbarung zwischen der Warteschlange, der Orchestrierungsschicht und den Sicherheitsmechanismen. Die meisten Teams erkennen diese Lücke erst, wenn bereits der reale Traffic darauf trifft.
Warum Trafficspitzen früher eintreten als erwartet
Agentensysteme verlassen zunehmend die Demo-Phase und gelangen in die reale Produktion, wodurch Spitzen unvermeidlich sind: ein Blitzverkauf, eine virale Funktion, eine geplante Batch-Aufgabe oder einfach jeder Benutzer, der am Dienstagmorgen die API nutzt. Mit steigender Last geschehen zwei Dinge gleichzeitig.
Zunächst erfolgt die Routierung in Echtzeit. Die Entscheidung, welcher Agent eine Anfrage bearbeitet oder ob sie sofort in die Warteschlange kommt, ist eine messbare Aufgabe.
Zweitens neigen Systeme unter Druck dazu, fehlerhaft zu funktionieren. Das sind in der Regel keine in Panik geratenen Ingenieure, die Sicherheitsprüfungen umgehen. Es handelt sich vielmehr um naives Fehlerrhandling, das bei Ablauf der Frist standardmäßig auf „Erlauben“ setzt, oder um eine Fallback-Route, die stillschweigend das Validierungs-Middleware überspringt. Wenn die Durchsetzung von Richtlinien unter Last verschwindet, ist in der Regel dieses architektonische Anti-Muster die Ursache – nicht menschliches Eingreifen.
Die Lösung besteht in einer klaren, durchsetzbaren Vereinbarung zwischen drei Komponenten: der Warteschlange (was hineinkommt), dem Orchestrierungsgraphen (wohin es geht) und dem Richtlinienmotor (was es tun darf). Vereinbaren Sie diese Regeln frühzeitig, dann wird ein plötzlicher Anstieg in ein gelöstes Problem statt in einen Notfall.
Ein Vertrag mit drei Schichten
Schicht 1: Die Warteschlange als Kontrollinstanz
Die Warteschlange ist der erste Ort, an dem Regeln durchgesetzt werden. Bevor eine Anfrage einen Agenten erreicht, wird sie einer Vertragsprüfung unterzogen, die drei Aspekte abdeckt:
- Priorität. Die Anfragen sind nicht gleichwertig. Interaktive Benutzeranfragen können eine höhere Priorität haben als Batch-Aufträge, und ein zahlender Kunde kann einer kostenlosen Version vorgezogen werden. Die Warteschlange sollte diese Reihenfolge steuern, sodass die Agenten nichts davon wissen müssen.
- Rate Limits und Quoten. Nein zu sagen ist am günstigsten, bevor Rechenleistung verbraucht wird. Ein Benutzer, der die tägliche API-Grenze erreicht hat, sollte eine klare Ablehnung erhalten und nicht in der Warteschlange landen – das kostet weitaus weniger als ein Eingreifen eines Agenten.
- Befolgung des Schemas. Eingaben, die das System nicht verarbeiten kann, sollten hier abgelehnt werden und nicht erst innerhalb eines Agenten entdeckt werden.
Dieser Layer garantiert, dass jede in der Warteschlange befindliche Anfrage validiert, bewertet und zur Nutzung von Ressourcen freigegeben wurde.
Layer 2: Die Orchestrierung bestimmt Routing und Tempo
Nachdem eine Anfrage in die Warteschlange eingereiht wurde, wählt das Orchestrierungssystem ihren Zielort sowie die zugelassenen Aktionen aus. Hier werden Konkurrenzsituationen und der Zugriff auf Tools gesteuert.
Das Routing-Vertragsmodell beantwortet einige Fragen: Welche Gruppe von Agenten soll die Anfrage bearbeiten – beispielsweise schnelle Agenten für einfache Abfragen und langsamere für komplexe Berechnungen? Wie viele Anfragen kann jeder Agent gleichzeitig verarbeiten? Was passiert, wenn alle Agenten beschäftigt sind: Warteschlange, Ablehnung oder Rückfall auf eine Alternative?
Das Tool-Throttling-Vertragsmodell berücksichtigt, dass Tools unterschiedlich sind. Das Aufrufen einer externen API hundertmal pro Sekunde unterscheidet sich stark vom Ausführen einer lokalen Verarbeitung. Jedes Tool hat seine eigene Konkurrenzgrenze. Ein tool-basiertes System mit Datenbankunterstützung könnte zehn gleichzeitige Aufrufe zulassen, während ein Tool, das auf eine API eines Drittanbieters zugreift, vielleicht nur fünf zulässt. Wenn ein Tool seine Grenze erreicht, wartet die Anfrage in der eigenen Warteschlange des Tools und nicht in der Hauptwarteschlange.
Um diese Tool-Warteschlangen gesund zu halten und das Ausbreiten von Fehlern zu verhindern, helfen Produktionssysteme mit speziellen Mechanismen:
- Circuit Breaker und Token-Bucket-Systeme greifen auf Tool-Ebene schnell ein, wodurch Wiederholungsanfragen verhindert werden, wenn eine Abhängigkeit überlastet ist.
- Dead-Letter-Warteschlangen speichern fehlerhafte oder schädliche Tool-Daten, sodass eine einzige fehlerhafte Anfrage niemals den gesamten Agentenprozess stoppt.
- Pro Tool vorhandene „leaking buckets“ wenden jeweils die eigenen Geschwindigkeitsbeschränkungen an, was parallele Agentenläufe vor externen Einschränkungen schützt.
Durch diese Mechanismen bleiben Engpässe auf Tool-Ebene eingedämmt und sichtbar und breiten sich nicht zu systemweiter Instabilität aus. Das Versprechen dieser Schicht: Eine Anfrage wird an einen Agenten mit freier Kapazität weitergeleitet, jedes Tool hält sich an seine Konkurrenzbeschränkungen, und wenn ein Tool überlastet ist, wartet die Anfrage auf das Tool und nicht auf den Agenten.
Schicht 3: Richtlinien, die sich niemals ändern
Das Schwierige ist, dass die Richtlinien jedes Mal ausgeführt werden müssen, auch unter Last. Es gibt weder eine Option „später überprüfen“ noch die Möglichkeit, anzunehmen, „diese sei sicher“.
Der Vertrag der Richtlinie umfasst vier Klauseln:
- Die Richtlinienprüfung erfolgt vor jedem Toolaufruf, synchron und blockierend.
- Die Prüfung ist kostengünstig – höchstens ein paar Millisekunden. Ist das nicht der Fall, ist das Design fehlerhaft.
- Wenn die Prüfung fehlschlägt, scheitert auch der Anfrage. Der Agent hat keine Chance, es erneut zu versuchen oder zu verhandeln.
- Fehler werden protokolliert und überwacht, und ein Anstieg der Richtlinienfehler ist an sich ein Signal.
Typische Richtlinien sehen so aus: Ein Agent darf nur Tools verwenden, die für diesen Benutzer als „nur zum Lesen“ gekennzeichnet sind; ein Tool darf nur für einen authentifizierten Anrufer ausgeführt werden; ein Agent darf pro Anfrage höchstens fünf Toolaufrufe tätigen. Die Schicht garantiert, dass vor jedem Toolaufruf eine Überprüfung stattfindet und dass die Richtlinien schnell, deterministisch und absolut sind.
Die Struktur der Pipeline
In einem minimalen Pseudo-Graphen tritt eine Anfrage über den Warteschlangen-Wächter ein, gelangt zum Router, erreicht einen Agenten, und jeder Toolaufruf durchläuft vor der Ausführung die Richtlinienüberprüfung sowie eine pro Tool festgelegte Beschränkung.
[ Incoming Request ]
│
▼
[ Queue Gatekeeper ]
• Validate Schema
• Enforce Rate Limits
• Assign Priority
│ (Pass)
▼
[ Orchestration Router ]
• Check Agent Capacity
• Route to Target Node
│
▼
[ Tool-Level Gate ]
• Sync Policy Check
• Per-Tool Concurrency Limits
• Circuit Breaker / DLQ
│ (Pass)
▼
[ Tool Execution ]
Der wichtige Punkt ist, wo die Richtlinien angewendet werden. Sie gelten auf Tool-Ebene und nicht auf Agent-Ebene, wodurch verhindert wird, dass ein Agent sie versehentlich umgeht, indem er ein Tool auf unerwartete Weise verwendet.
Ein Ansturmszenario – mit und ohne Vertrag
Stellen Sie sich einen Kundenservice-Agenten vor, der Bestellungen abrufen, Rückerstattungen bearbeiten und E-Mails versenden kann, und plötzlich steigt die Anzahl der Anfragen um das Zehnfache an.
Ohne Vertrag entwickelt sich der Fehler schrittweise:
- Die eingehenden Anfragen erschöpfen die verfügbaren Agenten.
- Die Agenten stellen Tool-Aufrufe in die Warteschlange, und das send_email-Tool sammelt 500 ausstehende Aufrufe an.
- Der E-Mail-Service beginnt, Zeitüberschreitungen zu melden.
- Die Agenten versuchen es erneut, sodass nun 1.000 Aufrufe warten.
- Fail-open-Pfade werden aktiviert. Zeitüberschreitungen oder überlastete Fallback-Routen umgehen die Richtlinien, um die Verfügbarkeit des Systems zu gewährleisten.
- Ein Agent sendet eine Rückerstattungse-Mail an den falschen Kunden.
Mit einem Vertrag verläuft derselbe Ablauf anders:
- Der Warteschlangen-Controller regelt die Zulassung nach Priorität und Quoten.
- Der Router stellt fest, dass das E-Mail-Sendeverfahren seine Konkurrenzgrenze von zehn erreicht hat, und stellt weitere E-Mail-Anfragen in die Warteschlange für dieses Verfahren und nicht für den Agenten.
- Die Richtlinienprüfungen laufen bei jedem Aufruf des Verfahrens weiter. Wenn ein Agent versucht, eine Rückerstattung an den falschen Kunden zu senden, scheitert die Prüfung und die Anfrage wird abgelehnt.
- Das System bleibt stabil. Die Latenz steigt, doch die Zuverlässigkeit sinkt nicht.
Zusammenfassung
Starten Sie bei LangGraph
Ein Team, das bereits bei LangGraph tätig ist, besitzt den Großteil der Primitiven. Agenten und Tools sind Knoten, Kanten stellen Routing-Entscheidungen dar, und bedingte Kanten leiten den Datenfluss je nach Zustand. Was hinzugefügt werden muss, ist eine Warteschlange – sei es Redis, RabbitMQ oder eine einfache In-Memory-Warteschlange – sowie ein Policy-Middleware, das die Tool-Aufrufe umschließt.
Der Policy-Wrapper selbst kann ein kleiner Dekorator sein, der die Überprüfungen durchführt und vor der Ausführung der Tool-Funktion einen Fehler wegen Verstößen auslöst.
from functools import wraps
from typing import Callable, Any
class PolicyViolation(Exception):
"""Raised when policy check fails."""
pass
def enforce_tool_policy(
policy_fn: Callable[[str, dict], bool]
):
"""Sync tool execution guardrail."""
def decorator(func: Callable):
@wraps(func)
def wrapper(*args, **kwargs):
tool_name = func.__name__
context = kwargs.get(
"request_context", {}
)
# Must fail closed
if not policy_fn(tool_name, context):
raise PolicyViolation(
f"Denied: {tool_name}"
)
return func(*args, **kwargs)
return wrapper
return decorator
# Example Usage
def strict_policy_check(tool_name: str, context: dict) -> bool:
if not context.get("is_authenticated"):
return False
if (context.get("role") != "admin" and tool_name.startswith("execute_")):
return False
return True
@enforce_tool_policy(strict_policy_check)
def execute_refund(
order_id: str,
amount: float,
request_context: dict = None
):
# Downstream API call
return f"Refund ${amount} sent: {order_id}"
Messen Sie es
Es reicht nicht aus, dies umzusetzen und zu hoffen. Instrumentalisieren Sie es und beobachten Sie:
- Die Warteschlangentiefe in jeder Schicht.
- Wie oft und welche Tools ihre Grenzen erreichen.
- Ob Richtlinien Anfragen ablehnen und warum.
- Die p50-, p95- und p99-Latenzen, die für verschiedene Anfragenarten getrennt erfasst werden.
- Die Kosten pro Anfrage unter Last. Steigen diese, verbirgt sich dahinter Ineffizienz.
Eine skeptische Sicht
Es ist berechtigt, zu sagen, dass dies wie eine Menge Infrastruktur für ein noch nicht vorhandenes Problem erscheint. Ein System, das zehn Anfragen pro Sekunde verarbeitet und dabei bleibt, benötigt sie nicht. Funktionen, die viral gehen könnten, oder Unternehmenskunden mit unvorhersehbarem Traffic, sind eine andere Geschichte – das Design muss bereits vor dem Launch fertig sein.
Building it in advance costs little next to retrofitting it after a spike has broken the system. It also shouldn't be overbuilt. A simple queue, a policy check function and per-tool concurrency limits resolve most spike problems. Neither a distributed consensus algorithm nor a machine-learning load predictor is needed. What matters is clarity and constraints.
Main points
- Spikes expose design problems. When an agent system breaks under load, the agents are not too slow. Nobody set clear rules for how the queue, the routing and the policies fit together.
- The queue doubles as an enforcement point. It can validate, prioritize and reject requests so compute is not wasted.
- Policies are absolute and non-negotiable. They run at the tool level, synchronously, every time, with no exceptions.
- Beschränken Sie die Tools vor den Agenten. Engpässe liegen in der Regel weiter flussabwärts, in externen APIs oder Datenbanken, die den Agenten mit Kontext versorgen, und nicht beim LLM-Anbieter.
- Messen Sie alles: Warteschlangentiefe, Konkurrenz bei den Tools, Policy-Fehler, Latenzprozente sowie Kosten pro Anfrage. Was nicht gemessen wird, kann nicht verbessert werden.
Wo anzufangen
- Legen Sie den Warteschlangenvertrag fest: Was wird akzeptiert und was abgelehnt?
- Legen Sie den Routing-Vertrag fest: Welche Agenten übernehmen welche Aufgaben und wie hoch sind die Konkurrenzlimits?
- Legen Sie den Policy-Vertrag fest: Welche Überprüfungen finden vor jedem Toolaufruf statt?
- Bauen Sie dies mit einem Tool wie LangGraph auf, fügen Sie eine Warteschlangenschicht hinzu und umhüllen Sie die Tools mit Policy-Überprüfungen.
- Führen Sie Lasttests durch. Simulieren Sie einen zehnfachen Anstieg und beobachten Sie, was ausfällt.
Alles das lässt sich am besten vor der Produktion erledigen, solange noch Zeit ist, ruhig damit umzugehen.
Verwandte Artikel
- Ein Agent ist ein While-Loop: Wo LangChain create_agent und LangGraph Fit zum Einsatz kommen — Ein tool-basierter Agent in zwanzig Zeilen, die vier Produktionsprobleme, mit denen solche Schleifen konfrontiert sind, sowie wann man von LangChain create_agent zu LangGraph State Graphs wechseln sollte.
- Praktische Notizen: Ich habe eine Mehr-Agenten-Debatteschleife gebaut und nie nachgesehen, was passiert — Eine schrittweise Anleitung zu „Praktische Notizen: Ich habe eine Mehr-Agenten-Debatteschleife gebaut und nie nachgesehen, was passiert“: Verträge, Überprüfungen sowie Code-Blöcke, die Teams nutzen können, die dieses Muster implementieren.