Teilausfall: Wenn ein Teil des Agent-Systems ausfällt

Ein Teilausfall entsteht, wenn nur ein Teil eines Agent-Systems nicht mehr funktioniert, während der Rest weiterläuft. Auswirkungen und typische Ursachen.
Auf dieser Seite
  1. Das Problem
  2. Warum das passiert
  3. Welche Ausfälle am häufigsten auftreten
  4. Intermittent-success-Falle (Intermittent success trap)
  5. Retry amplification über Schichten
  6. Queue wird durch "laute" Runs blockiert (Queue starvation)
  7. Warten auf "perfekte" Antwort ohne degrade path
  8. Wie man diese Probleme erkennt
  9. Wie man partial outage von full outage unterscheidet
  10. Wie man solche Ausfälle stoppt
  11. Wo das in der Architektur umgesetzt wird
  12. Selbstcheck
  13. FAQ
  14. Verwandte Seiten

Das Problem

Die Anfrage wirkt einfach: Zahlungsstatus prüfen und dem Kunden kurz antworten.

In Traces sieht man etwas anderes: in 11 Minuten machte ein Run 33 Aufrufe, davon 10 mit 200, 14 mit timeout, und 9 mit 502/503. Für eine Aufgabe dieser Klasse kann das etwa ~$1.90 statt der üblichen ~$0.14 sein.

Der Service ist formal "lebendig": ein Teil der Aufrufe geht durch, es gibt keinen kompletten Ausfall. Aber die Run-Queue wächst, latency springt, und User bekommen instabile Ergebnisse.

Das System stürzt nicht ab.

Es bleibt langsam zwischen seltenen Erfolgen und wiederholten Fehlern stecken.

Analogie: Stell dir eine Kasse vor, bei der das Terminal mal Karte akzeptiert und mal hängt. Der Laden ist nicht geschlossen, aber die Schlange wächst jede Minute. Teilausfall in Agent-Systemen funktioniert genauso: die Infrastruktur scheint verfügbar, aber ein stabiler Pfad zur Antwort existiert nicht mehr.

Warum das passiert

In production läuft es meist so:

  1. eine Abhängigkeit wird instabil (timeout, 5xx, manchmal 200);
  2. retries starten gleichzeitig in mehreren Schichten;
  3. Run hält Worker länger, Queue wächst;
  4. andere workflows werden wegen gemeinsamer Ressourcen ebenfalls langsamer;
  5. ohne fail-fast und safe-mode vervielfacht das System Kosten statt den Fehler zu isolieren.

Im Trace sieht man ein gemischtes Muster: tool_2xx_rate ist noch vorhanden, gleichzeitig steigen aber timeout_rate, retry_attempts_per_run und queue_backlog.

Das Problem ist nicht ein einzelner timeout.

Runtime schaltet die instabile Abhängigkeit nicht in degraded mode, solange der Fehler noch lokal bleibt.

Welche Ausfälle am häufigsten auftreten

In production sieht man bei partial outage am häufigsten vier Muster.

Intermittent-success-Falle (Intermittent success trap)

Tool liefert gelegentlich 200, und das maskiert die Degradation. Der Agent drückt weiter denselben Kanal statt kontrolliert umzuschalten.

Typische Ursache: keine "Health"-Schwelle der Abhängigkeit auf Run-Ebene.

Retry amplification über Schichten

HTTP-Client, gateway und runtime führen jeweils eigene retries aus. Schon ein kleiner Fehleranstieg wird schnell zur Welle unnötiger Aufrufe.

Typische Ursache: retry policy ist nicht zentralisiert.

Queue wird durch "laute" Runs blockiert (Queue starvation)

Problematische Runs hängen lange, belegen den worker pool und verdrängen gesunde Aufgaben.

Typische Ursache: fehlende Limits für Run-Dauer und budget-gates.

Warten auf "perfekte" Antwort ohne degrade path

System versucht auf ein "ideales" Ergebnis zu warten, obwohl die Abhängigkeit klar degradiert.

Typische Ursache: kein partial/fallback-Vertrag für User.

Wie man diese Probleme erkennt

Partial outage sieht man gut über die Kombination aus health-, runtime- und queue-Metriken.

MetrikSignal für partial outageWas tun
degraded_dependency_rateeine Abhängigkeit liefert oft timeout/5xxdegraded mode aktivieren und fan-out reduzieren
tool_2xx_with_high_timeout_rategleichzeitig 200 und hoher timeout-AnteilHealth-Schwelle ergänzen, nicht nur auf 200 schauen
retry_attempts_per_runauffällig viele Wiederholungen pro Runretries zentralisieren und retry budget begrenzen
run_duration_p95lange "hängende" Runsfail-fast-timeout und stop reasons einführen
queue_backlogQueue wächst bei normalem Trafficdegradierten Pfad isolieren und fallback einschalten

Wie man partial outage von full outage unterscheidet

Nicht jede Degradation ist ein full outage. Die Kernfrage: gibt es einen stabilen Ausführungspfad oder nur zufällige "Erfolge".

Normal für full outage, wenn:

  • fast alle Aufrufe gleichmäßig fehlschlagen (5xx oder komplette Nichtverfügbarkeit);
  • System schnell in fail-fast wechselt;
  • es keine Illusion von "manchmal funktioniert es" gibt.

Gefährlich für partial outage, wenn:

  • derselbe Run 200, timeout und 5xx mischt;
  • Agent Aufrufe wiederholt, weil er seltene Erfolge sieht;
  • queue/latency auch ohne klaren global incident steigen.

Wie man solche Ausfälle stoppt

Praktisch bedeutet das:

  1. health snapshot der Abhängigkeiten zu Run-Start fixieren;
  2. bei Schwellenverletzung workflow sofort in degraded mode schalten;
  3. retries in einem tool gateway mit hartem budget halten;
  4. partial/fallback mit explizitem stop reason zurückgeben statt "ewig" zu warten.

Minimaler Guard für partial outage:

PYTHON
from dataclasses import dataclass
import time


RETRYABLE = {408, 429, 500, 502, 503, 504}


@dataclass(frozen=True)
class OutageLimits:
    max_retry_per_call: int = 2
    max_retry_total: int = 6
    max_run_seconds: int = 45
    max_tool_calls: int = 14
    degraded_error_threshold: float = 0.35
    min_sample_size: int = 5


class PartialOutageGuard:
    def __init__(self, limits: OutageLimits = OutageLimits()):
        self.limits = limits
        self.started_at = time.time()
        self.tool_calls = 0
        self.retry_count = 0
        self.total_calls = 0
        self.error_calls = 0

    def before_tool_call(self) -> str | None:
        self.tool_calls += 1
        if self.tool_calls > self.limits.max_tool_calls:
            return "partial_outage:tool_call_budget"
        if (time.time() - self.started_at) > self.limits.max_run_seconds:
            return "partial_outage:run_timeout"
        return None

    def on_tool_result(self, status_code: int, attempt: int) -> str | None:
        self.total_calls += 1

        if status_code in RETRYABLE:
            self.error_calls += 1
            error_rate = self.error_calls / max(1, self.total_calls)
            if (
                self.total_calls >= self.limits.min_sample_size
                and error_rate >= self.limits.degraded_error_threshold
            ):
                return "partial_outage:degraded_mode"
            self.retry_count += 1
            if self.retry_count > self.limits.max_retry_total:
                return "partial_outage:retry_budget"
            if attempt >= self.limits.max_retry_per_call:
                return "partial_outage:retry_exhausted"
            return "partial_outage:retry_allowed"

        error_rate = self.error_calls / max(1, self.total_calls)
        if (
            self.total_calls >= self.limits.min_sample_size
            and error_rate >= self.limits.degraded_error_threshold
        ):
            return "partial_outage:degraded_mode"

        return None

In dieser Version zählt retry_count alle retryable Antworten innerhalb des Runs, und attempt ist die Wiederholungszahl eines konkreten Aufrufs.

Das ist ein Basis-Guard. In production wird er meist mit per-tool health probes, circuit breaker und separatem safe-mode-Pfad für degradierte Runs erweitert. before_tool_call(...) und on_tool_result(...) werden im tool gateway aufgerufen, damit Degradationsentscheidungen zentral statt pro Schicht getrennt getroffen werden.

Wo das in der Architektur umgesetzt wird

In production ist die Kontrolle von partial outage fast immer auf drei Systemschichten verteilt.

Tool Execution Layer liefert health signals: error rate, timeout patterns, retry budget und circuit breaker. Hier sieht man, dass eine Abhängigkeit bereits instabil ist, selbst wenn ein Teil der Aufrufe noch 200 liefert.

Agent Runtime trifft Entscheidungen pro Run: Wechsel in degraded mode, stop reasons und kontrollierter Abschluss mit fallback. Ohne diese Schicht wartet das System weiter auf "noch einen erfolgreichen Aufruf".

Orchestration Topologies definiert, wie degradierte workflows vom Rest des Systems isoliert werden (bulkheads, queues, Prioritäten). So wird lokale Degradation nicht zum gemeinsamen incident.

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/8

⚠ Es gibt Risikosignale

Grundlegende Kontrollen fehlen. Schließen Sie die wichtigsten Checklist-Punkte vor dem Release.

FAQ

Q: Warum ist partial outage oft schlimmer als full outage?
A: Weil er als "manchmal funktioniert es" maskiert ist. Das System stoppt nicht und verbrennt weiter Zeit, Tokens und worker pool.

Q: Soll ein degradiertes tool sofort deaktiviert werden?
A: Nicht immer. Üblicherweise aktiviert man degraded mode: retries begrenzen, fan-out reduzieren und auf partial/fallback-Pfad wechseln.

Q: Wo sollten retries und Degradationsentscheidungen getroffen werden?
A: In einem tool gateway. Sonst führt jede Schicht eigene retries aus und partial outage skaliert schnell.

Q: Was sollte dem User gezeigt werden, wenn eine Abhängigkeit degradiert?
A: Expliziter stop reason, was genau fehlgeschlagen ist, und ein kontrollierter nächster Schritt: Teilantwort oder erneuter Versuch nach Erholung der Abhängigkeit.


Partial outage sieht fast nie wie ein lauter Crash aus. Es ist eine stille Degradation: das System bewegt sich noch, hält aber Qualität und Tempo nicht mehr. Darum brauchen production-Agents nicht nur retries, sondern auch einen strikten Degradationsmodus und Isolierung von Abhängigkeiten.

Verwandte Seiten

Wenn dieses Problem in production auftritt, helfen auch diese Seiten:

⏱️ 7 Min. LesezeitAktualisiert 12. März 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

Nick — Engineer, der Infrastruktur für KI-Agenten in Produktion aufbaut.

Fokus: Agent-Patterns, Failure-Modes, Runtime-Steuerung und Systemzuverlässigkeit.

🔗 GitHub: https://github.com/mykolademyanov


Redaktioneller Hinweis

Diese Dokumentation ist KI-gestützt, mit menschlicher redaktioneller Verantwortung für Genauigkeit, Klarheit und Produktionsrelevanz.

Der Inhalt basiert auf realen Ausfällen, Post-Mortems und operativen Vorfällen in produktiv eingesetzten KI-Agenten-Systemen.