Construire une mémoire personnalisée pour LLM : un guide complet depuis zéro
Construire une couche de mémoire personnalisée pour un modèle de langage (LLM) à partir de zéro est une démarche essentielle pour transformer un système conversationnel étatique en une interface capable de maintenir une continuité contextuelle au fil des sessions. Contrairement aux LLM classiques, qui n’ont pas de mémoire intégrée, une telle architecture permet au chatbot de se souvenir des préférences, des interactions passées et des informations personnelles des utilisateurs, offrant ainsi une expérience plus fluide et personnalisée. L’architecture proposée s’inspire du modèle Mem0 et repose sur quatre composants fondamentaux : extraction, embedding, récupération et maintenance. Chaque étape est optionnelle, ce qui permet d’éviter les surcoûts computationnels lorsque la mémoire n’est pas nécessaire. Le système repose sur des outils intelligents, contrôlés par un agent LLM qui décide, via un cycle de raisonnement et d’action (ReAct), s’il doit extraire, chercher, ajouter, mettre à jour ou supprimer des informations. L’extraction commence par la transformation des transcripts de conversation en faits atomiques, grâce à DSPy. Un modèle de signature définit les règles d’extraction : à partir d’un historique de messages, le LLM extrait des faits courts, indépendants et significatifs, comme « l’utilisateur préfère le thé » ou « l’utilisateur aime le football ». Ces faits sont ensuite encodés en vecteurs grâce à un modèle d’embedding comme text-embedding-3-small (dimension 64), pour optimiser vitesse et coût tout en conservant une bonne expressivité. Les vecteurs sont stockés dans une base de données vectorielle, ici QDrant, qui permet des recherches par similarité et des filtres hybrides (par exemple, par utilisateur ou par catégorie). Un index sur user_id garantit une récupération rapide des données spécifiques à chaque utilisateur. Lorsqu’un utilisateur pose une question, le système génère une requête contextuelle via un outil de recherche, appelé seulement si le LLM estime qu’il manque du contexte. Cette recherche est déclenchée automatiquement par l’agent ReAct, qui peut appeler plusieurs fois l’outil de recherche avant de produire une réponse. Le LLM décide également, via un flag save_memory, s’il faut enregistrer une nouvelle information issue de la conversation. La maintenance de la mémoire est cruciale : elle permet de corriger les incohérences (ex. : « l’utilisateur aime le thé » puis « l’utilisateur déteste le thé ») et d’éviter la duplication. Un second agent ReAct, doté d’outils pour ajouter, mettre à jour, supprimer ou ignorer des mémoires, analyse les nouveaux faits en regard de ceux existants. Par exemple, il peut supprimer un ancien fait et en insérer un nouveau, ou simplement ne rien faire si l’information est déjà présente. Cette architecture illustre parfaitement la gestion de la mémoire comme problème d’ingénierie du contexte. Elle met en œuvre des techniques clés : extraction structurée, résumé, recherche par similarité, post-traitement, appel d’outils agents, et gestion dynamique des données. Elle est particulièrement adaptée aux applications de chatbots personnalisés, de conseillers virtuels ou de assistants intelligents. En complément, des extensions possibles incluent l’utilisation de bases de données de graphe pour représenter des relations complexes, l’ajout de métadonnées pour des filtres précis, ou encore un système basé sur des fichiers (ex. : fichiers Markdown) pour une approche plus simple et transparente. Ce projet, disponible sur GitHub et accompagné d’une vidéo tutoriel, démontre que la mémoire dans les LLM n’est pas une fonctionnalité native, mais un système ingénieux à concevoir, où l’intelligence de l’agent et la précision du traitement du contexte sont au cœur de la réussite.
