ReAct : mémoire de raisonnement et mémoire de conversation

, par Bertrand Degoy

Dans la conception d’un agent conversationnel basé sur le modèle ReAct de LlamaIndex, il est crucial de bien distinguer les différentes formes de mémoire utilisées. Trop souvent confondues, la mémoire de raisonnement interne (utilisée pendant une requête) et la mémoire de conversation (persistante entre les échanges) remplissent des rôles très différents.
Cette clarification vise à poser un vocabulaire rigoureux et à éviter toute ambiguïté dans l’architecture ou la documentation de nos agents.

Distinction entre ReAct Memory et Conversation Memory

Dans un agent conversationnel basé sur `ReActAgent` de `llama_index`, il est essentiel de distinguer deux types de mémoire bien distincts. Cette séparation permet de structurer proprement l’architecture des traitements et d’éviter toute confusion entre raisonnement interne et historique utilisateur.

ReAct Memory : mémoire de raisonnement
Également appelée "Mémoire ReAct".

Définition : mémoire temporaire utilisée pendant le traitement d’une requête unique.

Contenu :
 La question de l’utilisateur
 Les `Thoughts` (raisonnements internes)
 Les `Actions` (outils appelés)
 Les `Observations` (résultats des actions)
 La `Final Answer`

Cycle de vie : réinitialisée à chaque nouvelle question.

Stockage : dans `state["intermediate_steps"]` ou `AgentChatResponse.intermediate_steps`.

Remarque : cette mémoire est volatile et ne doit pas être confondue avec l’historique de conversation.

Conversation Memory : mémoire de conversation
Également appelée "Mémoire conversationnelle", "Chat memory", "History".

Définition : mémoire persistante des échanges utilisateur ↔ assistant, gérée par l’application appelante.

Contenu :
 Les messages de l’utilisateur (`role="user"`)
 Les réponses de l’agent (`role="assistant"`)

Cycle de vie : maintenue entre les requêtes, sauvegardée par l’application (fichier, base, buffer).

Stockage : via un objet comme `ChatMemoryBuffer`, ou une base externe. L’instance est souvent nommée "chat_memory".

Utilisation : pour injecter du contexte dans les prompts, suivre le fil de la discussion, ou adapter les réponses.

Comparaison synthétique

Type de mémoire Portée Contenu Persistée Gérée par
ReAct Memory Intra-requête Thoughts, actions, obs Non ReActAgent
Conversation Memory Inter-requête Messages utilisateur ↔ assistant Oui Application

Nos bonnes pratiques
 Utiliser le bon vocabulaire pour le nommage des fonctions et des variables.
 Ne jamais injecter les `intermediate_steps` dans le prompt utilisateur.
 Gérer la mémoire de conversation séparément, via un buffer ou une base.
 Injecter dynamiquement les derniers tours dans le prompt si besoin de contexte.
 Encapsuler les accès mémoire dans des méthodes dédiées (`get_history`, `update_memory`, etc.).
 Tracer les deux types de mémoire indépendamment pour audit ou debug.

Faut-il persister la ReAct Memory ?

Dans la logique ReAct classique, la mémoire de raisonnement est temporaire : elle est reconstruite à chaque requête, puis oubliée. Cela garantit un raisonnement frais et indépendant.
Mais dans certains cas — comme une série de questions sur un même objet — il peut être judicieux de persister certains résultats intermédiaires pour éviter des appels redondants à des outils.

Cas typique : résolution d’entité

Supposons que l’on pose plusieurs questions sur une entité nommée "Acme Corp". À chaque tour, ReAct doit :
 Identifier l’entité
 Résoudre son ID via un outil
 Appeler un outil avec cet ID qui retournera les données de l’entité

Sans mémoire persistante, l’agent répète ces étapes à chaque tour.

Stratégie : extraire et stocker les résultats utiles

Il faut inspecter les `intermediate_steps` après chaque appel, et en extraire les données pertinentes
Puis injecter ce contexte dans la requête suivante :

Conclusion

La ReAct Memory n’est pas conçue pour être persistée dans son ensemble — mais certains résultats extraits peuvent l’être, pour optimiser les performances et enrichir le contexte. Il suffit de les transférer dans une mémoire de travail (`state["context"]`) ou un outil à cache, selon l’architecture.
Mais il ne faut pas l’intégrer dans Conversation Memory , sous peine de joindre au prompt utilisateur des résultats hors contexte.