Zum Hauptinhalt springen
Lektion 2 von 14 · Mistral Workflows: Dauerhafte Orchestrierung

Zuverlässigkeit und Beständigkeit von Workflows

Lektion 2 von 14 Aktualisiert am 29. Juli 2026 Fortgeschritten
Auf dieser Seite
  1. Warum Beständigkeit alles verändert
  2. Event Sourcing: Das Kernprinzip
  3. Automatisches Wiederspielen: Wiederherstellung nach einem Fehler
  4. Fehlertoleranz: Abgedeckte Szenarien
  5. Die Determinismus-Einschränkung
  6. Vergleich mit traditionellen Ansätzen
  7. Genau einmal: Eine logische Garantie
  8. Kernaussagen

Warum Beständigkeit alles verändert

Stellen Sie sich eine Pipeline mit zehn Schritten zur Verarbeitung einer Batch von Rechnungen vor: Extraktion, Validierung, Modellaufruf, Datenbank-Schreibvorgang, Benachrichtigung. In einem herkömmlichen Python-Skript führt ein Absturz am Schritt 7 dazu, dass Sie bei Schritt 1 beginnen müssen. Die ersten sechs Schritte werden erneut ausgeführt, was zu erheblichen Problemen führt, falls einer dieser Schritte Daten in eine Datenbank geschrieben oder eine Nachricht gesendet hat. Mit einem beständigen Workflow (durable workflow) setzt das System exakt bei Schritt 7 fort. Es überspringt die ersten sechs Schritte, vermeidet die Duplizierung von Aktionen und verliert keine Daten.

Diese Fähigkeit beruht auf einem spezifischen Mechanismus namens Event Sourcing. Das Verständnis dieses Konzepts ist essenziell, da es die Einschränkungen erklärt, die Sie später antreffen werden.

Event Sourcing: Das Kernprinzip

Event Sourcing protokolliert jede Workflow-Aktion als unveränderliches Ereignis in einem Log. Der Unterschied zu einem traditionellen Ansatz lässt sich in einem Satz zusammenfassen: Anstatt nur den aktuellen Zustand zu speichern (z. B. „im Gange, Schritt 7”), behält die Plattform eine vollständige Historie der Operationen und ihrer Ergebnisse. Eine Workflow-Ausführung mit zwei Aktivitäten hinterlässt folgenden Verlauf:

  1. Der Workflow startet und erhält Eingabeparameter → Ereignis protokolliert
  2. Der Workflow ruft Aktivität A auf → Ereignis protokolliert
  3. Aktivität A schließt mit einem Ergebnis ab → Ereignis protokolliert
  4. Der Workflow ruft Aktivität B auf → Ereignis protokolliert
  5. Aktivität B schließt ab → Ereignis protokolliert
  6. Der Workflow gibt sein finales Ergebnis zurück → Ereignis protokolliert

Das System persistiert jeden Schritt vor dem Übergang zum nächsten. Es gibt keinen Zeitraum, in dem eine Aktion stattfindet, ohne dass das Log davon Kenntnis hat. Dieses Log wird zur einzigen Wahrheit (single source of truth); der Workflow-Zustand existiert an keiner anderen Stelle.

Automatisches Wiederspielen: Wiederherstellung nach einem Fehler

Wenn ein Worker abstürzt, übernimmt ein neuer Worker das Workflow-Protokoll und spielt den Workflow-Code von vorne ab. Der Begriff „Wiederspielen” (replay) überrascht viele: Der Code startet zwar erneut bei Zeile eins, aber für jede Aktivität, die bereits abgeschlossen wurde, ruft der Engine Ihre Funktion nicht erneut auf. Stattdessen ersetzt er das protokollierte Ergebnis aus dem Log. Der Workflow schreitet mit Lesegeschwindigkeit voran, bis er auf die erste unvollendete Aktivität trifft. Erst dann setzt die eigentliche Arbeit fort.

Aktivitäten, die bereits erfolgreich waren, werden während eines Wiederspiels niemals erneut ausgeführt. Das folgende Beispiel macht diese Garantie für den sensibelsten Fall greifbar: das Senden einer E-Mail.

import mistralai.workflows as workflows

@workflows.activity()
async def send_email(recipient: str, content: str) -> dict:
    """Diese Aktivität wird nur einmal ausgeführt,
    auch wenn der Workflow mehrere Male wiederspielt."""
    response = await email_service.send(recipient, content)
    return {"status": "sent", "id": response.id}

@workflows.workflow.define(name="notification_workflow")
class NotificationWorkflow:
    @workflows.workflow.entrypoint
    async def run(self, recipient: str) -> dict:
        # Wenn der Workflow nach dem Senden der E-Mail abstürzt,
        # wird die E-Mail während des Wiederspiels NICHT erneut gesendet.
        email_result = await send_email(recipient, "Ihr Bericht ist bereit")

        # Der Workflow setzt hier fort
        log_result = await log_notification(recipient, email_result)
        return log_result

Fehlertoleranz: Abgedeckte Szenarien

Die Plattform behandelt vier Arten von Vorfällen, ohne dass Sie eine einzige Zeile Code schreiben müssen. Erstens, ein Worker-Absturz: Der Python-Prozess stoppt abrupt aufgrund eines Speicherfehlers, eines kill-Signals oder eines Server-Neustarts. Ein anderer Worker übernimmt den Workflow exakt dort, wo er stehen geblieben ist. Zweitens, ein vorübergehender Netzwerkfehler: Ein API-Aufruf schlägt fehl aufgrund eines Timeouts. Die Retry-Richtlinie startet die Aktivität automatisch neu mit exponentiellem Backoff, wobei die Verzögerungen zunehmen, um eine überlastete Dienstleistung nicht zu überlasten.

Drittens, Fehler in Ihrem eigenen Code: Eine in einer Aktivität ausgelöste Ausnahme wird eine definierte Anzahl von Malen basierend auf der konfigurierten Richtlinie neu versucht, bevor sie endgültig fehlschlägt. Viertens, vorübergehende Unverfügbarkeit eines Drittanbieterdienstes. Die Wirkung ist hier dramatisch: Wenn eine Partner-API für zehn Minuten ausfällt, schlägt Ihre nächtliche Pipeline nicht mehr fehl. Ausstehende Aktivitäten starten neu, sobald der Dienst verfügbar ist, und die Verarbeitung endet lediglich zehn Minuten später.

Die Determinismus-Einschränkung

Wiederspielen hat einen Preis. Damit das Log-Wiederspiel die ursprüngliche Ausführung treu reproduziert, muss der Workflow-Code (nicht die Aktivitäten) deterministisch sein. Bei gleichen Eingaben muss er die gleiche Sequenz von Operationen erzeugen. Wenn Ihr Workflow basierend auf if datetime.now().hour < 12 verzweigt, könnte ein Wiederspiel heute Abend den anderen Zweig nehmen und das Log vollständig desynchronisieren.

Deshalb dürfen Sie in Workflow-Code niemals Folgendes tun:

  • datetime.now() verwenden → verwenden Sie workflow.now()
  • uuid.uuid4() verwenden → verwenden Sie workflow.uuid4()
  • random.random() verwenden → verwenden Sie workflow.random()
  • Netzwerk- oder I/O-Aufrufe direkt durchführen → verschieben Sie sie in eine Aktivität

Diese drei Substitutionen geben Werte zurück, die während des ersten Durchlaufs protokolliert und danach identisch wiederspielen werden. Wir werden diese Einschränkung in Lektion 8, die sich auf Determinismus konzentriert, detailliert erläutern.

Vergleich mit traditionellen Ansätzen

AnsatzWiederherstellung nach FehlerAusführungsgarantieKomplexität
Einfaches Python-SkriptNeinKeineNiedrig
Nachrichtenwarteschlange (Celery, RQ)TeilweiseMindestens einmalMittel
Cron + DatenbankManuellAbhängig von der ImplementierungHoch
Mistral Workflows (Temporal)AutomatischGenau einmal (logisch)Niedrig (SDK)

Achten Sie besonders auf die Spalte Komplexität. Eine Nachrichtenwarteschlange scheint am Anfang einfach, aber ihre teilweise Wiederherstellung zwingt Sie dazu, Zustandsmanagement-Logik zu schreiben, die das SDK von Haus aus bereitstellt.

Genau einmal: Eine logische Garantie

Die Plattform garantiert, dass Ihre Workflow-Logik genau einmal ausgeführt wird. Wenn eine Aktivität erfolgreich ist, protokolliert das System das Ergebnis und führt sie nie erneut aus. Wenn sie fehlschlägt, versucht das System sie gemäß der konfigurierten Richtlinie erneut.

Das Wort „logisch” ist keine Dekoration. Auf Netzwerkebene könnte ein Aufruf tatsächlich zweimal gesendet werden: Ihre Anfrage zur Erstellung eines Kunden erreicht das CRM, aber die Bestätigung geht im Transit verloren. Aus Ihrer Perspektive ist die Aktivität fehlgeschlagen und wird erneut versucht, obwohl der Kunde bereits existiert. Dies erzeugt die Notwendigkeit für idempotente Aktivitäten, die auch bei mehrmaligem Aufruf mit denselben Parametern das gleiche Ergebnis erzeugen. In der Praxis bedeutet dies, dass Sie einen PUT auf einer stabilen ID bevorzugen sollten, anstatt einen POST, der bei jedem Aufruf eine neue Zeile erstellt.

Kernaussagen

  • Event Sourcing protokolliert jeden Schritt als unveränderliches Ereignis in einem Log
  • Automatisches Wiederspielen ermöglicht es Ihnen, einen unterbrochenen Workflow fortzusetzen, ohne ausgeführte Aktivitäten erneut auszuführen
  • Die Plattform behandelt Abstürze, Netzwerkfehler und Dienstausfälle automatisch
  • Workflow-Code muss deterministisch sein, damit Wiederspielen funktioniert
  • Aktivitäten müssen idempotent sein, um Konsistenz während von Retries zu gewährleisten
  • Die Ausführungsgarantie ist logisch genau einmal