Que fait langgraph-persistence ?
INVOQUEZ CETTE COMPÉTENCE lorsque votre LangGraph a besoin de persister l'état, de se souvenir des conversations, de voyager dans l'historique ou de configurer la portée du checkpointer des sous-graphes. Couvre les checkpointers, thread_id, voyage temporel, Store et les modes de persistance des sous-graphes.
Checkpointers
Les checkpointers sont le mécanisme de base pour sauvegarder l'état de votre graphe à chaque étape. Ils permettent de reprendre l'exécution à partir d'un point de contrôle donné.
from langgraph.checkpoint import MemorySaver
# Utiliser un checkpointer en mémoire (utile pour le développement)
checkpointer = MemorySaver()
Pour la production, utilisez un checkpointer persistant (base de données):
from langgraph.checkpoint.sqlite import SqliteSaver
checkpointer = SqliteSaver.from_conn_string("checkpoints.db")
Thread ID
Chaque conversation ou session est identifiée par un thread_id. Cela permet d'isoler les histoires et les états entre les utilisateurs ou les sessions.
config = {"configurable": {"thread_id": "user-session-123"}}
# Le graphe utilise automatiquement ce thread_id pour charger/sauvegarder l'état
result = graph.invoke(input_data, config)
Voyage temporel (Time Travel)
Le voyage temporel permet de :
- Rejouer une séquence d'événements à partir d'un état antérieur
- Revenir à un point de contrôle spécifique
- Modifier une entrée passée et voir l'impact sur la suite
# Obtenir l'historique des états pour un thread
states = graph.get_state_history(config)
# Revenir à un état spécifique (par son checkpoint_id)
checkpoint_config = {"configurable": {"thread_id": "user-session-123", "checkpoint_id": "abc123"}}
graph.invoke(new_input, checkpoint_config)
Store (Stockage à long terme)
Le Store permet une persistance qui dépasse le simple état du graphe. Il est utilisé pour stocker des connaissances, des préférences utilisateur, ou toute donnée qui doit survivre au-delà d'une session.
from langgraph.store import Store
store = Store()
store.put("user_preferences", "user-123", {"theme": "dark"})
# Plus tard dans le graphe :
data = store.get("user_preferences", "user-123")
Modes de persistance pour sous-graphes
Lorsque vous utilisez des sous-graphes, vous pouvez configurer la portée du checkpointer :
"shared": tous les sous-graphes partagent le même checkpointer (l'état est global)"isolated": chaque sous-graphe a son propre checkpointer (l'état est privé)"custom": vous définissez la logique de persistance personnalisée
from langgraph.graph import Subgraph
subgraph = Subgraph(
nodes=[...],
edges=[...],
persistence_mode="isolated" # chaque instance de sous-graphe a son propre état
)
Exemple complet
import asyncio
from langgraph.graph import StateGraph, END
from langgraph.checkpoint import MemorySaver
# Définir un graphe simple avec persistance
class AgentState(TypedDict):
messages: List[str]
step: int
checkpointer = MemorySaver()
async def run_agent():
graph = StateGraph(AgentState)
graph.add_node("chat", lambda state: {"messages": ["Réponse"]})
graph.set_entry_point("chat")
graph.add_edge("chat", END)
app = graph.compile(checkpointer=checkpointer)
# Premier appel
config = {"configurable": {"thread_id": "session-1"}}
result = await app.ainvoke({"messages": ["Bonjour"], "step": 0}, config)
# Deuxième appel - l'état est préservé automatiquement
result2 = await app.ainvoke({"messages": ["Comment ça va ?"], "step": 1}, config)
# Voyage temporel vers la première étape
history = app.get_state_history(config)
for state in history:
print(state)
asyncio.run(run_agent())
Bonnes pratiques
- Utilisez des thread_id uniques pour chaque session utilisateur
- Choisissez le bon checkpointer :
MemorySaverpour le développement,SqliteSaverouPostgresSaverpour la production - Nettoyez les états obsolètes si vous utilisez un stockage persistant
- Testez le voyage temporel pour valider la reprise d'exécution
Pour plus de détails, consultez la documentation officielle de LangGraph.