LangGraph : construire des agents IA autonomes avec orchestration, mémoire et outils
Les LLM savent générer du texte. Mais un agent IA, c’est autre chose : c’est un programme qui raisonne, décide, utilise des outils, revient en arrière si nécessaire, et maintient un état entre les étapes. LangGraph, bibliothèque open source de l’écosystème LangChain, permet de construire exactement cela : des agents à base de graphes d’états, avec cycles, branchements conditionnels et mémoire persistante.
Pourquoi LangGraph plutôt qu’une chaîne linéaire
Un pipeline RAG classique est séquentiel : requête → retrieval → génération → réponse. Mais un agent doit pouvoir boucler, prendre des décisions, appeler un outil puis décider d’en appeler un autre en fonction du résultat. LangGraph modélise ce comportement sous forme de graphe orienté avec état (StateGraph) où chaque nœud est une fonction Python et chaque arête peut être conditionnelle. Le graphe tourne en boucle tant que l’agent n’a pas atteint un nœud terminal, exactement comme un humain qui itère sur un problème.
Les concepts fondamentaux
LangGraph repose sur quatre briques principales :
- State : un objet typé (TypedDict ou Pydantic) qui porte l’état complet de l’agent — messages, résultats intermédiaires, compteurs de boucle, flags de décision.
- Nodes : des fonctions Python qui reçoivent l’état, exécutent une action (appel LLM, requête API, transformation de données) et retournent un état mis à jour.
- Edges : les transitions entre nœuds, qui peuvent être inconditionnelles ou conditionnelles (une fonction Python décide du prochain nœud en fonction de l’état).
- Checkpointer : un mécanisme de persistance (SQLite, PostgreSQL) qui sauvegarde l’état à chaque étape, permettant reprise après erreur, historique de conversation, et human-in-the-loop.
Exemple minimal : un agent qui utilise des outils
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.prebuilt import ToolNode, tools_condition
from langchain_community.llms import Ollama
from langchain_core.tools import tool
@tool
def rechercher_ckan(query: str) -> str:
"""Recherche un jeu de données sur le portail CKAN."""
# Appel API CKAN ici
return f"3 jeux de données trouvés pour '{query}'"
@tool
def analyser_csv(url: str) -> str:
"""Télécharge et analyse un fichier CSV."""
# DuckDB ou pandas ici
return "Le fichier contient 12 colonnes et 45 000 lignes"
# Définir le modèle (Ollama local)
llm = Ollama(model="mistral").bind_tools([rechercher_ckan, analyser_csv])
# Construire le graphe
graph = StateGraph(MessagesState)
graph.add_node("agent", lambda state: {"messages": [llm.invoke(state["messages"])]})
graph.add_node("tools", ToolNode([rechercher_ckan, analyser_csv]))
graph.add_edge(START, "agent")
graph.add_conditional_edges("agent", tools_condition)
graph.add_edge("tools", "agent")
app = graph.compile()
# Lancer l'agent
result = app.invoke({
"messages": [("user", "Trouve les données transport de Rennes et analyse le premier CSV")]
})
Dans cet exemple, l’agent commence par appeler le LLM. Si le LLM décide d’utiliser un outil (recherche CKAN, analyse CSV), le graphe route vers le nœud tools, puis revient au nœud agent avec le résultat. Le cycle continue jusqu’à ce que le LLM produise une réponse finale sans appel d’outil.
Mémoire persistante et human-in-the-loop
En ajoutant un checkpointer, chaque exécution du graphe est sauvegardée étape par étape. Cela ouvre deux capacités essentielles en production : la reprise après erreur (l’agent reprend exactement là où il s’est arrêté) et le human-in-the-loop : on peut interrompre le graphe avant un nœud critique (par exemple avant d’écrire dans une base de données), demander validation à un humain, puis reprendre l’exécution.
from langgraph.checkpoint.sqlite import SqliteSaver
memory = SqliteSaver.from_conn_string(":memory:")
app = graph.compile(checkpointer=memory, interrupt_before=["tools"])
# Premier appel — s'arrête avant l'exécution de l'outil
config = {"configurable": {"thread_id": "session-42"}}
result = app.invoke({"messages": [("user", "Supprime les doublons du dataset")]}, config)
# Validation humaine, puis reprise
app.invoke(None, config) # continue l'exécution
Agents multi-acteurs et sous-graphes
LangGraph permet de composer des agents complexes à partir de sous-graphes. Un superviseur peut déléguer des tâches à des agents spécialisés : un agent « recherche open data », un agent « analyse qualité », un agent « rédaction de fiche métadonnée », chacun avec son propre graphe d’états. Le superviseur orchestre les échanges via un état partagé. C’est le pattern supervisor-worker qui se rapproche d’un véritable control plane pour agents.
Intégration dans une stack auto-hébergée
LangGraph s’intègre naturellement avec les briques déjà couvertes sur askem.eu :
- Ollama / vLLM comme backend LLM (via LangChain ou API OpenAI-compatible)
- Qdrant pour le retrieval vectoriel dans les nœuds RAG
- n8n pour déclencher un agent via webhook ou planification
- Langfuse pour tracer chaque étape du graphe (chaque nœud, chaque appel LLM, chaque outil)
- PostgreSQL comme checkpointer persistant en production
- MCP pour exposer des outils externes à l’agent via le protocole standard
LangGraph vs. les alternatives
D’autres frameworks existent pour construire des agents : CrewAI (orienté rôles et collaboration), AutoGen (Microsoft, multi-agent conversationnel), Haystack (pipelines modulaires). LangGraph se distingue par sa granularité de contrôle : on définit explicitement chaque transition, chaque condition, chaque point d’interruption. C’est moins magique mais plus prédictible, ce qui compte en production quand on a besoin de garantir un comportement déterministe et de déboguer finement.
Points de vigilance en production
- Boucles infinies : toujours définir un compteur de récursion maximal (
recursion_limit) pour éviter qu’un agent tourne indéfiniment. - Coût et latence : chaque cycle du graphe implique un appel LLM. Un agent qui boucle 8 fois sur un problème coûte 8× en tokens et en temps. Monitorer avec Langfuse.
- Déterminisme : les LLM sont stochastiques. Le même état peut produire des décisions différentes. Prévoir des tests de non-régression sur les chemins critiques.
- Sécurité des outils : un agent qui a accès à des outils d’écriture (API, base de données, fichiers) doit être sandboxé. Le pattern human-in-the-loop est indispensable pour les actions irréversibles.
Pour aller plus loin
- Documentation officielle : langchain-ai.github.io/langgraph
- Dépôt GitHub : github.com/langchain-ai/langgraph
- LangGraph Platform (option cloud ou self-hosted) pour le déploiement à l’échelle
- Tutoriel « Build a ReAct Agent » dans la documentation officielle
