ReAct expliqué aux devs : le pattern derrière les agents IA
Raisonner, agir, observer, recommencer. Le pattern qui fait tourner LangChain, LangGraph et CrewAI, et pourquoi le LLM n'exécute jamais lui-même les actions.
7 min de lecture
Quand on parle d'agents IA, on imagine souvent une boîte noire magique qui "réfléchit" et "agit" toute seule.
En réalité, derrière la plupart des agents — ceux de LangChain, LangGraph, CrewAI — il y a un pattern simple et élégant : ReAct.
Si tu es dev JavaScript ou TypeScript et que tu veux comprendre comment un agent IA fonctionne vraiment sous le capot, cet article est pour toi.
Le problème : un LLM ne peut pas agir
Un LLM classique (GPT, Claude, Llama...) a une limite fondamentale : il ne peut que générer du texte.
Il ne peut pas :
- chercher sur Google
- lire une base de données
- appeler une API
- exécuter du code
Si tu lui demandes "Quel temps fait-il à Paris ?", il va te répondre quelque chose de plausible... mais probablement faux, parce qu'il n'a aucun accès au monde réel.
C'est le problème d'hallucination : le modèle "invente" quand il ne sait pas.
La solution : ReAct (Reasoning + Acting)
ReAct vient d'un paper de recherche de Princeton et Google publié en 2022. L'idée tient en une phrase :
Faire réfléchir le modèle à voix haute, et lui donner des outils pour vérifier ses réflexions.
Le nom est la fusion de deux mots :
- Reasoning — le modèle raisonne étape par étape
- Acting — le modèle peut appeler des outils externes
Avant ReAct, ces deux capacités existaient séparément :
| Approche | Ce qu'elle fait | Le problème |
|---|---|---|
| Chain-of-Thought | Le modèle raisonne étape par étape | Il ne peut pas vérifier → il hallucine |
| Action-only | Le modèle appelle des outils | Il ne raisonne pas sur pourquoi → il agit à l'aveugle |
ReAct combine les deux dans une boucle : raisonner → agir → observer le résultat → raisonner à nouveau.
Le cycle ReAct en 4 étapes
Voici ce qui se passe quand tu poses une question à un agent ReAct :
📝 Question : "Qui a gagné le dernier Ballon d'Or ?"
💭 Thought : "Je ne connais pas le résultat le plus récent.
Je vais vérifier sur Wikipédia."
⚡ Action : WikipediaSearch("Ballon d'Or 2024")
👁️ Observation : "Le Ballon d'Or 2024 a été décerné à..."
💭 Thought : "J'ai l'information, je peux répondre."
✅ Final Answer : "Le Ballon d'Or 2024 a été remporté par..."
C'est une boucle. Si la première recherche ne suffit pas, l'agent refait un tour : Thought → Action → Observation, jusqu'à avoir assez d'info pour conclure.
Le schéma complet

Le point clé : le LLM ne fait PAS les actions
C'est la chose la plus importante à comprendre.
Quand l'agent écrit Action: WikipediaSearch("Ballon d'Or"), il ne cherche pas réellement sur Wikipédia. Il génère du texte qui dit qu'il veut chercher.
C'est le runtime (LangGraph, LangChain, ou tout autre framework) qui :
- Parse la sortie du LLM
- Détecte qu'il y a une action à exécuter
- Exécute l'outil (appel API, requête DB, etc.)
- Réinjecte le résultat comme "Observation" dans le prompt
- Rappelle le LLM avec tout le contexte mis à jour
Le LLM est le cerveau qui décide quoi faire. Le runtime est les mains qui exécutent.
┌─────────────────────────────────┐
│ LLM (cerveau) │
│ │
│ "Je veux chercher sur Wiki..." │
│ (génère du texte) │
└───────────────┬─────────────────┘
│ texte parsé
▼
┌─────────────────────────────────┐
│ Runtime / LangGraph (mains) │
│ │
│ → Parse l'action │
│ → Appelle l'API Wikipédia │
│ → Récupère le résultat │
│ → Réinjecte dans le prompt │
└─────────────────────────────────┘
La mémoire de travail : le Scratchpad
Un LLM est stateless — il n'a aucune mémoire entre deux appels. Chaque appel, c'est comme s'il se réveillait pour la première fois.
Alors comment l'agent se souvient de ce qu'il a déjà trouvé ?
Grâce au scratchpad (littéralement : "bloc-notes"). C'est un texte qui accumule tout l'historique des tours précédents (Thought + Action + Observation) et qui est renvoyé au LLM à chaque nouvel appel.
Exemple concret
L'agent doit comparer le PIB de la France et de l'Allemagne.
Tour 1 — le scratchpad est vide :
Thought: Je dois chercher le PIB de la France.
Action: WikiSearch("PIB France 2024")
Observation: 2 800 milliards €
Tour 2 — le scratchpad contient le tour 1 :
[tour 1 complet visible par le LLM]
Thought: J'ai la France. Maintenant l'Allemagne.
Action: WikiSearch("PIB Allemagne 2024")
Observation: 3 500 milliards €
Tour 3 — le scratchpad contient les tours 1 + 2 :
[tours 1 et 2 visibles par le LLM]
Thought: J'ai les deux chiffres, je peux comparer.
Final Answer: Le PIB de l'Allemagne (3 500 Mds) dépasse
celui de la France (2 800 Mds)...
Le problème de la taille
Plus l'agent fait de tours, plus le scratchpad grossit, et plus ça consomme de tokens (= de l'argent).
Les stratégies pour gérer ça :
- Rolling window : ne garder que les N derniers tours
- Résumé : compresser les anciens tours en un paragraphe (via un appel LLM dédié)
- Épisodique : ne garder que les résultats clés, pas le raisonnement intermédiaire
C'est un vrai sujet d'ingénierie quand ton agent fait 10+ appels d'outils.
Et les Function Calls dans tout ça ?
Si tu as utilisé l'API d'OpenAI ou Claude récemment, tu connais le function calling : le modèle renvoie directement un objet JSON structuré { "tool": "...", "args": {...} } au lieu de texte libre.
C'est plus fiable que le parsing de texte, mais le pattern conceptuel reste le même :
| ReAct classique (texte) | Function calling moderne | |
|---|---|---|
| Format | Texte libre parsé avec regex | JSON structuré |
| Raisonnement | Visible ("Thought: ...") | Implicite (dans la tête du modèle) |
| Fiabilité | Fragile (parsing) | Robuste (typé) |
| Débug | Facile (tu lis le raisonnement) | Plus difficile |
Les frameworks comme LangGraph supportent les deux, et dans la pratique, les agents modernes utilisent le function calling sous le capot tout en suivant la logique ReAct.
Pourquoi c'est important pour toi en tant que dev
Si tu es développeur JavaScript/TypeScript et que tu veux construire des agents IA, comprendre ReAct c'est comprendre le pattern fondamental sur lequel tout repose.
Que tu utilises LangGraph, LangChain, le Vercel AI SDK, ou que tu codes ton propre agent from scratch — c'est toujours la même boucle :
Raisonner → Décider → Agir → Observer → Boucler
Une fois que tu as compris ça, le reste (RAG, multi-agents, planification) c'est des variations et des compositions de ce même pattern.
Sujets abordés
- IA
- LLM
- agents
- LangGraph
- TypeScript