LangGraph : guide complet pour construire des agents à états
LangGraph (Python/TS) : StateGraph, nodes, edges, checkpoints — construire des agents IA robustes avec cycles et branchements. Guide technique francophone 2026.
LangGraph : guide complet pour construire des agents à états
Les agents IA basés sur des boucles ReAct simples atteignent rapidement leurs limites dès que le flux d'exécution devient non linéaire : que faire quand un agent doit revenir en arrière, corriger une erreur ou prendre une décision conditionnelle ? LangGraph répond à ce problème en modélisant l'exécution d'un agent comme un graphe d'état orienté. Ce guide explique comment LangGraph fonctionne, comment l'installer et configurer un premier agent, et quand l'utiliser (ou non). Si vous hésitez entre plusieurs stacks, le comparatif des frameworks agents IA résume les compromis ; pour une approche modulaire par skills et le déploiement d'agents autonomes, explorez aussi OpenClaw.
Résumé rapide
| Critère | Valeur |
|---|---|
| Langage | Python (et JavaScript/TypeScript) |
| Paradigme | Graphe d'état dirigé (StateGraph) |
| Cas d'usage principal | Agents multi-étapes avec logique conditionnelle |
| Relation avec LangChain | Bibliothèque indépendante, compatible LangChain |
| Persistance | Checkpointers (mémoire, SQLite, PostgreSQL) |
| Licence | MIT |
Qu'est-ce que LangGraph ?
LangGraph est une bibliothèque Python (et TypeScript) développée par LangChain Inc. qui permet de construire des agents et des workflows multi-acteurs sous forme de graphes d'état. Elle est indépendante de LangChain au sens où elle n'en requiert pas l'installation, bien qu'elle soit souvent utilisée avec.
Différence avec LangChain
LangChain est une boîte à outils généraliste pour construire des pipelines LLM : chaînes de prompts, intégrations d'outils, retrievers. Son abstraction centrale est la Chain — une séquence d'étapes exécutées de manière linéaire.
LangGraph part d'un constat différent : la plupart des agents réels ne sont pas linéaires. Un agent de recherche peut avoir besoin de vérifier si le résultat obtenu est suffisant, puis soit terminer, soit relancer une nouvelle recherche. Un agent de correction de code peut boucler jusqu'à ce que les tests passent. Ces comportements nécessitent des cycles, des branchements conditionnels et une persistance d'état entre les étapes — ce que LangChain seul gère mal.
LangGraph expose ces concepts explicitement :
- Nodes : unités de traitement (fonctions Python ou chaînes LangChain)
- Edges : transitions entre nodes, pouvant être conditionnelles
- State : objet partagé mis à jour à chaque étape, visible par tous les nodes
- Checkpoints : snapshots de l'état sauvegardés pour la reprise et le débogage
L'approche par graphes d'état
Un StateGraph est un graphe orienté dont chaque nœud prend l'état courant en entrée, effectue une opération, et retourne une mise à jour partielle de l'état. LangGraph fusionne ces mises à jour dans l'état global selon des règles définies (par défaut, remplacement simple ; avec des Annotated types, accumulation possible).
Cette architecture présente deux avantages concrets. D'abord, le flux d'exécution est explicite et inspectable — on peut visualiser le graphe, comprendre les transitions possibles et déboguer nœud par nœud. Ensuite, les cycles sont natifs : un nœud peut renvoyer vers un nœud précédent sans hack ni récursion manuelle.
Guide conceptuel : construire un agent avec LangGraph
Installation
pip install langgraph langchain-openai
Pour la persistance, selon le backend souhaité :
pip install langgraph-checkpoint-sqlite # SQLite
pip install langgraph-checkpoint-postgres # PostgreSQL
Définir l'état
L'état est un TypedDict Python. Chaque nœud reçoit cet état et retourne un dictionnaire de mises à jour.
from typing import TypedDict, Annotated
from langgraph.graph.message import add_messages
class AgentState(TypedDict):
messages: Annotated[list, add_messages]
iteration: int
result: str | None
L'annotation Annotated[list, add_messages] indique à LangGraph d'accumuler les messages plutôt que de les remplacer — comportement essentiel pour un historique de conversation.
Créer le graphe
from langgraph.graph import StateGraph, END
graph = StateGraph(AgentState)
Définir les nœuds (nodes)
Un nœud est une fonction Python qui prend l'état et retourne un dictionnaire partiel :
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
def agent_node(state: AgentState) -> dict:
response = llm.invoke(state["messages"])
return {"messages": [response], "iteration": state["iteration"] + 1}
def tool_node(state: AgentState) -> dict:
# Exécution d'un outil, ex. recherche web
last_message = state["messages"][-1]
tool_result = run_tool(last_message.tool_calls[0])
return {"messages": [tool_result]}
graph.add_node("agent", agent_node)
graph.add_node("tools", tool_node)
Définir les transitions (edges)
Les edges simples connectent deux nœuds directement. Les conditional edges choisissent la destination selon l'état courant.
from langgraph.graph import END
def should_continue(state: AgentState) -> str:
last_message = state["messages"][-1]
# Si le LLM a demandé un appel d'outil
if last_message.tool_calls:
return "tools"
# Sinon, on termine
return END
graph.set_entry_point("agent")
graph.add_conditional_edges("agent", should_continue)
graph.add_edge("tools", "agent") # Retour vers agent après l'outil
Compiler et exécuter
app = graph.compile()
result = app.invoke({
"messages": [{"role": "user", "content": "Quel est le cours du Bitcoin aujourd'hui ?"}],
"iteration": 0,
"result": None
})
Checkpoints et persistance
Les checkpoints permettent de reprendre un graphe interrompu ou de l'inspecter après exécution. Exemple avec SQLite :
from langgraph.checkpoint.sqlite import SqliteSaver
with SqliteSaver.from_conn_string("agent_state.db") as checkpointer:
app = graph.compile(checkpointer=checkpointer)
config = {"configurable": {"thread_id": "session-42"}}
result = app.invoke(initial_state, config=config)
Chaque étape est sauvegardée avec son thread_id. On peut relancer l'exécution depuis n'importe quel checkpoint, ou récupérer l'historique complet avec app.get_state_history(config).
Cycle de vie d'un agent LangGraph
- Entrée : l'état initial est passé au nœud de départ (
entry_point) - Exécution du nœud : le nœud traite l'état et retourne une mise à jour
- Fusion : LangGraph applique la mise à jour à l'état global
- Checkpoint (si configuré) : l'état fusionné est sauvegardé
- Routage : l'edge suivant est évalué (simple ou conditionnel)
- Répétition jusqu'à atteindre
END
Ce cycle est synchrone par défaut mais LangGraph supporte les nœuds async pour les I/O non bloquants.
Exemple concret : agent RAG avec boucle de correction
Cet exemple construit un agent qui récupère des documents, génère une réponse, puis évalue si la réponse est suffisamment précise — et relance une recherche si nécessaire.
from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages
from langchain_openai import ChatOpenAI
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
# État
class RAGState(TypedDict):
question: str
documents: list[str]
answer: str | None
is_sufficient: bool
attempts: int
# Composants
llm = ChatOpenAI(model="gpt-4o-mini")
vectorstore = FAISS.load_local("my_index", OpenAIEmbeddings())
# Nœuds
def retrieve(state: RAGState) -> dict:
docs = vectorstore.similarity_search(state["question"], k=4)
return {"documents": [d.page_content for d in docs]}
def generate(state: RAGState) -> dict:
context = "\n".join(state["documents"])
prompt = f"Contexte :\n{context}\n\nQuestion : {state['question']}\nRéponse :"
response = llm.invoke(prompt)
return {"answer": response.content, "attempts": state["attempts"] + 1}
def evaluate(state: RAGState) -> dict:
prompt = (
f"La réponse suivante est-elle complète et précise pour la question '{state['question']}' ?\n"
f"Réponse : {state['answer']}\n"
"Réponds uniquement par 'oui' ou 'non'."
)
verdict = llm.invoke(prompt).content.strip().lower()
return {"is_sufficient": verdict == "oui"}
def should_retry(state: RAGState) -> str:
if state["is_sufficient"] or state["attempts"] >= 3:
return END
return "retrieve" # Nouvelle recherche
# Construction du graphe
graph = StateGraph(RAGState)
graph.add_node("retrieve", retrieve)
graph.add_node("generate", generate)
graph.add_node("evaluate", evaluate)
graph.set_entry_point("retrieve")
graph.add_edge("retrieve", "generate")
graph.add_edge("generate", "evaluate")
graph.add_conditional_edges("evaluate", should_retry)
app = graph.compile()
result = app.invoke({
"question": "Quels sont les avantages de LangGraph sur LangChain ?",
"documents": [],
"answer": None,
"is_sufficient": False,
"attempts": 0
})
print(result["answer"])
Cet agent boucle au maximum 3 fois. À chaque itération, il récupère des documents, génère une réponse, l'évalue et décide s'il recommence. Le should_retry combine deux critères d'arrêt : qualité suffisante ou limite d'itérations atteinte.
Bonnes pratiques
Erreurs fréquentes
État mal typé : oublier l'annotation Annotated sur les listes provoque un remplacement à chaque nœud au lieu d'une accumulation. Toujours utiliser add_messages pour les historiques de conversation.
Cycles infinis : un conditional edge qui retourne toujours vers le même nœud sans condition de sortie bloque indéfiniment. Toujours inclure un compteur d'itérations ou une condition d'échec explicite.
Nœuds trop gros : regrouper plusieurs responsabilités dans un seul nœud rend le graphe difficile à déboguer. Chaque nœud doit avoir une responsabilité unique et observable via les checkpoints.
Ignorer les erreurs d'outil : les appels d'API externes échouent. Gérer les exceptions dans les nœuds tool et mettre à jour l'état avec un message d'erreur explicite plutôt que de laisser propager l'exception.
Quand ne pas utiliser LangGraph
- Pipelines linéaires simples : si votre agent suit toujours les mêmes étapes dans le même ordre, une simple chaîne LangChain ou même une fonction Python suffit. LangGraph ajoute de la complexité sans bénéfice.
- Prototypage rapide : la définition explicite du graphe ralentit l'itération initiale. Commencez par un script simple, migrez vers LangGraph quand la logique conditionnelle devient nécessaire.
- Équipes non familières avec les graphes : le modèle mental du graphe d'état demande un temps d'apprentissage. Sur de petites équipes avec peu de temps, ce coût peut dépasser le bénéfice.
Gestion des cycles
Utilisez toujours une limite d'itérations dans l'état et une condition de sortie sur cette limite. Pour les agents longs, configurez recursion_limit à la compilation :
app = graph.compile()
app.invoke(state, config={"recursion_limit": 10})
FAQ
LangGraph est-il une alternative à LangChain ou un complément ?
LangGraph est un complément. Il peut fonctionner sans LangChain, mais il est souvent utilisé avec pour bénéficier des intégrations LLM, des outils et des retrievers déjà disponibles. LangChain gère les appels LLM et les outils ; LangGraph orchestre leur séquençage conditionnel.
LangGraph supporte-t-il les agents multi-acteurs ?
Oui. LangGraph permet de définir plusieurs sous-graphes (un par acteur) et de les faire communiquer via un état partagé ou via des Send events. C'est l'approche recommandée pour les systèmes où plusieurs agents spécialisés collaborent sur une même tâche.
Peut-on utiliser LangGraph en production ?
Oui, LangGraph est utilisé en production par plusieurs entreprises. Pour un déploiement robuste, utiliser un checkpointer PostgreSQL pour la persistance, configurer des timeouts sur les nœuds I/O et activer LangSmith pour le traçage des exécutions.
Quelle est la différence entre LangGraph et AutoGen ?
AutoGen (Microsoft) modélise les agents comme des entités communicantes via des messages. LangGraph modélise l'exécution comme un graphe d'état explicite. LangGraph donne plus de contrôle sur le flux ; AutoGen facilite la collaboration entre agents hétérogènes avec moins de code de plomberie.
LangGraph fonctionne-t-il avec des modèles autres qu'OpenAI ?
Oui. LangGraph est agnostique au modèle LLM. Il fonctionne avec tout modèle supporté par LangChain (Anthropic Claude, Mistral, Ollama, Cohere, etc.) ou directement avec n'importe quel callable Python qui retourne une réponse.
Articles liés
LangGraph s'inscrit dans un écosystème plus large de frameworks d'agents IA. Pour aller plus loin, plusieurs ressources sur ce site couvrent des frameworks complémentaires ou alternatifs.
- Guide complet des agents IA en 2026 — comprendre les concepts fondamentaux avant de choisir un framework
- OpenClaw vs LangGraph — comparaison directe entre les deux approches pour orchestrer des agents
- Quel est le meilleur framework pour agents IA ? — tableau comparatif LangGraph, CrewAI, AutoGen, OpenClaw selon les cas d'usage
- Guide complet OpenClaw — alternative orientée automatisation SEO avec une architecture différente
Restez informé sur les agents IA
Nouveaux tutoriels, comparatifs et guides pratiques directement dans votre boîte mail.
