von Sam Ingbar
Ein Agent für die Prüfung von Privatkrediten sammelt Nachweise, wendet Richtlinien an und muss unter Umständen tagelang auf einen Prüfer warten. In dieser Zeit können Worker neu starten und Tool-Aufrufe fehlschlagen. Die Anwendung muss abgeschlossene Arbeiten sichern, die Ausführung fortsetzen und die Nachweise für den Prüfer bereithalten.
Diese Referenzimplementierung nutzt Temporal für eine dauerhafte Ausführung und Lakebase Postgres für einen abfragbaren Betriebsstatus. Eine synchronisierte Tabelle stellt die Kreditprüfungsrichtlinien aus dem Unity Catalog in Lakebase bereit. Temporal Activities schreiben Nachweise, Entscheidungen und Metriken in Lakebase. Sobald dies aktiviert ist, kann der Lakebase Change Data Feed diese Änderungen in von Unity Catalog verwalteten Delta-Verlaufstabellen veröffentlichen. Diese Kombination ist besonders nützlich, wenn Databricks bereits die Eingaben des Agenten und die nachgelagerte Analyse verwaltet.
Ein Cloud-Agent kann die Anfrage, den Worker, den Container oder das Deployment überleben, das ihn gestartet hat. Ein Benutzer kann eine Sitzung beginnen, am nächsten Tag zurückkehren und auf einem anderen Worker fortfahren. Deployments und Prozessfehler gehören zum Alltag, daher muss der Fortschritt des Agenten unabhängig von dem Prozess, der ihn ausführt, erhalten bleiben. Die Wiederherstellung erfordert sowohl die Ergebnisse abgeschlossener Operationen als auch den Kontrollflussstatus, der bestimmt, was als Nächstes passiert.
Für diesen Kreditprüfungs-Agenten ergeben sich daraus sechs Anforderungen:
Ein Gesprächsprotokoll deckt nur einen Teil dieses Status ab. Die Wiederherstellung erfordert auch den Kontrollflussverlauf: welche Operationen geplant waren, welche Ergebnisse aufgezeichnet wurden, worauf der Agent wartet und welche Befehle er akzeptiert hat.
Temporal vereinfacht die Verwaltung verteilter Systeme. Bei der Entwicklung mit Temporal ist ein Workflow der dauerhafte Kontrollfluss für einen Agenten-Durchlauf. Eine Activity ist ein Aufruf eines Modells, Tools oder einer Datenbank, dessen Ergebnis in der Event History des Workflows aufgezeichnet wird; Activities können wiederholt werden. Ein Signal ist ein asynchroner Befehl, der an einen laufenden Workflow gesendet wird, wie z. B. die Entscheidung eines Kreditprüfers. Die Referenzimplementierung des Temporal Lakebase AgentWorkflow ist ein ausführbarer Agent für die Prüfung von Privatkrediten. Er ruft mehrere Tools auf, liest gesteuerte Richtlinien, erstellt eine Empfehlung und wartet auf einen Kreditprüfer.
Lakebase Postgres hilft Entwicklern ebenfalls bei der Bewältigung dieser Probleme, aber Temporal und Lakebase speichern unterschiedliche Zustände für verschiedene Empfänger. Die Event History von Temporal steuert das Replay. Lakebase speichert die anwendungsseitige Ansicht: aktuellen Durchlaufstatus, Nachrichten, Nachweise, Prüfungsstatus und Metriken. Unity Catalog bleibt die Richtlinienquelle; eine synchronisierte Tabelle macht diese Richtlinie in Postgres abfragbar, und der Change Data Feed stellt den Rückpfad für den Betriebsverlauf bereit. Die Systeme teilen sich keine Transaktion. Lakebase-Schreibvorgänge werden als Temporal Activities mit At-Least-Once-Ausführung ausgeführt. Deterministische Identifikatoren, Constraints, geschützte Updates und Postgres-Upserts stellen sicher, dass wiederholte Activity-Versuche auf denselben logischen Datensatz abzielen.
Diese Architektur fügt zwei verwaltete Systeme und einen Projektionsvertrag zwischen ihnen hinzu. Zusammen verbessern sie die Resilienz und Skalierbarkeit des Agenten, während der betriebliche Aufwand gering bleibt. Temporal plus Lakebase ist am nützlichsten, wenn eine Agenten-Sitzung den Austausch von Workern überstehen, Eingaben nach langen Wartezeiten akzeptieren, einer Anwendung einen relationalen Status bereitstellen und gesteuerte Daten anwenden muss, während sie geöffnet bleibt.
Ich habe mich für die Kreditprüfung entschieden, weil derselbe Durchlauf Nachweise sammeln, Richtlinien anwenden, eine Empfehlung aussprechen und auf eine Person warten muss. Ein Worker kann zwischen jedem dieser Schritte ausfallen. Richtlinien können sich ohne ein Anwendungs-Deployment ändern, und die UI benötigt die aktuellen Nachweise, bevor der Workflow geschlossen wird.
Simulierte Antragsteller ersetzen echte Auskunfteien und Einkommensnachweise, und die Tool-Abfolge ist aus Gründen der Einfachheit deterministisch. Jede Anfrage enthält eine Benutzer-ID, eine Antragsteller-ID, den Betrag, den Zweck, die Modellauswahl und ein Rundenlimit. FastAPI weist run_id zu, startet LoanUnderwritingWorkflow und verwendet dieselbe ID über die API, die Temporal-Ausführung und die Lakebase-Zeilen hinweg.
In der ersten Runde gibt credit_check Score, Kreditlinien, Zahlungsverzüge und aktuelle Schulden zurück. income_verification liefert Einkommens- und Beschäftigungsnachweise. debt_to_income_calc berechnet das Verhältnis von Schulden zu Einkommen. policy_lookup lädt die Richtlinie für den Kreditzweck und bewertet die Nachweise anhand von Schwellenwerten für Genehmigung, Weiterleitung und strikte Ablehnung.
Der Grenzwert-Antragsteller im Beispiel hat einen Kredit-Score von 665, ein verifiziertes Jahreseinkommen von 76.000 $, monatliche Schulden von 2.400 $ und einen unwesentlichen Zahlungsverzugs-Flag. Das Richtlinienergebnis protokolliert jede Regel, jeden Schwellenwert, Ist-Wert, jedes Pass/Fail-Ergebnis, jede Quelle, Empfehlung und Begründung. Das Modell kann Empfehlungen aussprechen, aber keine Entscheidungen treffen. Ein Kreditprüfer genehmigt, lehnt ab oder fordert weitere Informationen an. Eine Anforderung weiterer Informationen wird zu einer weiteren Benutzernachricht und einer weiteren Agenten-Runde. Der Fall simuliert einen Worker-Absturz nach abgeschlossenen Tool-Aufrufen, einen geschriebenen Lakebase-Schreibvorgang, dessen Activity-Abschluss verloren ging, eine tagelang offene Prüfung, eine veraltete Browser-Entscheidung und eine Richtlinienänderung während der Ausführung.
Zur Implementierung des Kreditprüfungs-Agenten übernehmen React und FastAPI die HTTP- und UI-Arbeit: Starten von Durchläufen, Rendern von Nachweisen, Auflisten von Fällen und Übermitteln von Prüfungsentscheidungen. Temporal Cloud speichert die Event History und verteilt Tasks. Worker spielen Workflow-Code ab und führen Modell-, Tool- und Lakebase-Activities aus; Netzwerk- und Datenbank-I/O bleiben außerhalb des deterministischen Workflow-Codes.
Ein Durchlauf beginnt, wenn FastAPI einen Workflow startet. Der Worker plant Activities, Temporal zeichnet deren Ergebnisse auf, und der Agent erreicht schließlich AWAITING_REVIEW. Die Antwort des Kreditprüfers wird über ein Signal zurückgegeben. Eine Genehmigung oder Ablehnung schließt den Durchlauf ab; eine Anforderung weiterer Informationen setzt die Agenten-Schleife fort.
Lakebase enthält zwei Betriebsschemata. agent_ops enthält den Durchlaufstatus, Nachrichten, Tool-Aufrufe, Prüfungsdatensätze, Ereignisse und Metriken, die FastAPI mit SQL abfragen kann. agent_policy enthält die schreibgeschützte synchronisierte Richtlinie, die von policy_lookup verwendet wird. Jede Activity schreibt Datensätze, die mit denselben deterministischen Identifikatoren versehen sind, die auch vom Workflow verwendet werden, sodass die Projektion nach einem Wiederholungsversuch aufholen kann, ohne Lakebase zu einem Teil des Replay-Mechanismus von Temporal zu machen.
Unity Catalog ist die Quelle für die Schwellenwerte der Kreditprüfung. Eine kontinuierlich synchronisierte Tabelle stellt sie dem laufenden Agenten zur Verfügung. Die angewendeten Schwellenwerte, Nachweise und die anschließende menschliche Entscheidung werden in agent_ops geschrieben. Der Change Data Feed kann diese Änderungen in von Unity Catalog verwalteten Verlaufstabellen für Audits und Analysen veröffentlichen.
Temporal bewahrt die geordnete Event History auf, die erforderlich ist, um den Workflow-Status auf einem anderen Worker wiederherzustellen. Dieser Verlauf umfasst die Activity-Planung und -Ergebnisse, Timer und Signals. Das Replay führt den Workflow-Code für diese aufgezeichneten Events aus und rekonstruiert Variablen wie die aktuelle Runde, akzeptierte Prüfungsentscheidungen, Token-Nutzung und gesammelte Nachweise.
Ein aufgezeichnetes Activity-Ergebnis wird während des Replays zurückgegeben, anstatt die Activity erneut auszuführen. Eine abgeschlossene Kreditprüfung bleibt abgeschlossen, und eine aufgezeichnete Modellantwort bleibt die Antwort für diese Ausführung. Wenn eine Activity aktiv war, als der Worker ausfiel, und Temporal deren Abschluss nie aufgezeichnet hat, Temporal einen weiteren Versuch planen kann. Für einen Agenten bleiben so die bereits in der Event History aufgezeichneten Modellantworten erhalten. Ein Modellaufruf, dessen Abschluss nicht aufgezeichnet wurde, wird unter Umständen erneut ausgeführt, selbst wenn der Anbieter die Verarbeitung bereits abgeschlossen hat.
Retry-Richtlinien werden auf der Ebene einzelner Operationen zugewiesen und können im Code wiederverwendet werden. Im Beispiel erlauben modellaufrufende Activities bis zu vier Versuche innerhalb eines dreiminütigen Schedule-to-Close-Timeouts. Die Tool-aufrufenden Activities erlauben bis zu drei Versuche und haben ein Start-to-Close-Timeout von 60 Sekunden. Die Lakebase-Activities erlauben bis zu fünf Versuche mit einem Start-to-Close-Timeout von 15 Sekunden.
Ein Risiko besteht darin, dass ein Schreibvorgang für ein Lakebase-Tool-Ergebnis festgeschrieben (committed) werden kann, bevor der Worker den Abschluss der Activity meldet. Wenn die Verbindung in dieser Lücke abbricht, hat Temporal kein aufgezeichnetes Ergebnis und plant einen weiteren Versuch. Beide Versuche stellen denselben logischen Schreibvorgang dar.
Jeder Lakebase-Datensatz hat eine stabile Identität. run_id verankert das Betriebsschema. message_id identifiziert eine Nachricht, tool_call_id einen Tool-Aufruf, event_id einen Meilenstein, review_id eine Überprüfungsrunde und decision_id einen Prüferbefehl. Postgres-Primärschlüssel und Unique Constraints erzwingen diese Identitäten.
Der Schreibvorgang beim Tool-Start zeigt sowohl die stabile Identität als auch den Terminal-State-Guard:
Ein Wiederholungsversuch zielt auf dasselbe tool_call_id ab. Das finale Prädikat erlaubt es nur, eine vorhandene nicht-terminale Zeile wieder auf „gestartet“ zurückzuschreiben. Wenn die Zeile bereits erfolgreich war oder fehlgeschlagen ist, betrifft PostgreSQL null Zeilen. Es wird kein Fehler ausgelöst.
Der Aufrufer muss ein Ergebnis von null Zeilen prüfen. LakebaseWriteResult gibt die Anzahl der betroffenen Zeilen zurück, aber der aktuelle Activity-Wrapper wertet null nicht als Fehler. Produktivcode sollte null erst dann als erwartetes No-Op klassifizieren, wenn der gespeicherte Terminal-Zustand bestätigt wurde; andernfalls sollte er einen Konflikt auslösen oder protokollieren. Dieselbe Regel gilt für geschützte Run- und Review-Übergänge.
Ähnliche Upserts decken Nachrichten, Tool-Ergebnisse und Events ab. Deterministische IDs sorgen dafür, dass Wiederholungsversuche auf dieselbe logische Zeile konvergieren, während jeder geschützte Schreibvorgang definiert, welche Zustandsübergänge zulässig sind. Die API kann kurzzeitig einen älteren Zustand anzeigen, während ein Schreibvorgang wiederholt wird. Nach erfolgreichem Abschluss der Activity ist die akzeptierte Zeile abfragbar.
Jedes Tool mit Seiteneffekten benötigt einen entsprechenden Vertrag. Eine Zahlungs-API akzeptiert möglicherweise einen Idempotenzschlüssel, ein E-Mail-Dienst eine vom Aufrufer bereitgestellte Nachrichten-ID und eine Datenbank einen Unique Constraint. Wenn das externe System keinen Deduplizierungsmechanismus bietet, benötigt die Activity einen eigenen Datensatz oder einen Abstimmungsprozess. Temporal bestimmt, wann ein Wiederholungsversuch stattfindet. Die Activity bestimmt, wie das externe System diesen Wiederholungsversuch handhabt.
Die Event History liefert Ausführungssemantik und Debugging-Details. Die Anwendung benötigt indizierte relationale Abfragen über den aktuellen Run: Auflisten von Fällen nach Benutzer und Status, Laden eines Transkripts mit seinen Nachweisen, Finden von Überprüfungen, die auf eine Person warten, und Aggregieren von Messungen über Ausführungen hinweg.
Lakebase speichert diese Anwendungsansicht in einem normalisierten Postgres-Schema. agent_runs enthält den aktuellen Status, die Workflow-ID, die Anfrage, Token-Gesamtzahlen, Zeitstempel und Empfehlungs-Metadaten. agent_messages bewahrt das Transkript. agent_tool_calls zeichnet Argumente, Status, strukturiertes Ergebnis, Fehler und Timing auf. agent_review_decisions verbindet die Empfehlung mit einer stabilen Review-ID, einem Prüferbefehl, einer Begründung und der Entscheidungszeit.
Das Schema zeichnet auch benannte Events und Metriken auf Workflow-, Turn- und Activity-Versuchsebene auf. FastAPI stellt die Endpunkte run-detail, workflow-metrics und retry-metrics bereit, die von diesen Tabellen gestützt werden. Die UI kann einen Run anzeigen, der Nachweise sammelt, einen anderen, der auf eine Überprüfung wartet, und einen dritten, der ein fehlgeschlagenes Tool erneut versucht. Operatoren können dieselben Zeilen mit SQL abfragen.
Nachweise sind verfügbar, bevor der Workflow abgeschlossen ist. Nach Abschluss von policy_lookup wird das strukturierte Ergebnis mit dem Tool-Aufruf gespeichert. Wenn der Run AWAITING_REVIEW erreicht, kann der Underwriter die Kreditwürdigkeit, DTI, Schwellenwerte, Regelergebnisse, die Begründung und die Richtlinienquelle sehen, die die Empfehlung generiert haben.
Wenn das Modell eine Empfehlung zurückgibt, leitet der Workflow review_id aus run_id und dem aktuellen Turn ab. Er schreibt die ausstehende Überprüfung in Lakebase, zeichnet ein agent.review_pending-Event auf, setzt die Projektion auf AWAITING_REVIEW und ruft workflow.wait_condition auf. Temporal behält den offenen Workflow bei, ohne einen Worker-Prozess zu belegen.
Die API sendet die Aktion des Underwriters als Signal. Vor dem Senden prüft die API, ob Lakebase anzeigt, dass der Run auf eine Überprüfung wartet, und ob die übermittelte review_id mit der aktuellen Runde übereinstimmt. Wenn eine der Prüfungen fehlschlägt, gibt die API einen Konflikt zurück. Der Workflow validiert den Befehl unabhängig anhand seines eigenen Zustands und ignoriert veraltete oder doppelte Entscheidungen, wodurch die Ausführung geschützt wird, selbst wenn die Lakebase-Projektion hinterherhinkt.
Nach dem Akzeptieren des Signals speichert der Workflow die Entscheidung über eine idempotente Lakebase-Activity dauerhaft. Genehmigung oder Ablehnung schließen den Run ab. Eine Anfrage nach weiteren Informationen ändert die Projektion zurück auf RUNNING, fügt die Begründung des Prüfers als Benutzernachricht hinzu und startet den nächsten Turn. Da sich der Turn geändert hat, erhält die nächste Empfehlung ein neues review_id.
Die 202-Antwort der API bestätigt, dass Temporal das Signal empfangen hat. Die geschäftliche Akzeptanz erfolgt asynchron im Workflow, sodass ein Befehl die API-Vorabprüfung bestehen und dennoch ignoriert werden kann, wenn sich der Überprüfungszustand geändert hat. Der Client aktualisiert die Lakebase-Projektion, um den resultierenden Zustand zu beobachten.
Underwriting-Schwellenwerte ändern sich unabhängig vom Worker-Code. Die Quelltabelle in Unity Catalog enthält zweckspezifische Werte wie die Mindestkreditwürdigkeit, DTI für automatische Genehmigung, Schwellenwerte für harte Ablehnungen und den Richtliniennamen.
Das Setup-Skript erstellt eine kontinuierliche, mit Lakebase synchronisierte Tabelle namens agent_policy.underwriting_policy_limits. policy_lookup, die diese schreibgeschützte Postgres-Kopie nach normalisiertem Darlehenszweck abfragt. Richtlinieninhaber aktualisieren die Unity Catalog-Quelle; die Synchronisierungspipeline propagiert die Änderung, und ein späterer Run liest sie ohne eine Worker- oder API-Bereitstellung.
Das Richtlinienergebnis enthält die angewendeten Schwellenwerte, den tatsächlichen Wert jeder Regel und das Pass/Fail-Ergebnis sowie die Quelle. Die Demo kann auf eine Standardrichtlinie (Fixture Policy) zurückgreifen, wenn Lakebase deaktiviert oder die Zeile nicht verfügbar ist, und zeichnet diesen Pfad als fixture_fallback auf. Ein regulierter Workflow schlägt stattdessen möglicherweise fehl (Fail-Closed). Die Anwendung muss diese Fallback-Entscheidung explizit treffen.
Das Repository bereitet jede agent_ops-Tabelle für den Lakebase Change Data Feed vor, indem REPLICA IDENTITY FULL festgelegt wird. Ein Administrator muss die Funktion noch für das Schema aktivieren. Lakebase erfasst dann Inserts, Updates und Deletes aus dem Postgres-Write-Ahead-Log und schreibt sie in Batches in von Unity Catalog verwaltete Delta-Verlaufstabellen, die nach dem Muster lb_<table>_history benannt sind.
Der Change Data Feed befindet sich derzeit in der Public Preview und schreibt Änderungen etwa alle 15 Sekunden. Dieses Intervall eignet sich für Audits und Analysen, während die UI Lakebase direkt für den aktuellen Betriebszustand abfragt.
Die Verlaufstabellen können die Richtlinienquelle eines Runs, Tool-Nachweise, Activity-Versuche, das Warten auf Überprüfungen, die Empfehlung und die menschliche Entscheidung rekonstruieren. Das Repository konfiguriert das Quellschema für diesen Pfad, enthält jedoch keinen beobachteten End-to-End-Lauf des Change Data Feeds. Das Aktivieren des Feeds und das Überprüfen der Zieltabellen bleiben Bereitstellungsschritte.
Die Bereitstellung trennt React/FastAPI vom Temporal-Worker. API-Replikate skalieren mit der Anfragelast; Worker skalieren mit dem Workflow- und Activity-Task-Backlog sowie der konfigurierten Concurrency. Die automatische Skalierung von Lakebase passt die Datenbank-Rechenleistung innerhalb der Projektgrenzen an.
Die Preise für die Temporal Cloud basieren auf Actions sowie dem aktiven und aufbewahrten Event-History-Speicher, sodass sich auch die Häufigkeit von Wiederholungsversuchen und lange offene Verläufe auf die Kosten auswirken. Das Team legt weiterhin Kubernetes-Replikate, Task Queues, Limits für den Connection-Pool und Datenbankgrenzen für seine Workload fest. Alternativ können Sie Ihren eigenen Open-Source-Temporal-Service unter Verwendung des neuesten Open-Source-Releases einrichten.
Der Lakebase-Client verwendet eine OAuth-Maschine-zu-Maschine-Authentifizierung. Databricks-OAuth-Tokens und generierte Datenbank-Anmeldeinformationen laufen ab, daher aktualisiert der Client seinen SQLAlchemy-Verbindungspool, bevor die einstündigen Datenbank-Anmeldeinformationen ablaufen. Verbindungen verwenden TLS. Ohne Rotation würde ein lang laufender Worker nach einem vorhersehbaren Zeitplan auf Datenbankfehler stoßen.
Operatoren verwenden Temporal, um den Workflow- und Activity-Verlauf zu untersuchen, Lakebase, um den Anwendungszustand und Metriken abzufragen, und Kubernetes, um den Zustand von Prozessen und Bereitstellungen zu überprüfen. Ein Operator kann dann ein bewusstes Warten auf eine Überprüfung von einem Activity-Wiederholungsversuch, einem Datenbankzugriffsfehler oder einem fehlgeschlagenen Tool unterscheiden.
Die Testsuite enthält 21 erfolgreiche Tests für Workflow-Sequenzierung, Review-Verhalten, Aufbau von OAuth-Verbindungen, idempotente Persistenz, Metrik-Verträge, API-Workflow-Start und Worker-Einstellungen. Das Crash-Recovery-Skript fügt eine Prozessausfall-Übung mit dem deterministischen Provider hinzu.
Bewerber- und Provider-Daten sind Fixtures. Das Repository validiert keine Kreditvergabemodelle, regulatorische Compliance, Sicherheitskontrollen für die Produktion, regionale Verfügbarkeit oder Performance im großen Maßstab. Die lokale Crash-Übung wurde mit deaktiviertem Lakebase ausgeführt, sodass sie die Temporal-Wiederherstellung isoliert. Change Data Feed erfordert weiterhin die Aktivierung und Verifizierung in der Databricks-Zielumgebung.
Möchten Sie mehr erfahren? Probieren Sie die Demo selbst aus und erleben Sie Durable Execution in Aktion. Führen Sie die Referenzimplementierung aus, stoppen Sie einen Worker mitten im Lauf und sehen Sie zu, wie sich der Agent wiederherstellt. Verbinden Sie Lakebase, um die Nachweise, Richtlinien und den Status der menschlichen Überprüfung hinter jeder Entscheidung zu untersuchen.
(Dieser Blogbeitrag wurde mit KI-gestützten Tools übersetzt.) Originalbeitrag
Abonnieren Sie unseren Blog und erhalten Sie die neuesten Beiträge direkt in Ihren Posteingang.