learn.chetana.fr

Checkpointer Postgres et human-in-the-loop

13 min readAdvanced

Le checkpointer : le state qui survit Ă  tout

Un chat copilot dure des jours ; le process, lui, redémarre (deploys, crashs, autoscaling). Le checkpointer persiste le state du graphe à chaque étape, par thread de conversation :

checkpointer = AsyncPostgresSaver.from_conn_string(DATABASE_URL)
await checkpointer.setup()                      # crée les tables checkpoints*
graph = workflow.compile(checkpointer=checkpointer)

# chaque exécution est rattachée à un thread :
await graph.ainvoke(input, config={"configurable": {"thread_id": thread_id}})

Relance le mĂȘme thread_id aprĂšs un crash : la conversation reprend exactement oĂč elle en Ă©tait — messages, itĂ©rations, tout le state. C'est le passage d'un agent-dĂ©mo Ă  un agent de production : l'Ă©tat ne vit plus dans la RAM d'un process.

interrupt() : l'humain dans la boucle

Pour les actions à effet réel (tools write : créer un devis, modifier une commande), LangGraph offre le pattern HITL :

from langgraph.types import interrupt

def approve_writes(state):
    decision = interrupt({"action": "create_quote", "summary": ...})  # ⏞ le graphe SE FIGE
    ...  # reprend ici quand on ré-invoque avec Command(resume=décision)

interrupt() suspend l'exĂ©cution et persiste tout via le checkpointer : l'utilisateur peut rĂ©pondre dans une heure, depuis un autre pod. Dans le projet, le mĂ©canisme est cĂąblĂ© sur les tools permission == "write" mais actuellement dĂ©sactivĂ© (les confirmations passent par le prompt) — l'infrastructure attend le jour oĂč l'approbation explicite deviendra une exigence.

La leçon d'architecture : le graphe à UN node

DĂ©tail savoureux du rĂ©tro-engineering : le copilot avait un graphe de 13 nodes — il a Ă©tĂ© volontairement rĂ©duit Ă  un seul node agent (START → agent → END) contenant la boucle ReAct du module 4. Pourquoi garder LangGraph alors ? Pour le checkpointer (la persistance de conversation), la compatibilitĂ© du contrat de streaming, et la possibilitĂ© de rĂ©-ajouter un node approve_writes le jour venu.

La morale, applicable partout : la granularité du graphe doit suivre les besoins d'orchestration réels, pas le dessin d'architecture idéal. Le pipeline d'extraction a besoin de 7 nodes (progression, routage, tests) ; la boucle agent n'en a besoin que d'un. Sur-découper, c'est de la complexité gratuite.

đŸ§© Quiz1/4

Que permet le checkpointer AsyncPostgresSaver ?

🃏 Flashcards1/4