KI-Agenten & Zuverlässigkeit

Der Agent sagt „Fertig“. Ist sein Zustand gespeichert?

Ein abgeschlossener Lauf und ein wiederherstellbarer Zustand sind zwei verschiedene Zusagen. Ein gezielt gestörter Test mit der echten Mecatl-Engine macht die Grenze sichtbar.

Die Frage hinter „cloud-native“

Ein Agent ruft ein Werkzeug auf. Das Werkzeug meldet Erfolg, das Modell beendet seine Antwort, und der Client kann „Fertig“ anzeigen. Welche dieser Informationen überlebt einen Prozesswechsel? Diese Frage entscheidet darüber, ob ein erneuter Versuch sinnvoll, redundant oder gefährlich ist.

Ausgangspunkt war Craig McLuckies Beitrag über cloud-native Agent Harnesses. Mecatl trennt die Agenten-Schleife von Clients, Ausführungsumgebungen und Speicherung. Der Beitrag beschreibt ausdrücklich die Wiederherstellung an gespeicherten Rundengrenzen und verspricht keine Transaktion über bereits laufende externe Aktionen. Das Experiment prüft eine engere Frage: Was meldet die Engine, wenn das Speichern selbst scheitert?

Untersucht wurde Commit 9edd9b751f22c4deb5f5d0b03308e77ff06ba5d2 vom 2. Oktober 2026. Die Ergebnisse gelten für diese Version und die unten beschriebene Engine-Konfiguration, nicht automatisch für jede Mecatl-Installation.

Erfolg trotz fehlgeschlagener Speicherung

Die Methode Engine.save() behandelt normale Snapshot-Schreibvorgänge als best effort. Bei einem Fehler schreibt sie einmal pro Lauf eine korrelierte Warnung. Sie gibt den Fehler nicht an den Aufrufer zurück. Im normalen Abschlusspfad ruft terminateComplete() diese Methode auf und kann anschließend weiterhin ein erfolgreiches Ergebnis ausgeben.

Das ist durch einen bestehenden Test ausdrücklich abgesichert: TestSaveFailureEmitsOneCorrelatedWarn injiziert einen immer fehlschlagenden Store und verlangt trotzdem StopEndTurn. „Erfolg“ bedeutet hier, dass die Engine die Modellrunde normal abgeschlossen hat. Es ist keine Bestätigung einer dauerhaft gespeicherten Geschäftstransaktion.

Nicht jeder Schreibpfad hat diese Semantik. Die Engine besitzt auch saveRequired() für bestimmte Übergänge. Der Befund ist daher nicht „Mecatl ignoriert alle Speicherfehler“, sondern eine konkrete Eigenschaft des normalen Snapshot- und Abschlusspfads.

Was im Experiment tatsächlich passiert

Der Test speichert zunächst eine leere, inaktive Session in Mecatls In-Memory-Store. Ein Wrapper lässt das Laden zu, weist danach aber jeden Snapshot-Schreibversuch zurück. Ein deterministischer Modelladapter ruft ein schreibendes Testwerkzeug auf und liefert anschließend „done“. Das Werkzeug erhöht einen Zähler außerhalb des Session-Snapshots.

Beim ersten Lauf steigt der Zähler auf 1; die Engine meldet end_turn. Danach lädt der Test den alten Snapshot und erzeugt eine neue Engine. Der Snapshot enthält weiterhin null Nachrichten. Der Test reicht die Aufgabe bewusst erneut ein; der geskriptete Modelladapter fordert dieselbe Aktion an, und der Zähler steigt auf 2.

Die Kontrollprobe verwendet einen funktionierenden Store. Nach einem Lauf lässt sich der Zustand completed mit vier Nachrichten laden; der Zähler steht auf 1. Diese Probe wiederholt die Aufgabe nicht. Sie bestätigt die erfolgreiche Speicherung und behauptet nicht, dass die Engine bei einem weiteren Prompt automatisch jede doppelte Aktion verhindern würde.

Sechs bestehende Tests und beide zusätzlichen Experimenttests bestanden mit Go 1.27.1. Die zusätzliche Datei wird über ein Go-Overlay eingebunden; produktiver Quellcode bleibt unverändert. Die vollständigen Befehle und beobachteten Ergebnisse stehen im Download.

Drei Grenzen der Aussage

Erstens: Der Test verwendet die echte Engine, aber ein simuliertes Modell, einen In-Memory-Store und einen Zähler als Stellvertreter eines externen Dienstes. Er tötet keinen Prozess und startet keinen Pod neu. Er untersucht weder Redis noch den vollständigen HTTP/gRPC-Server oder dessen separates Event-Log.

Zweitens: Die Wiederholung wird vom Test angefordert. Der Befund zeigt eine mögliche doppelte Wirkung bei bewusstem Retry aus altem Zustand. Er zeigt weder einen automatischen Retry von Mecatl noch eine Vorhersage darüber, was ein echtes Sprachmodell entscheiden würde.

Drittens: Eine reparierte Unterhaltung ist noch keine geklärte externe Wirkung. Session.Abandon() ergänzt für bestimmte unbeantwortete Werkzeugaufrufe synthetische Fehlerantworten, damit die Historie wieder gültige Aufruf-Antwort-Paare enthält. Es fragt dabei keinen externen Dienst nach dem tatsächlichen Ergebnis. Wenn der alte Snapshot den Aufruf gar nicht enthält, kann diese Reparatur ihn auch nicht rekonstruieren.

Die Betriebsentscheidung explizit machen

Für eine rein lesende Recherche kann Weiterarbeiten trotz eines Speicherfehlers sinnvoll sein, solange die eingeschränkte Wiederherstellbarkeit sichtbar bleibt. Für einen Agenten, der Infrastruktur verändert, würde ich die Freigabe weiterer Mutationen an eine klar definierte Speicher- und Ausführungsrichtlinie binden. Ein allgemeines „Done“ darf diese Zustände nicht zusammenfassen.

Dabei hilft es, drei Fakten getrennt zu erfassen: Ergebnis des Agentenlaufs, Bestätigung der Zustandsspeicherung und Ergebnis der externen Aktion. Letzteres kann unbekannt sein. Ein Timeout oder ein fehlender Snapshot bedeutet nicht, dass die Aktion nicht ausgeführt wurde.

Wo die Ziel-API Idempotenzschlüssel unterstützt, muss dieselbe logische Aktion bei Wiederholungen denselben stabilen Schlüssel nutzen. Wo sie das nicht tut, braucht es eine dienstspezifische Abfrage und Abgleichlogik oder eine menschliche Klärung. „Erst prüfen, dann erstellen“ allein schützt nicht vor konkurrierenden Aufrufen. Auch das Stoppen nach einem Speicherfehler macht eine bereits ausgeführte Aktion nicht rückgängig.

Was ich vor produktiven Schreibrechten prüfen würde

Dieser Test ist ein Einstieg in eine größere Prüfung. Für die tatsächlich eingesetzte Kombination aus Server, Store und Werkzeugen würde ich Snapshot- und Event-Log-Schreibfehler getrennt injizieren, anschließend aus einem neuen Prozess laden und die externen Wirkungen unabhängig zählen. Danach würde ich einen Abbruch zwischen externer Bestätigung und lokaler Speicherung sowie zwei konkurrierende Wiederholungen prüfen. Diese Tests sind hier nicht durchgeführt worden.

Mecatl dokumentiert Wiederherstellungsgrenzen und macht diese Entscheidung im Code sichtbar. Der nützliche Befund ist keine pauschale Produktbewertung: Ein erfolgreiches Agentenergebnis allein reicht nicht als Freigabe für einen sicheren Retry. Die Anwendung muss wissen, welche Wirkung sie bestätigt hat und welche Frage noch offen ist.

Den Speicherausfall reproduzieren

Reproduzierbares Lernbeispiel mit synthetischen Daten. Kein Bericht über ein Arbeitgeber- oder Kundenprojekt.

Der Download enthält die beiden zusätzlichen Tests, ein Skript für den festgelegten Commit und die beobachtete Ausgabe. Er führt Tests in Mecatls echter Engine aus, nicht in einer nachgebauten Python-Schleife.

Lokal ausführen

Voraussetzungen: Go 1.27.1 (getestet), Git, Python 3 und eine POSIX-Shell. Das ZIP in ein leeres Arbeitsverzeichnis entpacken. Das Skript lädt Repository und Go-Abhängigkeiten; die Tests selbst benötigen weder Modell-API noch Zugangsdaten. Ein vorhandenes Verzeichnis mecatl wird nicht überschrieben.

Experiment herunterladen · mecatl-snapshot-lab.zip

sh reproduce.sh

Ausgabe des Beispiels

attempt=1 restored_state=idle restored_messages=0
attempt=1 result=end_turn external_effect_count=1
attempt=2 restored_state=idle restored_messages=0
attempt=2 result=end_turn external_effect_count=2
healthy_store: restored_state=completed restored_messages=4 external_effect_count=1

Oben stehen die Logzeilen des Experiments ohne Go-Testpräfixe. Beide Tests bestanden. Der Zähler überlebt die neu erzeugte Engine, ist aber kein echter externer Dienst. Der geskriptete Modelladapter und die bewusst erneut eingereichte Aufgabe machen das Ergebnis deterministisch.

Den Fehler am richtigen Übergang sichtbar machen

Für einen produktiven Dienst würde ich Speicherzustand und Aufgabenergebnis getrennt anzeigen und korrelieren. Eine Speicherwarnung braucht eine konkrete Reaktion: weitere Mutationen anhalten, Wiederherstellung prüfen oder einen Betreiber einbeziehen. Welche Reaktion richtig ist, hängt von der Wirkung des Werkzeugs ab.

Engine-Test mit injiziertem Speicherausfall. Keine Aussage über die Häufigkeit in Produktion, automatische Wiederholungen, reale Modellentscheidungen oder die vollständige mecak8s-Deployment-Kette.

Technische Referenzen

Alle technischen Notizen

Eine Frage zu
meiner Arbeit?

Ich freue mich über fachlichen Austausch und berufliche Kontakte.

Kontakt aufnehmen