Ein Lauf, der einen Nodeausfall überlebt
Durable Execution heißt: Der Fortschritt eines Agenten liegt nicht im Prozessspeicher, sondern in einem append-only Event Log. Fällt der ausführende Node aus, setzt der Lauf auf dem letzten Checkpoint auf — ohne bereits ausgeführte Seiteneffekte zu wiederholen.
Durable Execution persistiert den Fortschritt eines Agenten-Laufs außerhalb des Prozesses. Nach einem Absturz wird der Lauf auf dem letzten Checkpoint fortgesetzt statt neu gestartet. Idempotenz-Keys verhindern, dass Tool-Calls mit Seiteneffekten — Buchungen, Erstattungen, Mails — ein zweites Mal ausgeführt werden.
Warum ein Agent kein normaler Request ist
Ein HTTP-Request dauert Millisekunden. Schlägt er fehl, wiederholt man ihn. Ein Agenten-Lauf dauert Sekunden bis Stunden, ruft dabei fremde Systeme auf und hinterlässt Spuren: eine Gutschrift ist gebucht, eine Mail ist raus, ein Ticket ist geschlossen. Ein naiver Neustart wiederholt diese Seiteneffekte.
Deshalb behandelt die Runtime einen Lauf wie einen Workflow, nicht wie einen Request. Jeder Schritt wird als Ereignis geschrieben, bevor er wirkt. Der Zustand ist keine Variable im Speicher, sondern eine Ableitung aus dem Ereignisstrom.
- Durable Execution
- Ausführungsmodell, bei dem der Fortschritt eines langlaufenden Prozesses persistent außerhalb des ausführenden Prozesses gehalten wird, sodass die Ausführung nach einem Ausfall an der letzten bekannten Stelle fortgesetzt werden kann.
- Checkpoint
- Konsistenter, persistierter Zustand eines Laufs an einer definierten Grenze — in der Regel unmittelbar vor und nach jedem Tool-Call. Ein Checkpoint enthält Schrittzähler, Kontextreferenzen und die Ergebnisse abgeschlossener Aufrufe.
- Idempotenz-Key
- Eindeutiger, aus Lauf-ID und Schrittnummer abgeleiteter Schlüssel, der einem Tool-Call mitgegeben wird. Erhält das Zielsystem denselben Schlüssel zweimal, führt es die Aktion nur einmal aus und liefert beim zweiten Mal dasselbe Ergebnis zurück.
Was bei einem Ausfall tatsächlich passiert
Der folgende Ablauf zeigt einen Lauf, dessen ausführender Node während des dritten Tool-Calls verloren geht.
Schritte, die Sie selbst schreiben
Ein Schritt ist eine gewöhnliche Funktion. Die Runtime umgibt sie mit Persistenz, Retry-Politik und Idempotenz — sichtbar bleibt nur die Deklaration.
import { defineAgent, step } from "@hostspezial/agent-sdk";
export default defineAgent({
name: "refund-agent",
// Harte Obergrenze pro Lauf. Wird sie erreicht, endet der Lauf
// mit status=budget_exceeded — nicht mit einer Endlosschleife.
budget: { tokens: 200_000, eur: 0.50, wallClockMs: 120_000 },
async run(ctx, input) {
// Lesende Schritte sind frei wiederholbar.
const order = await step(ctx, "load-order", () =>
ctx.tools.postgres.query("SELECT * FROM orders WHERE id = $1", [input.orderId])
);
// Schreibende Schritte bekommen einen Idempotenz-Key aus
// Lauf-ID und Schrittnamen. Nach einem Absturz liefert das
// Zielsystem dasselbe Ergebnis statt einer zweiten Buchung.
const refund = await step(ctx, "issue-refund", {
idempotencyKey: `${ctx.runId}:issue-refund`,
retry: { attempts: 3, backoff: "exponential", maxDelayMs: 8_000 },
}, () => ctx.tools.stripe.refund({ orderId: order.id, amount: order.total }));
return { refundId: refund.id, status: "settled" };
},
});
Fehlermodi und das Verhalten der Runtime
Die interessante Frage ist nie, ob etwas ausfällt, sondern was danach passiert.
| Fehlermodus | Verhalten | Sichtbar als |
|---|---|---|
| Tool antwortet mit 5xx | Retry mit exponentiellem Backoff bis zur konfigurierten Obergrenze, danach Eskalation an den definierten Fehlerpfad. | tool.failed → tool.retried |
| Tool antwortet gar nicht | Timeout je Tool, Abbruch des Aufrufs, Checkpoint bleibt auf dem Stand davor. | tool.timeout |
| Node fällt zwischen zwei Schritten aus | Ein anderer Node übernimmt, spielt das Event Log ein und setzt am nächsten Schritt an. | run.resumed |
| Node fällt während eines Schreib-Calls aus | Wiederaufnahme wiederholt den Call mit demselben Idempotenz-Key. Das Zielsystem führt ihn nicht erneut aus. | run.resumed (dedup) |
| Modell liefert unbrauchbare Antwort | Schema-Validierung schlägt an, ein Reparaturversuch mit engerem Prompt, danach Abbruch. | plan.invalid |
| Budget aufgebraucht | Harter Stopp. Der Lauf endet mit budget_exceeded, der bisherige Zustand bleibt einsehbar. | run.budget_exceeded |
| Mensch antwortet nicht auf Freigabe | Lauf bleibt im Wartezustand, ohne Rechenkosten zu erzeugen, bis Freigabe oder Ablauffrist. | run.awaiting_approval |
Was das nicht löst
Exactly-once gilt nur, soweit das Zielsystem mitspielt. Ein Tool ohne Idempotenz-Unterstützung kann die Runtime nicht nachrüsten — sie kann den Aufruf nur als „bereits versucht“ markieren und die Entscheidung an Ihre Fehlerbehandlung geben. Und: Wiederaufnahme reproduziert den Zustand, nicht die Modellantwort. Wer bitgleiche Wiederholbarkeit braucht, arbeitet mit dem deterministischen Replay gegen aufgezeichnete Antworten.
Durable Execution im Detail
Was unterscheidet Durable Execution von einer Retry-Schleife?
Eine Retry-Schleife wiederholt den gesamten Vorgang. Durable Execution wiederholt nur den fehlgeschlagenen Schritt und kennt den Zustand aller vorherigen. Der Unterschied wird bei Seiteneffekten entscheidend: Die Schleife bucht zweimal, die Runtime einmal.
Event-Sourcing oder Snapshotting?
Beides. Jeder Schritt wird als Ereignis geschrieben; zusätzlich wird periodisch ein Snapshot abgelegt, damit die Wiederaufnahme nicht bei langen Läufen tausende Ereignisse einspielen muss. Die Begründung für diese Kombination steht im Architektur-Kapitel.
Wie lange darf ein Lauf dauern?
Bis zu 72 Stunden am Stück — das deckt auch Wartezustände auf menschliche Freigaben ab. Längere Vorhaben wie eine Codebase-Migration werden als Kette geplanter Läufe modelliert, damit jeder Abschnitt einzeln bewertbar bleibt.
Kostet ein wartender Lauf Geld?
Rechenzeit nicht. Ein Lauf im Wartezustand hält keinen Prozess offen, sondern nur einen Datensatz. Abgerechnet werden Schritte, Tool-Calls und Tokens — die Aufteilung steht auf der Preisseite.
Kann ich einen abgebrochenen Lauf manuell fortsetzen?
Ja. Jeder Lauf lässt sich ab einem beliebigen Checkpoint fortsetzen — auch mit geändertem Modell, geänderter Policy oder korrigierten Eingaben. Der neue Zweig wird als eigener Lauf geführt, der ursprüngliche bleibt unverändert im Log.
Was passiert bei einem Rechenzentrums-Ausfall?
Der Zustandsspeicher wird an den DR-Standort repliziert. Laufende Runs werden dort fortgesetzt, sobald die Kontrollebene übernimmt. Verfügbarkeits- und Wiederanlaufziele werden vertraglich je Umgebung vereinbart — Details auf der Trust-Seite.
Weiter in der Plattform
Testen Sie den Fehlerfall, nicht den Glücksfall
In der Sandbox schalten wir einen Node während Ihres Laufs ab. Sie sehen im Trace, wo er wieder aufsetzt — und dass die Buchung nur einmal existiert.