Deadlocks in Multi-Agent-Systemen (Failure Mode + Fixes + Code)

  • Erkenne den Fehler früh, bevor die Rechnung steigt.
  • Verstehe, was in Prod bricht – und warum.
  • Guardrails kopieren: Budgets, Stop-Reasons, Validation.
  • Wissen, wann das nicht die Root Cause ist.
Erkennungs-Signale
  • Tool-Calls pro Run steigen (oder wiederholen sich mit args-hash).
  • Kosten/Tokens pro Request steigen ohne bessere Ergebnisse.
  • Retries kippen von selten zu konstant (429/5xx).
Agents, die auf Agents warten, sind Distributed Deadlocks mit netteren Logs. Leases, Timeouts und Orchestration verhindern Hänger in Prod.
Auf dieser Seite
  1. Problem (aus der Praxis)
  2. Warum das in Production bricht
  3. 1) Circular Dependencies sind easy
  4. 2) Keine Timeouts auf “waiting”
  5. 3) Shared Resources ohne Leases
  6. 4) “Frag einen anderen Agent” wird Retry Loop
  7. 5) Fix = Orchestration, nicht Prompting
  8. Implementierungsbeispiel (echter Code)
  9. Echter Incident (mit Zahlen)
  10. Abwägungen
  11. Wann du es NICHT nutzen solltest
  12. Checkliste (Copy/Paste)
  13. Sicheres Default-Config-Snippet (JSON/YAML)
  14. FAQ (3–5)
  15. Verwandte Seiten (3–6 Links)
Interaktiver Ablauf
Szenario:
Schritt 1/2: Execution

Normal path: execute → tool → observe.

Problem (aus der Praxis)

Du baust ein Multi-Agent Setup:

  • “research agent”
  • “planner agent”
  • “executor agent”
  • “reviewer agent”

Im Diagramm sieht’s super aus.

In Production hängt ein Request für immer, weil:

  • Agent A wartet auf Agent B
  • Agent B wartet auf Agent C
  • Agent C wartet auf Agent A

Niemand ist “falsch”. Alle warten.

Das ist ein Deadlock.

Deadlocks sind fies, weil sie nicht crashen. Sie hängen. Und Hängen verbrennt Budgets leise.

Warum das in Production bricht

Multi-Agent erbt jedes Distributed-Systems Failure Mode, plus LLM Ambiguität.

1) Circular Dependencies sind easy

“Planner fragt Researcher, Researcher fragt Reviewer, Reviewer fragt Planner.” Cycle gebaut.

2) Keine Timeouts auf “waiting”

HTTP bekommt Timeouts. Agent Messages oft nicht. Also wartet der Worker forever.

3) Shared Resources ohne Leases

Shared Ticket/Doc/Lock ohne TTL → Crash lässt System blockiert zurück.

4) “Frag einen anderen Agent” wird Retry Loop

Unsicherheit → anderer Agent → nochmal → dritter Agent. Deadlock wird Tool Spam.

5) Fix = Orchestration, nicht Prompting

Du promptest dich nicht aus Deadlocks heraus. Du brauchst:

  • Orchestrator/Leader
  • explizite State Machine
  • Timeouts/Leases
  • Stop Reason wenn kein Progress möglich

Implementierungsbeispiel (echter Code)

Minimaler Lease-Lock:

  • acquire lease für resource_id
  • lease expire’t bei Crash
  • orchestrator kann recovern
PYTHON
from dataclasses import dataclass
import time


@dataclass
class Lease:
  owner: str
  expires_at: float


class LeaseLock:
  def __init__(self) -> None:
      self._leases: dict[str, Lease] = {}

  def try_acquire(self, *, resource_id: str, owner: str, ttl_s: int) -> bool:
      now = time.time()
      lease = self._leases.get(resource_id)
      if lease and lease.expires_at > now and lease.owner != owner:
          return False
      self._leases[resource_id] = Lease(owner=owner, expires_at=now + ttl_s)
      return True

  def release(self, *, resource_id: str, owner: str) -> None:
      lease = self._leases.get(resource_id)
      if lease and lease.owner == owner:
          del self._leases[resource_id]


def run_work(orchestrator_id: str, resource_id: str, lock: LeaseLock) -> str:
  if not lock.try_acquire(resource_id=resource_id, owner=orchestrator_id, ttl_s=30):
      return "blocked: lease held"

  try:
      return orchestrate(resource_id)  # (pseudo)
  finally:
      lock.release(resource_id=resource_id, owner=orchestrator_id)
JAVASCRIPT
export class LeaseLock {
constructor() {
  this.leases = new Map(); // resourceId -> { owner, expiresAtMs }
}

tryAcquire({ resourceId, owner, ttlS }) {
  const now = Date.now();
  const lease = this.leases.get(resourceId);
  if (lease && lease.expiresAtMs > now && lease.owner !== owner) return false;
  this.leases.set(resourceId, { owner, expiresAtMs: now + ttlS * 1000 });
  return true;
}

release({ resourceId, owner }) {
  const lease = this.leases.get(resourceId);
  if (lease && lease.owner === owner) this.leases.delete(resourceId);
}
}

Das verhindert die schlimmste Klasse: “System stuck, weil ein Agent beim Lock gestorben ist”. Und: Timeouts auf “agent waits”. Ein Wait ohne Timeout ist Schlaf, den du bezahlst.

Echter Incident (mit Zahlen)

Multi-Agent “incident triage”:

  • Agent A sammelt Signale
  • Agent B schreibt Hypothese
  • Agent C checkt Runbook

Runbook Tool degradete. Agent C wartete. Agent B wartete auf C. Agent A wartete auf B.

Impact:

  • 43 Runs stuck in “waiting”
  • Worker saturiert, neue Requests queued
  • on-call verbrannte ~2 Stunden mit canceln + State cleanup

Fix:

  1. Timeouts auf inter-agent waits
  2. orchestrator-owned leases pro incident id
  3. stop reasons: “blocked waiting for tool” vs “blocked waiting for approval”
  4. fallback: single-agent mode bei degraded deps

Multi-Agent macht Coordination zu deinem Problem. Nicht zu dem des LLM.

Abwägungen

  • Orchestration Code kostet Zeit. Spart Deadlocks.
  • Leases können mid-work expir’n; du brauchst Idempotency + Replay.
  • Single-agent fallback senkt Qualität, erhöht Liveness.

Wann du es NICHT nutzen solltest

  • Kleine Tasks: Multi-Agent ist Overhead.
  • Kein Orchestration+Observability? Nicht shippen.
  • Strikte Order/Consistency? Workflows mit expliziten State Machines.

Checkliste (Copy/Paste)

  • [ ] Cycles vermeiden (Graph aufzeichnen)
  • [ ] Timeouts auf waits
  • [ ] Leases/TTLs für shared resources
  • [ ] Orchestrator owns state transitions
  • [ ] Idempotency keys für writes
  • [ ] Stop reasons + alerting
  • [ ] Fallback mode bei degraded deps

Sicheres Default-Config-Snippet (JSON/YAML)

YAML
multi_agent:
  orchestrator: "single_owner"
  wait_timeouts_s: { default: 30 }
  leases:
    ttl_s: 30
    renew: true
fallback:
  enabled: true
  mode: "single_agent"

FAQ (3–5)

Sind Multi-Agent Systeme immer schlecht?
Nein, aber sie adden Coordination + Failure Modes. Plane Orchestration ein.
Fixen Leases Deadlocks?
Sie fixen lock-based deadlocks durch Crashes. Logische Cycles fixen sie nicht — Cycles vermeiden.
Einfachste Prevention?
Ein Orchestrator + Timeouts auf waits. Ohne Timeouts wird ‘waiting’ zu ‘stuck’.
Wie debugge ich Deadlocks?
State transitions loggen + wait chain sichtbar machen. Ohne das rätst du.

Q: Sind Multi-Agent Systeme immer schlecht?
A: Nein, aber sie adden Coordination + Failure Modes. Plane Orchestration ein.

Q: Fixen Leases Deadlocks?
A: Sie fixen lock-based deadlocks durch Crashes. Logische Cycles fixen sie nicht — Cycles vermeiden.

Q: Einfachste Prevention?
A: Ein Orchestrator + Timeouts auf waits. Ohne Timeouts wird “waiting” zu “stuck”.

Q: Wie debugge ich Deadlocks?
A: State transitions loggen + wait chain sichtbar machen. Ohne das rätst du.

Nicht sicher, ob das dein Fall ist?

Agent gestalten ->
⏱️ 5 Min. LesezeitAktualisiert Mär, 2026Schwierigkeit: ★★☆
In OnceOnly umsetzen
Guardrails for loops, retries, and spend escalation.
In OnceOnly nutzen
# onceonly guardrails (concept)
version: 1
budgets:
  max_steps: 25
  max_tool_calls: 12
  max_seconds: 60
  max_usd: 1.00
policy:
  tool_allowlist:
    - search.read
    - http.get
controls:
  loop_detection:
    enabled: true
    dedupe_by: [tool, args_hash]
  retries:
    max: 2
    backoff_ms: [200, 800]
stop_reasons:
  enabled: true
logging:
  tool_calls: { enabled: true, store_args: false, store_args_hash: true }
Integriert: Production ControlOnceOnly
Guardrails für Tool-Calling-Agents
Shippe dieses Pattern mit Governance:
  • Budgets (Steps / Spend Caps)
  • Kill switch & Incident Stop
  • Audit logs & Nachvollziehbarkeit
  • Idempotenz & Dedupe
  • Tool-Permissions (Allowlist / Blocklist)
Integrierter Hinweis: OnceOnly ist eine Control-Layer für Production-Agent-Systeme.
Beispiel-Policy (Konzept)
# Example (Python — conceptual)
policy = {
  "budgets": {"steps": 20, "seconds": 60, "usd": 1.0},
  "controls": {"kill_switch": True, "audit": True},
}
Autor

Diese Dokumentation wird von Engineers kuratiert und gepflegt, die AI-Agenten in der Produktion betreiben.

Die Inhalte sind KI-gestützt, mit menschlicher redaktioneller Verantwortung für Genauigkeit, Klarheit und Produktionsrelevanz.

Patterns und Empfehlungen basieren auf Post-Mortems, Failure-Modes und operativen Incidents in produktiven Systemen, auch bei der Entwicklung und dem Betrieb von Governance-Infrastruktur für Agenten bei OnceOnly.