Problem
In den Traces eines Runs sieht man eine Warteschleife:
Agent A -> Agent B -> Agent C -> Agent A.
In 20 Minuten können 40+ Runs im Status waiting landen.
Die Queue wächst, Worker sind beschäftigt, aber nützliche Arbeit passiert fast nicht.
Von außen wirkt alles "ruhig": kein klarer Fehler, kein Service-Crash. Aber der Run endet nicht, weil alle drei Agenten nur aufeinander warten.
Das System crasht nicht.
Es hängt einfach und verbrennt leise Ressourcen.
Analogie: Stell dir drei Personen in einer Tür vor, die sich höflich gegenseitig den Vortritt lassen. Niemand streitet, niemand macht einen "Fehler", aber niemand geht durch. Genau so sieht ein Deadlock in Multi-Agent-Systemen aus.
Warum das passiert
Deadlock entsteht nicht, weil Agenten zu lange "nachdenken", sondern weil das System nicht weiß, wer den Zustand als Nächstes weiterbewegen soll.
In Production sieht das meistens so aus:
- Agenten tauschen Nachrichten aus und hängen voneinander ab;
- ein Warten verzögert sich (Tool, Approval, Lock);
- weitere Agenten gehen ebenfalls in
waiting; - ohne Timeout und Owner des workflow-Zustands bleibt der workflow stecken.
Das Problem liegt nicht bei einem einzelnen Agenten. Das Problem ist unkontrollierte Koordination zwischen Agenten.
Welche Ausfälle am häufigsten auftreten
Praktisch gesehen sieht man bei Deadlocks meist vier Muster.
Zirkuläres Warten (Circular wait)
Agent A wartet auf B, B wartet auf C, C wartet auf A. Alle sind "beschäftigt", aber es gibt keinen Fortschritt.
Typische Ursache: Der Abhängigkeitsgraph enthält einen Zyklus, und es gibt keinen einzelnen Orchestrator.
Lock ohne TTL (Lock without lease)
Ein Agent holt sich einen Lock auf Dokument/Ticket und crasht. Andere Agenten warten endlos auf diesen Lock.
Typische Ursache: Lock ohne Lease/TTL und ohne Recovery-Mechanismus für den Owner.
Hängende Wartestatus (Unbounded waiting)
Es gibt ein HTTP-Timeout, aber kein Timeout für interne Agent-Waits. Der workflow kann "ewig" warten.
Typische Ursache: Timeouts sind nur auf Transport-Ebene umgesetzt, nicht auf Ebene der Orchestration-Zustände.
Retry-Zyklus zwischen Agenten (Cross-agent retry loop)
Agenten reichen die Aufgabe untereinander mit "prüf nochmal" weiter, und daraus wird endloses Ping-Pong.
Typische Ursache: kein Retry-Limit und kein Stop Reason für Blocked-State-Szenarien.
Wie man diese Probleme erkennt
Deadlock wird über die Kombination von workflow- und runtime-Metriken sichtbar.
| Metrik | Deadlock-Signal | Was tun |
|---|---|---|
waiting_runs | Anzahl der Runs in waiting steigt dauerhaft | Wait-Timeout und Stop Reason für Blocked-State ergänzen |
wait_duration_p95 | Wartezeit liegt über der Norm | Wartezeit bei jeder State Transition begrenzen |
blocked_transition_rate | häufige Blockierung zwischen denselben Agenten | Abhängigkeitsgraph auf Zyklen prüfen |
lease_conflict_rate | häufige Konflikte oder abgelaufene Leases | TTL, Renew und Recovery-Policy ergänzen |
queue_backlog | Queue wächst trotz normalem eingehendem Traffic | hängende Runs bereinigen, Fallback-Mode aktivieren |
Wie man Deadlock von einer wirklich langen Aufgabe unterscheidet
Nicht jeder lange Run ist ein Deadlock. Das zentrale Kriterium: gibt es State Transitions und echten Fortschritt?
Normal, wenn:
- workflow-Status sich erwartbar ändert;
- nach dem Warten ein neues Artefakt oder ein neuer Schritt erscheint;
- es einen klaren Owner der aktuellen Transition gibt.
Gefährlich, wenn:
- ein Run lange im gleichen
waiting-Status bleibt; - mehrere Agenten gleichzeitig aufeinander warten;
- es keinen klaren Stop Reason gibt, warum das System nicht weitergeht.
Wie man solche Ausfälle stoppt
Praktisch sieht das so aus:
- einen Owner für Transitions einführen (Orchestrator oder Leader);
- Timeout auf jeden
waiting-Status setzen; - Lease/TTL für Shared Resources verwenden;
- bei No-Progress den Run kontrolliert beenden: Stop Reason + Fallback.
Minimaler Guard für Wait-State:
import time
class WaitGuard:
def __init__(self, wait_timeout_s: int = 30):
self.wait_timeout_s = wait_timeout_s
self.wait_started_at: dict[str, float] = {}
def mark_wait_start(self, run_id: str):
self.wait_started_at[run_id] = time.time()
def check_wait(self, run_id: str):
started = self.wait_started_at.get(run_id)
if started is None:
return None
if time.time() - started > self.wait_timeout_s:
return "deadlock_risk:wait_timeout"
return None
In Production wird mark_wait_start(...) meist beim Wechsel in waiting aufgerufen,
und check_wait(...) in Scheduler oder Heartbeat-Loop, um hängende Runs rechtzeitig zu beenden.
Wo das in der Architektur umgesetzt wird
Deadlock-Kontrolle in Production ist meist auf mehrere Schichten verteilt.
Agent Runtime steuert den Run-Lifecycle:
Timeouts, Stop Reasons, erzwungenes Beenden hängender Zustände und Fallback-Transitions.
Hier werden typischerweise deadlock_risk:*-Regeln gesetzt.
Orchestration Topologies definiert, wer State Transitions besitzt und wie Agenten ohne zirkuläres Warten zusammenarbeiten. Ohne klaren Owner für Zustände wird Deadlock nur eine Frage der Zeit.
Tool Execution Layer deckt den technischen Teil ab: Lease/TTL für Shared Resources, eine einheitliche Retry-Policy und Kontrolle von Waits auf Tool-Ebene.
Selbstcheck
Schneller Check vor dem Release. Hake die Punkte ab und sieh dir den Status unten an.
Das ist ein kurzer Sanity-Check, kein formales Audit.
Fortschritt: 0/9
⚠ Es gibt Risikosignale
Grundlegende Kontrollen fehlen. Schließen Sie die wichtigsten Checklist-Punkte vor dem Release.
FAQ
Q: Gibt es Deadlocks nur in großen Multi-Agent-Systemen?
A: Nein. Schon 2-3 Agenten können eine Warteschleife bilden, wenn es keinen expliziten State-Owner gibt.
Q: Reicht es, nur Timeouts zu ergänzen?
A: Timeouts begrenzen das Hängen, beseitigen aber nicht die Ursache. Du brauchst zusätzlich Orchestrator und klare State Transitions.
Q: Lösen Leases Deadlock vollständig?
A: Nein. Leases lösen Lock-Probleme nach Crashes, aber keine logischen Zyklen zwischen Agenten.
Q: Was tun, wenn ein Run bereits in waiting hängt?
A: Run mit Stop Reason erzwungen beenden, Lease freigeben, workflow auf Fallback schalten und Waiting-Kette in Traces analysieren.
Deadlock sieht fast nie wie ein lauter Ausfall aus. Meist ist es ein stiller Fortschrittsstopp, der Worker und Budget frisst. Deshalb brauchen Production-Multi-Agent-Systeme nicht nur Rollenaufteilung, sondern strikte Orchestration-Disziplin.
Verwandte Seiten
Für eine tiefere Abdeckung dieses Problems:
- Warum AI-Agenten scheitern - allgemeine Karte von Ausfällen in Production.
- Multi-agent chaos - wie unkontrollierte Agent-Interaktion Stabilität zerstört.
- Partial outage - wie partielle Degradation von Abhängigkeiten Waiting-Status erzeugt.
- Agent Runtime - wo Stop Reasons, Timeouts und Run-Lifecycle gesteuert werden.
- Orchestration Topologies - wie man kontrollierte Koordination zwischen Agenten entwirft.