LangGraph-Agenten haben nach Wochen des stillen Datenverlusts endlich eine zuverlässige Methode gefunden, ihren Zustand beizubehalten. Nach drei gescheiterten Checkpointing-Versuchen – SQLite, einfachem Object Storage und einer fehlerhaften Version von beidem – entschied sich der Autor für ein Atomic-Update-Muster, das verhindert, dass Agenten bei jeder neuen Anfrage wieder ganz von vorne beginnen müssen.

Warum Checkpointing für LangGraph wichtig ist

LangGraph ermöglicht es Entwicklern, LLM-Aufrufe zu wiederverwendbaren „Agenten“ zusammenzufügen, die sich an den bisherigen Gesprächsverlauf erinnern können. Diese Agenten unterteilen eine Benutzeranfrage in Teilaufgaben, speichern die Zwischenergebnisse und machen beim nächsten Aufruf dort weiter, wo sie aufgehört haben. Wenn der gespeicherte Zustand verloren geht, berechnet der Agent alles neu, was Rechenleistung verschwendet, die Latenz erhöht und zu einer schlechten Benutzererfahrung führt. Bei einem Produktions-Bot, der Telegram-Nachrichten verarbeitet, löschte der Verlust wochenlange Gesprächshistorien.

Die erste Lösung: SQLite saver

Der integrierte SqliteSaver funktioniert einwandfrei, wenn nur eine einzige Instanz den Agenten ausführt. Er schreibt jeden Checkpoint als JSON-Blob in eine lokale SQLite-Datei. Probleme traten auf, als der Entwickler ein neues Feld zum AgentState-Typ hinzufügte und das System neu bereitstellte. Bestehende Checkpoints, die vor der Schemaänderung erstellt wurden, enthielten das neue Feld nicht. Da SqliteSaver niemals eine Migration durchführt, lud LangGraph das unvollständige JSON, verworf die fehlenden Daten, und der Agent startete wieder von vorne.

Kernpunkt: SQLite-Speicherung ist ein Demo-Tool und keine produktionsreife Lösung, wenn eine Schema-Evolution erforderlich ist.

Die zweite Lösung: Object Storage

Um die Kontrolle über das Serialisierungsformat zu gewinnen, schrieb der Autor einen benutzerdefinierten Saver, der den JSON-Checkpoint in den Oracle Cloud Object Storage hochlud. Dieser Schritt bot die Flexibilität, das Schema manuell zu versionieren, führte jedoch zu einem neuen Fehlermodus. Wenn zwei Anfragen gleichzeitig denselben Konversationsverlauf erreichten, versuchten beide, dasselbe Objekt zu überschreiben. Object-Storage-Dienste sind auf „Write-once, Read-many“-Muster optimiert; sie bieten keine atomaren Überschreib-Semantiken. Die Race Condition führte zu fehlerhaften oder abgeschnittenen JSON-Dateien, und der Agent verlor erneut seinen Kontext.

Kernpunkt: Einfaches Überschreiben in Object Storage ist nicht sicher, wenn mehrere Worker gleichzeitig auf denselben Key zugreifen können.

Die dritte Lösung: Atomare Updates mit Versionierung

Das endgültige, stabile Design kombiniert zwei Ideen: explizite Versionsnummern und bedingte Schreibvorgänge (conditional writes) basierend auf dem ETag des Objekts (dem Prüfsummen-Identifikator des Speicher-Dienstes).

  1. Lese den aktuellen Checkpoint und erfasse seinen ETag.
  2. Erhöhe ein Versionsfeld innerhalb des Checkpoint-Envelopes.
  3. Schreibe den aktualisierten Checkpoint mithilfe einer bedingten Anfrage, die nur dann erfolgreich ist, wenn der ETag mit dem zuvor gelesenen übereinstimmt.
  4. Wiederhole die gesamte Read-Increment-Write-Schleife, falls der bedingte Schreibvorgang fehlschlägt, weil ein anderer Prozess das Objekt geändert hat.

Da der Schreibvorgang nur dann erfolgreich ist, wenn kein anderer Prozess die Datei geändert hat, kann immer nur ein Worker einen neuen Zustand committen. Das Versionsfeld erleichtert zudem das Erkennen veralteter Checkpoints und deren Migration bei Schemaänderungen.

Dieses Muster funktioniert mit Object Storage, der ETag-basierte bedingte Schreibvorgänge unterstützt.

Lektionen für KI-Ingenieure

  • Nutzen Sie SQLite nur für Prototypen. Produktionsreife Agenten benötigen einen Speicher, der Schemaänderungen und gleichzeitige Schreibvorgänge verarbeiten kann.
  • Planen Sie Schema-Migrationen selbst. Typed Dictionaries beschreiben Strukturen für die statische Analyse, erzwingen aber keine Laufzeitstruktur.
  • Behandeln Sie den Zustand als gemeinsame Ressource. Concurrency-Bugs äußern sich als stiller Datenverlust; sie sind schwieriger zu debuggen als explizite Exceptions.
  • Nutzen Sie Cloud-Primitives. ETag-basierte bedingte Schreibvorgänge ermöglichen ein kostengünstiges Optimistic Locking ohne einen separaten Lock-Service.
  • Protokollieren Sie jeden Schritt. Stille Fehler – wie ein fehlendes Feld, das LangGraph ignoriert – sind am schwersten aufzuspüren.

Wie geht es mit dem LangGraph-Checkpointing weiter?

Für Teams, die bereits auf dieselben Hindernisse gestoßen sind, bietet das Atomic-Update-Rezept eine schnelle und kostengünstige Lösung. Es zeigt, dass eine zuverlässige Produktions-Pipeline keinen schwerfälligen State-Store benötigt – sondern nur einen sorgfältigen Umgang mit Nebenläufigkeit (Concurrency) und Versionierung.

Fazit: Ein einfacher versionierter Envelope plus bedingte Schreibvorgänge verwandelt ein instabiles System in ein zuverlässiges, sodass sich KI-Ingenieure auf die Agenten-Logik konzentrieren können, anstatt endloses Debugging von Datenverlusten zu betreiben.