LangGraph pour les agents de production : points de contrôle, HITL et graphes multi-agents
Pourquoi les chaînes s’arrêtent et se relancent sur les cycles, et comment les nœuds, les arêtes de LangGraph ainsi que les outils de sauvegarde des points de contrôle permettent aux agents de production de fonctionner, avec une révision par un humain.
Sources: LangGraph Explained: Build Production-Ready AI Agents in 2026
Qu’est-ce que LangGraph ?
LangGraph est un environnement d’exécution permettant de créer des agents à états, multi-étapes sous forme de graphes explicites : les nœuds effectuent des tâches, les arêtes déterminent ce qui s’exécute ensuite, et l’état partagé persiste à travers les étapes — y compris après des échecs ou des pauses humaines.
Il y a deux ans, de nombreux “agents” n’étaient que des boucles while autour d’un LLM sans mécanisme de récupération. Les plantages en cours de tâche obligeaient à tout reprendre depuis le début. Les graphes rendent la mémoire, les branches et la reprise en cours de mission des éléments fondamentaux.
Pourquoi les chaînes ne suffisaient pas
Les chaînes LCEL se révèlent utiles pour des pipelines linéaires. Elles peinent lorsqu’il est nécessaire d’avoir des cycles, un routage conditionnel, des points de contrôle durables ou l’approbation humaine en cours d’exécution. Ce sont là des problèmes de graphes.
Concepts fondamentaux : nœuds, arêtes et état
- État — champs typés que l’exécution transporte
- Nœuds — fonctions qui mettent à jour l’état
from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, END
import operator
# Define your state
class AgentState(TypedDict):
messages: Annotated[list, operator.add]
next_action: str
final_answer: str
from langgraph.graph import StateGraph, END
from langgraph.prebuilt import ToolNode
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
# 1. Define a tool
@tool
def search_web(query: str) -> str:
"""Search the web for current information."""
# Connect to your actual search API here
return f"Search results for: {query}"
# 2. Define the LLM with tools bound
llm = ChatOpenAI(model="gpt-4o", temperature=0)
tools = [search_web]
llm_with_tools = llm.bind_tools(tools)
# 3. Define node functions
def call_llm(state):
response = llm_with_tools.invoke(state["messages"])
return {"messages": [response]}
def should_continue(state):
last_message = state["messages"][-1]
if last_message.tool_calls:
return "run_tools"
return END
# 4. Build the graph
workflow = StateGraph(AgentState)
workflow.add_node("agent", call_llm)
workflow.add_node("run_tools", ToolNode(tools))
workflow.set_entry_point("agent")
workflow.add_conditional_edges("agent", should_continue)
workflow.add_edge("run_tools", "agent")
# 5. Compile with a checkpointer
from langgraph.checkpoint.sqlite import SqliteSaver
memory = SqliteSaver.from_conn_string("agents.db")
graph = workflow.compile(checkpointer=memory)
# 6. Run with a thread ID for persistent state
config = {"configurable": {"thread_id": "user-123"}}
result = graph.invoke({"messages": [("user", "What is the latest GPT model?")]}, config)
print(result["messages"][-1].content)
# Add a human approval gate before a risky action
workflow.add_node("human_review", interrupt(before="execute_payment"))
pip install langgraph langchain-openai psycopg2-binary
Comment fonctionne réellement la gestion d’état
Les mises à jour sont fusionnées via des réducteurs. Des réducteurs mal configurés dupliquent les messages ou effacent des champs. Considérez le choix des réducteurs comme faisant partie de l’examen du schéma.
Premier agent (Python)
Définir l’état → ajouter des nœuds → relier les arêtes → compiler → appeler avec un identifiant de thread lors de l’utilisation d’un sauvegardeur.
Intervention humaine
Interrompre avant les effets secondaires ; reprendre avec un en-tête d’approbation. C’est là la différence opérationnelle entre les démos et les agents en production.
Modèles multi-agents
Les transferts de responsabilités entre superviseurs/spécialistes, les branches parallèles et les sous-graphes s’adaptent parfaitement à des nœuds nommés disposant d’un état partagé ou partitionné.
Persistence et récupération
Les outils de sauvegarde basés sur une base de données survivent aux redémarrages de processus. Les sauvegardes en mémoire ne servent qu’aux tests.
Quand recourir à LangGraph
L’utilisez lorsque le flux de contrôle est non linéaire, qu’il faut faire une pause ou reprendre quelque chose. Préférez des chaînes plus simples pour des réponses RAG uniques sans branches.
Conclusion
Les agents en environnement de production ont besoin d’un état et d’arêtes explicites — pas de solutions improvisées. LangGraph est un moyen fiable pour représenter cela en code.
Évitez le bruit des promotions sur les plateformes ; la valeur technique réside dans un flux de contrôle sauvegardé et dans le HITL. Concentrez les tutoriels sur ces éléments fondamentaux.
Instrumentez les événements de démarrage/arrêt des nœuds afin que les traces montrent quelle branche a été exécutée. Les graphes sans télémesure deviennent des boîtes noires à 2 heures du matin.
Les définitions des graphes sont mises à jour en même temps que les prompts. Un renomage de nœud sans migration perturbe les threads repris qui continuent de faire référence aux anciens noms.
Évitez le bruit des promotions sur le marché ; la valeur technique réside dans un flux de contrôle avec points de contrôle et HITL. Gardez les tutoriels axés sur ces primitives.
Instrumentez les événements de démarrage/fin des nœuds afin que les traces indiquent quel branch a été exécuté. Les graphes sans télémesure deviennent des boîtes noires à 2 heures du matin.
Les définitions des graphes sont mises à jour en même temps que les prompts. Un renomage de nœud sans migration perturbe les threads repris qui continuent de faire référence aux anciens noms.
Évitez le bruit des promotions sur le marché ; la valeur technique réside dans un flux de contrôle avec points de contrôle et HITL. Gardez les tutoriels axés sur ces primitives.
Instrumentez les événements de démarrage/fin des nœuds afin que les traces indiquent quel branch a été exécuté. Les graphes sans télémesure deviennent des boîtes noires à 2 heures du matin.
Les définitions des graphes sont mises à jour en même temps que les prompts. Un renomage d’un nœud sans migration perturbe les threads repris qui continuent de faire référence aux anciens noms.
Évitez le bruit des promotions sur le marché ; la valeur technique réside dans un flux de contrôle vérifié par des points de contrôle et HITL. Gardez les tutoriels axés sur ces primitives.
Instrumentez les événements de démarrage/fin des nœuds afin que les traces indiquent quel branch a été exécuté. Les graphes sans télémesure deviennent des boîtes noires à 2 heures du matin.
Les définitions des graphes sont mises à jour en même temps que les prompts. Un renomage d’un nœud sans migration perturbe les threads repris qui continuent de faire référence aux anciens noms.
Évitez le bruit des promotions sur le marché ; la valeur technique réside dans un flux de contrôle vérifié par des points de contrôle et HITL. Gardez les tutoriels axés sur ces primitives.
Instrumentez les événements de démarrage/fin des nœuds afin que les traces indiquent quel branch a été exécuté. Les graphes sans télémesure deviennent des boîtes noires à 2 heures du matin.
Les définitions des graphes sont mises à jour en même temps que les prompts. Un renomage d’un nœud sans migration perturbe les threads repris qui continuent de faire référence aux anciens noms.
Évitez le bruit des promotions sur le marché ; la valeur technique réside dans un flux de contrôle vérifié par des points de contrôle et HITL. Gardez les tutoriels axés sur ces primitives.
Instrumentez les événements de démarrage/fin des nœuds afin que les traces indiquent quel branch a été exécuté. Les graphes sans télémesure deviennent des boîtes noires à 2 heures du matin.
Les définitions des graphes sont mises à jour en même temps que les prompts. Un renomage d’un nœud sans migration perturbe les threads repris qui continuent de faire référence aux anciens noms.
Évitez le bruit des promotions sur le marché ; la valeur technique réside dans un flux de contrôle vérifié par des points de contrôle et HITL. Gardez les tutoriels axés sur ces primitives.
Instrumentez les événements de démarrage/fin des nœuds afin que les traces indiquent quel branch a été exécuté. Les graphes sans télémesure deviennent des boîtes noires à 2 heures du matin.
Les définitions des graphes sont mises à jour en même temps que les prompts. Un renomage d’un nœud sans migration perturbe les threads repris qui continuent de faire référence aux anciens noms.
Évitez le bruit des promotions sur le marché ; la valeur technique réside dans un flux de contrôle vérifié par des points de contrôle et HITL. Gardez les tutoriels axés sur ces primitives.
Instrumentez les événements de démarrage/fin des nœuds afin que les traces indiquent quel branch a été exécuté. Les graphes sans télémesure deviennent des boîtes noires à 2 heures du matin.
Les définitions des graphes sont mises à jour en même temps que les prompts. Un renomage d’un nœud sans migration perturbe les threads repris qui continuent de faire référence aux anciens noms.
Évitez le bruit des promotions sur le marché ; la valeur technique réside dans un flux de contrôle vérifié par des points de contrôle et HITL. Gardez les tutoriels axés sur ces primitives.
Instrumentez les événements de démarrage/fin des nœuds afin que les traces indiquent quel branch a été exécuté. Les graphes sans télémesure deviennent des boîtes noires à 2 heures du matin.
Les définitions des graphes sont mises à jour en même temps que les prompts. Un renomage d’un nœud sans migration perturbe les threads repris qui continuent de faire référence aux anciens noms.
Évitez le bruit des promotions sur le marché ; la valeur technique réside dans un flux de contrôle avec points de contrôle et HITL. Gardez les tutoriels axés sur ces primitives.
Instrumentez les événements de démarrage/fin des nœuds afin que les traces indiquent quel branch a été exécuté. Les graphes sans télémesure deviennent des boîtes noires à 2 heures du matin.
Les définitions des graphes sont mises à jour en même temps que les prompts. Un renomage d’un nœud sans migration perturbe les threads repris qui continuent de faire référence aux anciens noms.
Évitez le bruit des promotions sur le marché ; la valeur technique réside dans un flux de contrôle avec points de contrôle et HITL. Gardez les tutoriels axés sur ces primitives.
Instrumentez les événements de démarrage/fin des nœuds afin que les traces indiquent quel branch a été exécuté. Les graphes sans télémesure deviennent des boîtes noires à 2 heures du matin.
Les définitions des graphes sont mises à jour en même temps que les prompts. Un renomage d’un nœud sans migration perturbe les threads repris qui continuent de faire référence aux anciens noms.
Évitez le bruit des promotions sur le marché ; la valeur technique réside dans un flux de contrôle vérifié par des points de contrôle et HITL. Gardez les tutoriels axés sur ces primitives.
Instrumentez les événements de démarrage/fin des nœuds afin que les traces indiquent quel branch a été exécuté. Les graphes sans télémesure deviennent des boîtes noires à 2 heures du matin.
Les définitions des graphes sont mises à jour en même temps que les prompts. Un renomage d’un nœud sans migration perturbe les threads repris qui continuent de faire référence aux anciens noms.
Évitez le bruit des promotions sur le marché ; la valeur technique réside dans un flux de contrôle vérifié par des points de contrôle et HITL. Gardez les tutoriels axés sur ces primitives.
Instrumentez les événements de démarrage/fin des nœuds afin que les traces indiquent quel branch a été exécuté. Les graphes sans télémesure deviennent des boîtes noires à 2 heures du matin.
Les définitions de graphes sont présentées conjointement avec les instructions. Un renomage d’un nœud sans migration perturbe les threads en cours qui font encore référence aux anciens noms.
Évitez le bruit des promotions sur le marché ; la valeur technique réside dans un flux de contrôle vérifiable et dans HITL. Gardez les tutoriels axés sur ces primitives.
Associez chaque type d’incident de production à une fonctionnalité du graphique : délais d’attente → nœud de tentatives répétées, JSON invalide du outil → nœud de validation, suppression par l’opérateur → interruption.
Les sous-graphes aident à isoler les instructions spécifiques aux spécialistes sans perdre aucun identifiant de thread parent pour les audits.
Évitez d’entasser toute la politique commerciale dans un seul nœud central ; divisez-la afin que les échecs puissent être attribués clairement.
Associez chaque type d’incident de production à une fonctionnalité du graphique : délais d’attente → nœud de tentatives répétées, JSON invalide du outil → nœud de validation, suppression par l’opérateur → interruption.
Les sous-graphes aident à isoler les instructions spécifiques aux spécialistes sans perdre aucun identifiant de thread parent pour les audits.
Évitez de mettre toute la politique commerciale dans un seul nœud central ; divisez-la afin que les échecs puissent être attribués.
Associez chaque type d’incident de production à une caractéristique du graphe : temps d’attente → nœud de tentatives répétées, JSON invalide du outil → nœud de validation, modification par l’opérateur → interruption.
Les sous-graphes aident à isoler les demandes spécifiques des spécialistes sans perdre aucun identifiant de thread parent pour les audits.
Évitez de mettre toute la politique commerciale dans un seul nœud central ; divisez-la afin que les échecs puissent être attribués.
Associez chaque type d’incident de production à une caractéristique du graphe : temps d’attente → nœud de tentatives répétées, JSON invalide du outil → nœud de validation, modification par l’opérateur → interruption.
Les sous-graphes aident à isoler les demandes spécifiques des spécialistes sans perdre aucun identifiant de thread parent pour les audits.
Évitez de mettre toute la politique commerciale dans un seul nœud central ; divisez-la afin que les échecs puissent être attribués.
Associez chaque type d’incident de production à une caractéristique du graphe : les temps d’attente → nœud de tentatives répétées, le JSON invalide d’une outil → nœud de validation, la modification par l’opérateur → interruption.
Les sous-graphes aident à isoler les demandes spécifiques des spécialistes sans perdre aucun identifiant de thread parent pour les audits.
Évitez d’entasser toute la politique commerciale dans un seul nœud central ; divisez-la afin que les échecs puissent être attribués précisément.
Associez chaque type d’incident de production à une caractéristique du graphe : les temps d’attente → nœud de tentatives répétées, le JSON invalide d’une outil → nœud de validation, la modification par l’opérateur → interruption.
Les sous-graphes aident à isoler les demandes spécifiques des spécialistes sans perdre aucun identifiant de thread parent pour les audits.