Créez des agents qui n'oublient jamais

@akshay_pachaar
ANGLAISil y a 3 mois · 13 avr. 2026
625K
1.9K
305
46
4.1K

TL;DR

Une plongée technique au cœur des systèmes de mémoire pour agents IA, de l'évolution des simples listes vers le moteur graph-vector open-source de Cognee pour un raisonnement relationnel et persistant.

Une exploration de la mémoire d'un agent à partir des premiers principes : des listes Python aux fichiers Markdown, en passant par la recherche vectorielle, les hybrides graphe-vecteur, et enfin, une solution open-source propre pour tout cela.

Akshay 🚀 - inline image

Un LLM est apatride par conception. Chaque appel API repart de zéro. La « mémoire » que vous ressentez en discutant avec ChatGPT est une illusion créée par le renvoi de l'intégralité de l'historique de la conversation à chaque requête.

Cette astuce fonctionne pour les discussions informelles. Elle s'effondre dès que vous essayez de construire un véritable agent.

Voici 7 modes de défaillance qui apparaissent dès que vous sautez la mémoire :

  1. Amnésie contextuelle : l'agent demande des informations que vous lui avez déjà fournies
  2. Zéro personnalisation : chaque interaction semble générique
  3. Échec des tâches multi-étapes : l'état intermédiaire se perd silencieusement en cours de tâche
  4. Erreurs répétées : aucun rappel épisodique signifie les mêmes erreurs, pour toujours
  5. Aucune accumulation de connaissances : chaque session part de zéro
  6. Hallucination due aux lacunes : lorsque le contexte déborde, le modèle invente
  7. Effondrement de l'identité : pas de continuité, pas de confiance

La réponse évidente est « d'y mettre plus de contexte ». C'est pourquoi les fenêtres de 128 000 et 200 000 jetons semblent devoir tout résoudre.

Ce n'est pas le cas.

La précision chute de plus de 30 % lorsque des informations pertinentes se situent au milieu d'un long contexte. C'est l'effet bien documenté de « perte au milieu ».

Le contexte est un budget partagé : les invites système, les documents récupérés, l'historique des conversations et la sortie se battent tous pour les mêmes jetons.

Même à 100 000 jetons, l'absence de persistance, de priorisation et de saillance rend la longueur brute du contexte insuffisante.

Akshay 🚀 - inline image

La mémoire ne consiste pas à entasser plus de texte dans l'invite. Il s'agit de structurer ce dont l'agent se souvient afin qu'il puisse trouver ce qui est important.

Le cadre des sciences cognitives qui aide vraiment

La formulation de Lilian Weng en 2023 est devenue le cadre par défaut :

Agent = LLM + Mémoire + Planification + Utilisation d'outils.

Les quatre piliers d'égale importance.

Sa taxonomie emprunte aux sciences cognitives, où la mémoire humaine se divise en trois systèmes :

  • La mémoire sensorielle capture les entrées perceptuelles brutes et les conserve pendant une fraction de seconde. Seules les parties auxquelles vous prêtez attention sont transmises.
  • La mémoire de travail est l'endroit où se déroule la pensée active. Elle contient environ 7±2 éléments à la fois (découverte de Miller en 1956). Perdez votre concentration, et le contenu disparaît.
  • La mémoire à long terme est un stockage durable sans limite de capacité pratique. La récupération est le goulot d'étranglement : vous pouvez stocker des millions de choses et échouer à vous souvenir de celle dont vous avez besoin.

Chacune correspond directement à un composant dans les architectures d'agents modernes :

Akshay 🚀 - inline image

La mémoire à long terme se divise encore :

  • Épisodique : événements passés spécifiques (« mardi, le cluster PostgreSQL est tombé en panne »)
  • Sémantique : faits et concepts (« PostgreSQL est une base de données relationnelle »)
  • Procédurale : compétences et flux de travail (« lorsqu'un utilisateur demande un remboursement, vérifiez d'abord la date d'achat »)

Le pont entre l'épisodique et le sémantique est la consolidation de la mémoire : des événements spécifiques répétés se distillent en connaissances générales. Un agent qui remarque que « les utilisateurs préfèrent systématiquement les résumés exécutifs » à travers des dizaines d'interactions devrait transformer cela en une règle réutilisable. Sans consolidation, votre agent rejoue des événements individuels plutôt que d'apprendre d'eux.

Akshay 🚀 - inline image

L'agent minimal, et ce qui casse en premier

Enlevez les cadres, et un agent est une boucle : percevoir, penser, agir.

python
1class Agent:
2 """Agent AI minimal : percevoir, penser, agir"""
3 def __init__(self):
4 self.client = anthropic.Anthropic()
5 self.model = "claude-sonnet-4-20250514"
6
7 def run(self, user_input: str) -> str:
8 response = self.client.messages.create(
9 model=self.model,
10 max_tokens=1024,
11 messages=[{"role": "user", "content": user_input}],
12 )
13 return response.content[0].text

Dites-lui « J'ai 4 pommes », puis demandez « J'en ai mangé une, combien en reste-t-il ? » et il n'a aucune idée de quelles pommes vous parlez. Chaque appel existe en isolation.

Couche 1 : La liste Python

La première correction que tout le monde utilise :

python
1class Agent:
2 def __init__(self):
3 self.client = anthropic.Anthropic()
4 self.messages = [] # Toute la "mémoire" est une liste
5
6 def chat(self, user_input: str) -> str:
7 self.messages.append({"role": "user", "content": user_input})
8 response = self.client.messages.create(
9 model="claude-sonnet-4-20250514",
10 max_tokens=1024,
11 messages=self.messages, # L'historique complet est envoyé à chaque fois
12 )
13 reply = response.content[0].text
14 self.messages.append({"role": "assistant", "content": reply})
15 return reply

Les tours multiples fonctionnent maintenant. La question des pommes obtient une réponse correcte car la conversation complète est renvoyée à chaque appel.

Deux problèmes apparaissent rapidement :

  • La liste croît sans limite. Au tour 200 environ, vous atteignez le plafond du contexte et les messages les plus anciens sont silencieusement supprimés. Le nom de l'utilisateur du tour 1 disparaît bien avant la blague jetable d'hier. Aucune priorisation, juste un ordre chronologique strict.
  • Tout vit dans la RAM. Dès que le processus Python se termine, votre agent n'a aucune idée de qui vous êtes.

Couche 2 : Les fichiers Markdown pour la persistance

L'étape suivante consiste à écrire la mémoire sur le disque. Markdown est un choix naturel : lisible par l'homme, compatible Git, et l'agent peut le relire comme texte brut. Claude Code utilise exactement ce modèle avec les fichiers CLAUDE.md et MEMORY.md.

python
1class MarkdownMemoryAgent:
2 def __init__(self):
3 self.client = anthropic.Anthropic()
4 self.history_file = Path("memory/conversation_history.md")
5 self.facts_file = Path("memory/known_facts.md")
6
7 def save_to_disk(self, role: str, content: str) -> None:
8 with open(self.history_file, "a") as f:
9 f.write(f"### {role} à {datetime.now().isoformat()}\n{content}\n\n")
10
11 def load_history(self) -> str:
12 if self.history_file.exists():
13 return self.history_file.read_text()
14 return ""
15
16 def chat(self, user_input: str) -> str:
17 self.save_to_disk("user", user_input)
18 history = self.load_history()
19 response = self.client.messages.create(
20 model="claude-sonnet-4-20250514",
21 max_tokens=1024,
22 system=f"Conversation précédente :\n{history}",
23 messages=[{"role": "user", "content": user_input}],
24 )
25 reply = response.content[0].text
26 self.save_to_disk("assistant", reply)
27 return reply

La persistance est résolue. Redémarrez le script, et la conversation est toujours sur le disque. Vous pouvez également maintenir un fichier de faits séparé que l'agent extrait au fil du temps :

text
1- Le nom de l'utilisateur est Sarah
2- Sarah gère l'équipe backend chez Acme Corp
3- Acme Corp est une entreprise SaaS B2B
4- En train de migrer la base de données de production vers une nouvelle région AWS

Vous pouvez ouvrir le fichier dans n'importe quel éditeur, voir exactement ce que l'agent sait, et le corriger à la main. Vraiment utile pour le prototypage.

Avec 4 faits, cela fonctionne parfaitement. Chargez l'intégralité du fichier dans le contexte et le LLM répond à toute question sur Sarah, son entreprise ou son secteur.

Maintenant, avancez de trois mois. Votre agent a 2 000 faits extraits et 200 journaux de conversation. Cela représente plus de 500 000 jetons de markdown sur le disque, et votre fenêtre de contexte est de 128 000.

Vous ne pouvez plus tout charger. Vous devez récupérer sélectivement uniquement les faits pertinents pour la requête en cours. Avec des fichiers plats, votre seule option est la recherche par mot-clé :

python
1# L'utilisateur demande : "Quel est le statut de notre migration cloud ?"
2grep("migration cloud", facts_file)
3# Retourne : []
4# Le fait sur le disque dit "migration de la base de production vers une nouvelle région AWS."
5# Les mots "migration cloud" n'apparaissent nulle part.
6
7# L'utilisateur demande : "Quelle équipe s'occupe du travail sur la base de données ?"
8grep("équipe base de données", facts_file)
9# Retourne : []
10# Un fait dit que Sarah "gère l'équipe backend." Un autre dit que l'équipe
11# "migre la base de production." Mais aucune ligne ne contient
12# à la fois "base de données" et "équipe" ensemble.

À petite échelle, les fichiers Markdown fonctionnent. À échelle réelle, ils imposent une recherche par mot-clé, et les mots-clés ne peuvent pas gérer les synonymes, les paraphrases ou les connexions entre les faits.

L'information est sur le disque. Mais vous ne pouvez pas tout charger, et la recherche par mot-clé est trop fragile pour trouver les bonnes pièces.

Si vous avez utilisé OpenClaw, vous avez vu cela se produire. Il stocke la mémoire sous forme de fichiers de point de contrôle Markdown, et après des semaines d'utilisation quotidienne, les faits plus anciens disparaissent discrètement à mesure que le contexte s'accumule et se compacte. Le stockage est là. La récupération ne l'est pas.

Le stockage sans récupération intelligente est une bibliothèque sans catalogue.

Couche 3 : La recherche vectorielle et le mur qu'elle heurte

Ajoutez des embeddings. Découpez votre markdown, intégrez les morceaux, recherchez par similarité cosinus. Maintenant, « base de données » correspond à « PostgreSQL » car leurs vecteurs vivent proches dans l'espace d'embedding. Le problème des synonymes disparaît.

Puis vous heurtez un nouveau mur. Considérez ces trois faits dans votre base vectorielle :

text
1- "Alice est la responsable technique du projet Atlas"
2- "Le projet Atlas utilise PostgreSQL comme magasin de données principal"
3- "Le cluster PostgreSQL a subi une panne mardi"

L'utilisateur demande : « Le projet d'Alice a-t-il été affecté par la panne de mardi ? »

La requête mentionne Alice et la panne de mardi, donc la recherche vectorielle classe les premier et troisième faits en haut. Mais le pont critique, « Le projet Atlas utilise PostgreSQL », ne mentionne ni Alice ni mardi. C'est la pièce de liaison, et c'est celle qui ne remontera pas.

Chaque fait est un point isolé dans l'espace d'embedding. Le tissu conjonctif qui les relie est invisible pour les vecteurs.

Akshay 🚀 - inline image

Ce n'est pas un cas marginal. C'est la forme normale des questions du monde réel. La connaissance métier est intrinsèquement relationnelle : les personnes appartiennent à des équipes, les équipes possèdent des projets, les projets dépendent de systèmes, les systèmes ont des incidents. Toute question qui traverse deux sauts ou plus dépasse ce que la récupération vectorielle plate peut répondre.

La matrice des capacités

Chaque couche corrige la douleur précédente mais en révèle une plus profonde :

Akshay 🚀 - inline image

Vous avez besoin de persistance, de compréhension sémantique et de raisonnement relationnel dans une seule couche de mémoire.

Construire cela vous-même signifie assembler une base vectorielle, une base de graphes, un magasin relationnel, un extracteur d'entités, un pipeline de déduplication et un système de pondération des arêtes. Cela représente des semaines de travail d'infrastructure avant d'écrire une seule ligne de logique d'agent.

J'utilise une solution qui comble cette lacune proprement. Elle est entièrement open-source, gère les trois paradigmes de stockage sous un même toit, et vous pouvez la faire fonctionner en quelques minutes. Parlons de Cognee.

Cognee : trois magasins, un moteur, quatre appels

Cognee est un moteur de connaissance open-source conçu pour la mémoire des agents. Il combine la recherche vectorielle avec des graphes de connaissances et une couche de provenance relationnelle en un seul système.

L'ensemble de la surface API est de quatre appels asynchrones :

python
1import cognee
2
3await cognee.add("Votre document ici") # Ingérer n'importe quoi
4await cognee.cognify() # Construire le graphe de connaissances + embeddings
5await cognee.memify() # Auto-améliorer la mémoire
6await cognee.search("Votre requête") # Récupérer avec raisonnement

Derrière ces quatre appels se trouve une architecture à trois magasins.

Akshay 🚀 - inline image

Pourquoi trois magasins et pas un ?

Chaque magasin capture une dimension de la connaissance que les autres ne peuvent pas :

  • Magasin relationnel → provenance : d'où viennent les données, quand elles ont été ingérées, qui y a accès
  • Magasin vectoriel → sémantique : ce que le contenu signifie, à quoi il ressemble
  • Magasin de graphes → relations : comment les entités sont connectées, ce qui cause quoi, qui relève de qui

Aplatir l'un d'entre eux et vous perdez des informations qui comptent pour la précision de la récupération.

La pile par défaut est SQLite + LanceDB + Kuzu, entièrement intégrée et basée sur des fichiers. pip install cognee plus une clé API LLM et vous êtes opérationnel.

Pas de Docker, pas de services externes.

Pour la production, remplacez SQLite par Postgres, LanceDB par Qdrant/Pinecone/pgvector, et Kuzu par Neo4j/FalkorDB/Neptune.

Même API à quatre appels dans les deux cas.

Que fait réellement cognify ?

cognee.cognify() exécute un pipeline en plusieurs étapes qui convertit le texte brut en connaissances structurées et interconnectées :

  1. Classification des documents par type et domaine
  2. Vérification des permissions pour le contrôle d'accès multi-locataire
  3. Extraction de morceaux qui respecte la structure des paragraphes (pas des découpes de taille fixe)
  4. Extraction d'entités et de relations via LLM, avec déduplication automatique via le hachage du contenu
  5. Génération de résumés pour une récupération efficace
  6. Double indexation dans le magasin vectoriel (embeddings) et le magasin de graphes (arêtes)

L'étape de déduplication est plus importante qu'il n'y paraît. Si la même entité apparaît dans 50 documents, Cognee la fusionne en un seul nœud de graphe avec 50 arêtes entrantes. Votre agent ne voit plus « Alice » comme 50 inconnues différentes. Et le pipeline est incrémental par défaut : seuls les fichiers nouveaux ou mis à jour sont retraités.

Akshay 🚀 - inline image

Chaque nœud du graphe a un embedding correspondant. Cette double représentation est l'astuce centrale : entrez par les vecteurs (trouvez du contenu sémantiquement similaire) et sortez par le graphe (suivez les relations vers les entités connectées), ou l'inverse. C'est ce qui permet aux requêtes multi-sauts de fonctionner sans sacrifier la recherche sémantique.

Memify : une mémoire qui apprend

memify() est ce qui distingue Cognee de tous les outils « ingérer et rechercher ». Il exécute une passe d'optimisation inspirée du RL sur le graphe :

  • Renforcement des chemins utiles qui ont conduit à une bonne récupération
  • Élagage des nœuds obsolètes qui n'ont pas été touchés
  • Auto-ajustement des poids des arêtes basé sur l'utilisation réelle
  • Ajout de faits dérivés en identifiant les relations implicites

Le graphe d'un agent de support client renforce naturellement les chemins à travers les documents produits et les politiques de remboursement tout en laissant les arêtes RH rarement interrogées se dégrader. Le graphe développe son propre sens de la pertinence au fil du temps.

Akshay 🚀 - inline image

Quatorze modes de récupération

Cognee propose 14 modes de recherche. Ceux auxquels vous aurez réellement recours :

Akshay 🚀 - inline image

Construire un véritable agent avec la mémoire Cognee

Voici le modèle complet pour intégrer Cognee dans la boucle percevoir-penser-agir :

python
1import cognee
2from cognee import SearchType
3
4class CogneeMemoryAgent:
5 """Agent avec mémoire persistante hybride graphe-vecteur."""
6
7 def __init__(self, session_id: str = "default"):
8 self.llm_client = OpenAI()
9 self.session_id = session_id
10
11 async def ingest(self, text: str, dataset: str = "main"):
12 await cognee.add(text, dataset)
13 await cognee.cognify([dataset])
14
15 async def recall(self, query: str) -> str:
16 results = await cognee.search(
17 query_text=query,
18 query_type=SearchType.GRAPH_COMPLETION,
19 session_id=self.session_id,
20 )
21 return results[0] if results else ""
22
23 async def chat(self, user_input: str) -> str:
24 context = await self.recall(user_input)
25 messages = [
26 {"role": "system", "content": "Vous êtes utile. Utilisez le contexte mémoire."},
27 {"role": "system", "content": f"Contexte mémoire :\n{context}"},
28 {"role": "user", "content": user_input},
29 ]
30 response = self.llm_client.chat.completions.create(
31 model="gpt-4o-mini", messages=messages
32 )
33 reply = response.choices[0].message.content
34 await cognee.add(
35 f"Utilisateur : {user_input}\nAssistant : {reply}",
36 "conversations"
37 )
38 await cognee.cognify(["conversations"])
39 return reply

Le cycle mémoire : ingérer, extraire, stocker, récupérer, répondre, stocker à nouveau. Chaque tour enrichit le graphe de connaissances, et le traitement incrémental signifie que vous ne payez que pour indexer le nouveau contenu.

La mémoire de session gère automatiquement la résolution des pronoms :

python
1await cognee.search(query_text="Où vit Alice ?", session_id="conv_1")
2await cognee.search(query_text="Que fait-elle comme travail ?", session_id="conv_1")
3# "elle" est résolu en Alice à partir du contexte de session

La multi-location est intégrée au niveau du graphe avec des permissions par ensemble de données (lecture, écriture, suppression, partage). Pas de séparation par espace de noms, une isolation réelle au niveau du graphe.

La voie pratique à suivre

Si vous construisez un agent aujourd'hui, la vraie question de départ est : « De quoi mon agent a-t-il besoin de se souvenir, et à quel genre de questions répondra-t-il ? »

Si vos requêtes n'ont besoin que d'une recherche de similarité (« trouver des conversations similaires à celle-ci »), la mémoire vectorielle seule fonctionne. Dès que les requêtes traversent les frontières des entités (« Le projet d'Alice a-t-il été affecté par la panne de mardi ? »), vous avez besoin d'un parcours de graphe.

Vous pouvez connecter vous-même des magasins vectoriels, de graphes et relationnels séparés. Les équipes qui suivent cette voie brûlent généralement des semaines sur l'infrastructure pour une couche mémoire qui n'apprend toujours pas de sa propre utilisation.

Cognee réduit cela à quatre appels API. Les valeurs par défaut intégrées vous permettent de démarrer en quelques minutes. Les backends interchangeables (Postgres, Qdrant, Neo4j) vous amènent en production sans modifier le code de votre agent.

L'intelligence nécessite de la structure, pas seulement du stockage. Les trois paradigmes de stockage (relationnel, vectoriel, graphe) ne sont pas des options concurrentes. Ce sont des couches complémentaires du même système de mémoire. Les traiter comme telles est ce qui transforme un simple wrapper LLM apatride en quelque chose qui apprend vraiment.

Quelle est la prochaine chose que vous voudriez que votre agent se souvienne demain et qu'il a oubliée aujourd'hui ? Commencez par là.

👉 Découvrez Cognee sur GitHub →, donnez-lui une étoile, et essayez de l'intégrer dans votre prochain agent.

Quatre appels asynchrones, un pip install, et vous êtes opérationnel.

C'est tout !

Si vous avez aimé lire cet article :

Retrouvez-moi → @akshay_pachaar ✔️

Chaque jour, je partage des tutoriels et des idées sur l'IA, le Machine Learning et les meilleures pratiques de codage « vibe ».

Enregistrer en un clic

Lire les articles viraux en profondeur avec l’IA de YouMind

Enregistrez la source, posez des questions ciblées, résumez l’argument et transformez un article viral en notes réutilisables dans un seul espace de travail IA.

Découvrir YouMind
Pour les créateurs

Transformez votre Markdown en un article 𝕏 impeccable

Quand vous publiez vos propres textes longs, la mise en forme 𝕏 des images, tableaux et blocs de code est pénible. YouMind transforme un brouillon Markdown complet en un article 𝕏 impeccable, prêt à publier.

Essayer Markdown vers 𝕏

D'autres patterns à décoder

Articles viraux récents

Explorer plus d'articles viraux