La recherche en IA te passionne ?
Les papers et avancées qui comptent, expliqués simplement, chaque soir. Gratuit.
Inclus dès l'inscription : notre sélection des meilleurs guides & comparatifs IA.
Choisis ton rythme
Gratuit · Pas de spam · Désabonnement en 1 clic
La persistance problématique des mémoires IA
Dans le domaine de l'intelligence artificielle, la gestion de la mémoire est souvent perçue comme un simple problème de stockage et de récupération. Cependant, cette approche peut entraîner des dysfonctionnements inattendus. Par exemple, un assistant IA a conservé une mémoire avec un score d'importance de 8/10 concernant une enquête sur Bun.js, un projet qui n'a jamais été poursuivi. Cette mémoire est restée active pendant six mois, influençant les recommandations de l'IA malgré son obsolescence.
Ce cas illustre un problème fondamental : les systèmes de mémoire IA actuels ne sont pas conçus pour gérer l'évolution des informations. Ils se contentent de stocker et de récupérer des données, sans tenir compte des changements de contexte ou de la pertinence des informations au fil du temps.
Nick Lawson a écrit un excellent article sur TDS où il décrit comment il a mis en œuvre un système de mémoire IA. Son architecture de stockage et de récupération est particulièrement bien pensée, mais elle soulève des questions sur la gestion des mémoires au fil du temps. Quand une mémoire devrait-elle disparaître ? Quelle mémoire est plus fiable qu'une autre ? Combien de mémoires qui se chevauchent devraient être combinées en une seule ?
Les limites des systèmes actuels
Les systèmes de mémoire IA traditionnels fonctionnent sur un modèle en deux étapes : écrire et lire. Cela peut suffire pour des tâches simples, mais devient problématique pour des applications nécessitant une fiabilité sur le long terme. Une mémoire enregistrée en début de projet peut rester prioritaire des semaines plus tard, même si la décision initiale a été révisée.
Ce manque de mise à jour dynamique conduit à des situations où l'IA s'appuie sur des données obsolètes, compromettant ainsi la qualité des décisions prises. Le véritable défi réside dans la capacité à oublier ou à mettre à jour les informations devenues non pertinentes.
À quoi cela ressemble-t-il concrètement ? Une mémoire que vous avez écrite au cours de la première semaine reste, huit semaines plus tard, aussi fraîche et prioritaire que le jour où vous l'avez créée, même si la décision que vous avez prise a été inversée deux semaines auparavant. L'autre mémoire, qui contredit votre décision précédente, a été rangée sans cérémonie et n'a tout simplement jamais eu le temps de devenir une priorité car elle n'a pas reçu suffisamment d'accès pour se hisser dans la file d'attente.
Ainsi, sans hésitation, votre assistant sort une décision que vous avez annulée. Ce n'est qu'à la troisième tentative que vous réalisez enfin que votre assistant s'est appuyé sur des informations obsolètes tout le temps. Le problème n'est pas de se souvenir, c'est de ne pas savoir laisser aller.
Vers une mémoire IA plus humaine
L'objectif est de développer une mémoire IA qui fonctionne plus comme un cerveau humain que comme une base de données. Cela implique d'intégrer des mécanismes de dégradation et de remplacement des mémoires. Par exemple, chaque mémoire pourrait être associée à un decay_score qui diminue avec le temps, en fonction de son utilisation.
Certaines mémoires ne sont pas très fiables dès le départ. D'autres expirent après une certaine période. Le cerveau gère tout cela automatiquement et sans que vous n'ayez à faire quoi que ce soit. C'était mon objectif.
La Fondation (Promis, c'est bref)
Faisons un rapide point de contexte. Plutôt que d'encoder vos mémoires et d'exécuter des recherches de similarité cosinus, vous les conservez en texte brut dans une base de données SQLite, que le LLM peut consulter pour un index concis à chaque demande. Il n'est pas nécessaire d'avoir un processus d'embedding, une API tierce ou des fichiers supplémentaires. La compréhension linguistique du LLM effectue la tâche de récupération. Cela semble trop simple. Mais cela fonctionne en réalité étonnamment bien sur un plan personnel.
Mon schéma repose sur cela avec des champs de cycle de vie :
# memory_store.py
from datetime import datetime
from pathlib import Path
from contextlib import contextmanager
DB_PATH = Path("agent_memory.db")
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
with _db() as conn:
conn.execute("
CREATE TABLE IF NOT EXISTS memories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
content TEXT NOT NULL,
summary TEXT,
tags TEXT DEFAULT '[]',
-- Champs de cycle de vie — c'est ce que cet article ajoute
importance REAL DEFAULT 5.0,
confidence REAL DEFAULT 1.0,
access_count INTEGER DEFAULT 0,
decay_score REAL DEFAULT 1.0,
status TEXT DEFAULT 'active',
contradicted_by INTEGER REFERENCES memories(id),
created_at TEXT NOT NULL,
last_accessed TEXT,
expires_at TEXT
")
Les colonnes intéressantes sont celles que vous ne voyez pas dans un schéma de mémoire standard : confiance, decay_score, statut, contradicted_by, expires_at. Chacune répond à une question sur la santé d'une mémoire que « existe-t-elle ? » ne peut pas.
Le premier problème est assez simple : les anciennes mémoires ne se nettoient pas toutes seules. Chaque mémoire dans la base de données se voit attribuer un decay_score de 0 à 1. Il commence à 1.0 au moment de sa création et se dégrade avec le temps, en fonction de la dernière fois que la mémoire a été consultée.
Les mémoires que vous continuez à référencer restent fraîches. Tandis que les mémoires qui ne sont pas consultées pendant plusieurs mois s'effacent vers zéro. Une fois qu'elles tombent en dessous du seuil de pertinence, elles sont archivées, non supprimées, car s'effacer ne signifie pas qu'elles étaient fausses, juste plus utiles.
from datetime import datetime
from memory_store import _db, log_event
HALF_LIFE_DAYS = 30 # ajustez cela — 30 fonctionne bien pour la mémoire conversationnelle,
# poussez à 90+ si vous suivez des projets de longue durée
def _decay_score(last_accessed: str | None, created_at: str, access_count: int) -> float:
ref = last_accessed or created_at
days_idle = (datetime.now() - datetime.fromisoformat(ref)).days
# Décroissance exponentielle standard : e^(-ln2 * t / half_life)
# (En pratique, le score diminue de moitié tous les HALF_LIFE_DAYS.)
score = math.exp(-0.693 * days_idle / HALF_LIFE_DAYS)
# Les mémoires fréquemment consultées gagnent un petit bonus de fraîcheur.
# Limitez à 1.0 — cela n'est pas censé gonfler au-delà de frais.
return min(1.0, score + min(0.3, access_count * 0.03))
Détection de Contradiction
C'est la partie que personne ne construit et celle qui cause le plus de dommages lorsqu'elle est manquante. Prenons ce scénario : vous dites à l'IA que vous utilisez PostgreSQL. Puis, trois mois plus tard, vous migrez vers MySQL, en le mentionnant brièvement dans la conversation.
Maintenant, vous avez quatorze mémoires liées à PostgreSQL avec une grande importance, tandis que votre unique mémoire concernant MySQL a une faible importance. Ainsi, lorsque vous demandez des informations sur votre configuration de base de données six mois plus tard, l'IA dit avec confiance « vous utilisez PostgreSQL », et vous passez dix minutes confus avant de réaliser ce qui se passe.
J'ai rencontré cela moi-même. J'avais arrêté d'utiliser poetry et commencé à utiliser uv comme gestionnaire de dépendances, je l'ai mentionné une fois, sans déclencher un score d'importance élevé, et j'ai passé une semaine à me demander pourquoi l'assistant continuait à suggérer des commandes poetry. L'ancienne mémoire n'était pas fausse ; elle n'avait tout simplement pas été remplacée.
La solution : lorsque qu'une nouvelle mémoire est créée, vérifiez si elle contredit quelque chose déjà stocké et marquez activement les anciennes comme remplacées.
