2 points par GN⁺ 3 일 전 | 1 commentaires | Partager sur WhatsApp
  • Une couche de mémoire persistante qui maintient le contexte des conversations et des tâches même d’une session à l’autre, en stockant les observations brutes sous forme d’episodes puis en les accumulant en connaissances structurées
  • Une architecture indépendante du modèle qui permet de brancher Claude, GPT, des LLM locaux et des agents personnalisés sur la même couche mémoire, avec un stockage reposant sur PostgreSQL et pgvector
  • Un rôle différent du RAG : au lieu de se limiter à la recherche documentaire, le système accumule aussi au fil des conversations de nouveaux faits, relations, objectifs, échecs et hypothèses, et peut être utilisé avec le RAG
  • Des namespaces et des chemins hiérarchiques pour isoler les connaissances liées aux utilisateurs, aux projets et à l’auto-connaissance de l’agent, avec un pipeline de consolidation qui synthétise en continu facts, relationships, causal links, patterns et contradictions
  • Une intégration native MCP, un modèle de soi basé sur /self et même une boucle de recherche itérative pour transformer un agent sans mémoire, limité aux sessions, en un acteur de travail doté d’une continuité à long terme

Vue d’ensemble de Stash

  • Une couche de mémoire persistante placée entre les agents IA et le monde extérieur, qui leur permet de conserver le contexte précédent même quand la session change
  • Les observations brutes sont stockées comme des episodes, puis accumulées en connaissances structurées telles que facts, relationships, patterns, goals, failures et hypotheses
  • Le système ne remplace pas le modèle lui-même, mais renforce sa continuité, et il est conçu pour pouvoir être branché sur n’importe quel agent, qu’il s’agisse de Claude, GPT ou de modèles locaux
  • Le stockage repose sur PostgreSQL + pgvector
  • GitHub

Organisation de la mémoire

  • Les namespaces servent à séparer la mémoire liée aux utilisateurs, aux projets et à l’auto-connaissance de l’agent
  • Chaque namespace est structuré comme un chemin hiérarchique ; lire /projects inclut aussi les sous-chemins comme /projects/stash et /projects/cartona
  • Les écritures ne sont enregistrées que dans un namespace exact, afin d’éviter la contamination de mémoire
  • La mémoire liée aux utilisateurs, celle des projets et l’auto-connaissance sous /self restent bien séparées
  • Exemple de structure : /users/alice, /projects/restaurant-saas, /projects/mobile-app, /self/capabilities, /self/limits, /self/preferences

Différence avec le RAG

  • Le RAG est davantage une couche de recherche qui va chercher des contenus pertinents dans des documents, sans mémoriser ni apprendre de la conversation elle-même
  • Le RAG ne peut traiter que ce qui existe déjà dans les documents et ne peut pas créer de nouvelles connaissances à partir de la conversation
  • Le suivi des objectifs, la compréhension des intentions, la détection de contradictions dans le temps et le raisonnement sur les causes et les effets sont présentés comme étant hors du champ du RAG
  • Stash apprend automatiquement à partir des conversations, des décisions, des succès et des échecs, et construit progressivement un graphe de connaissances
  • La recherche documentaire et la mémoire d’expérience traitent de problèmes différents ; il est donc possible d’utiliser RAG et Stash ensemble

Ce qui le distingue des mémoires IA existantes

  • Claude.ai et ChatGPT disposent aussi d’une mémoire, mais cette fonction reste liée à leur propre plateforme et leur propre modèle
  • Stash fonctionne de manière indépendante du modèle et peut aussi être connecté à des modèles locaux ou privés
  • La propriété des données reste du côté de l’utilisateur, et le projet est proposé en open source
  • Il inclut notamment la consolidation en arrière-plan, le suivi des goals et de l’intention, l’apprentissage à partir des failures, le causal reasoning et un self-model de l’agent
  • Dans le tableau comparatif, ChatGPT Memory et Claude.ai Memory sont décrits comme un “notepad”, tandis que Stash est présenté comme un “mind”

Le problème visé

  • Les modèles IA actuels raisonnent bien, mais n’ont pas de mémoire entre les sessions, ce qui oblige l’utilisateur à réexpliquer à chaque fois son contexte personnel et celui du projet
  • Injecter à chaque fois un long historique de conversation dans le prompt est lent et coûteux, tout en restant limité par la taille de la fenêtre de contexte
  • Il manque un mécanisme de transmission des leçons apprises qui empêcherait de répéter lors d’une session suivante les tentatives déjà échouées
  • Les fonctions de mémoire ne sont proposées que comme des fonctions propriétaires sur certaines plateformes, si bien que les agents personnalisés ou les LLM locaux repartent sans contexte à chaque fois

Pipeline de consolidation

  • Un processus en arrière-plan synthétise continuellement l’expérience et transforme la mémoire brute en connaissances structurées
  • À l’étape Episodes, les observations sont stockées en append-only
  • À l’étape Facts, des groupes d’episodes sont synthétisés par un LLM
  • À l’étape Relationships, les relations entre entités présentes dans les facts sont extraites
  • À l’étape Causal Links, les paires cause-effet entre facts sont reliées
  • À l’étape Patterns, des motifs abstraits de plus haut niveau sont dérivés
  • À l’étape Contradictions, le système effectue de l’auto-correction et une confidence decay
  • Avec Goal Inference, il suit automatiquement les faits liés aux objectifs actifs et met en évidence l’avancement comme les conflits
  • Avec Failure Patterns, il détecte les erreurs répétées et les extrait comme de nouveaux faits afin de réduire la répétition des mêmes échecs
  • Avec Hypothesis Scan, de nouvelles preuves permettent de confirmer ou d’infirmer des hypothèses ouvertes sans intervention manuelle

Intégration MCP

  • Le système fonctionne de manière native avec MCP et peut être relié à Claude Desktop, Cursor, OpenCode, des agents personnalisés, des LLM locaux et d’autres clients MCP
  • Il peut être connecté sans SDK, ce qui permet d’utiliser la même couche mémoire partout, sans vendor lock-in
  • Il fournit au total 28 outils, couvrant notamment remember, recall, forget, init, mais aussi causal links, contradictions et hypotheses
  • ./stash mcp execute --with-consolidation permet de lancer à la fois le serveur MCP en stdio et la consolidation
  • ./stash mcp serve --port 8080 --with-consolidation permet de démarrer un serveur SSE pour des agents distants

Modèle de soi de l’agent

  • Lors de l’appel à init, une ossature de namespace /self est créée pour démarrer la construction du modèle de soi
  • /self/capabilities mémorise ce que l’agent sait bien faire afin de s’en servir pour planifier le travail
  • /self/limits stocke l’historique des échecs et les faiblesses afin d’éviter de répéter les mêmes erreurs
  • /self/preferences apprend les modes de fonctionnement les plus efficaces pour façonner progressivement le style de travail

Boucle d’apprentissage autonome

  • Une research loop lancée toutes les 5 minutes récupère le contexte courant à partir de la mémoire passée, choisit elle-même un sujet à étudier, crée de nouvelles connexions, reconsolide le tout puis s’arrête
  • À l’étape Orient, elle recharge le contexte passé, les objectifs actifs, les hypothèses ouvertes et les échecs passés
  • À l’étape Research, l’agent effectue une recherche web sur un sujet qu’il a lui-même choisi
  • À l’étape Think, il met en lumière les tensions, lacunes et contradictions dans ce qu’il sait actuellement
  • À l’étape Invent, il produit de nouveaux éléments comme des hypothèses, des patterns ou des découvertes
  • À l’étape Consolidate, le pipeline s’exécute pour synthétiser les episodes bruts en connaissances structurées
  • À l’étape Reflect + Sleep, il laisse un résumé de session, prépare le contexte pour l’exécution suivante, puis s’arrête
  • Voir le prompt de la boucle

Compatibilité modèles et infrastructure

  • La configuration suppose un seul provider utilisant une API compatible OpenAI à la fois pour l’embedding et le raisonnement
  • Le projet prend en charge les déploiements cloud, locaux et self-hosted, et indique ne pas imposer de vendor lock-in
  • Il est indiqué qu’OpenRouter est utilisé en local, avec un accès à des centaines de modèles via une seule clé API
  • Le système fonctionne aussi directement avec Ollama, ce qui permet une configuration de mémoire hors ligne avec des modèles locaux comme Qwen, Llama et Mistral
  • Des backends utilisant le format OpenAI API comme vLLM, LM Studio, llama.cpp server, Together AI et Groq sont également listés comme compatibles
  • Le modèle d’embedding par défaut est openai/text-embedding-3-small, avec STASH_VECTOR_DIM=1536 dans cette configuration
  • STASH_VECTOR_DIM ne peut être défini qu’avant le premier lancement ; le modifier après l’initialisation nécessite une réinitialisation complète de la base de données

Informations de déploiement et d’usage

  • Une configuration Docker Compose est fournie pour lancer ensemble Postgres, pgvector et Stash
  • La procédure d’exécution est présentée en trois étapes : cloner le dépôt, copier .env.example vers .env, configurer la clé API et les modèles, puis lancer docker compose up
  • Après le premier démarrage, on s’attend à voir Postgres + pgvector prêts, les migrations appliquées, le serveur MCP en attente et la consolidation en arrière-plan active
  • Le projet est publié sous licence Apache 2.0
  • GitHub Repository
  • alash3al.com

1 commentaires

 
GN⁺ 3 일 전
Avis Hacker News
  • J’ai cliqué en pensant qu’ils avaient enfin rendu portable quelque chose comme le système de mémoire de Claude.ai, mais ce n’est pas du tout ça.
    Ici, on a juste une approche store/remember, alors que ce que j’ai trouvé meilleur, c’est quand un modèle en arrière-plan résume l’historique de chat pour créer la mémoire.
    Dans ce cas, le modèle n’a pas besoin d’écrire lui-même la mémoire, et ça fonctionnait bien mieux ; donc présenter ça comme étant au niveau de Claude.ai me semble assez trompeur.
    J’essaie moi aussi de basculer vers quelque chose comme LibreChat, et je cherche sans arrêt un système de mémoire du même type, mais je n’en ai toujours pas trouvé ; à vrai dire, c’est presque la seule raison pour laquelle je reste encore sur Claude.ai.
    À noter que ce système n’existe que sur Claude.ai, pas dans Claude Code.

    • D’après le récent leak de Claude Code, il y avait quelque chose appelé autoDream, décrit ici comme un background memory consolidation engine : https://kuber.studio/blog/AI/Claude-Code's-Entire-Source-Code-Got-Leaked-via-a-Sourcemap-in-npm,-Let's-Talk-About-it
    • J’aimerais vraiment tester cette approche.
      Mon expérience a été exactement inverse : j’ai surtout construit https://github.com/flippyhead/ai-brain pour moi-même, et quelques amis l’utilisent aussi.
      Jusqu’ici, faire en sorte que l’IA retrouve les mémoires pertinentes via CLAUDE.md, puis réfléchisse à quand et comment les enregistrer, a plutôt bien marché.
      Cette méthode permet de structurer selon les priorités et de laisser aussi des notes pour l’avenir, donc ça me paraît assez différent d’une simple approche qui résume tout.
    • Moi, je préfère un rappel automatique qui fonctionne sans être visible pour l’agent.
      La création de mémoire via un tool call marche aussi plutôt bien, et créer automatiquement de la mémoire au moment de la compression du contexte me semble également correct.
      En revanche, si c’est généré automatiquement, il faut une consolidation asynchrone, et appeler ça du dreaming me paraît un peu exagéré.
      Mon implémentation est dans Elroy.bot, et j’ai résumé plusieurs approches ici : https://tombedor.dev/approaches-to-agent-memory/
    • Je me demande comment ils benchmarkent ça.
      Quand on extrait la mémoire en arrière-plan, le problème, c’est que ça se marie mal avec le prefix cache.
      Rien qu’avec un schéma simple en deux niveaux LOG.md (journal détaillé des tâches et enseignements) + MEMORY.md (éléments promus quand le journal est tronqué) + un stop hook exécuté à la fin de chaque tour, on peut déjà aller assez loin.
    • Le concept est assez intéressant.
      Ça donne l’impression d’avoir des assistants en coulisses derrière l’agent qui parle à l’utilisateur, qui écoutent la conversation, notent les faits importants ou vont chercher dans une base de données des informations pertinentes, puis interviennent en disant : cette mémoire X semble pertinente.
      Si les tokens étaient gratuits, ça semblerait facile, mais rendre ça efficace est un problème assez passionnant.
  • Les projets qui promettent quelque chose sans presque rien révéler de l’implémentation me paraissent toujours être un énorme signal d’alarme.
    En creusant un peu, on voit que c’est essentiellement une structure avec pg_vector, mcp, et deux fonctions recall/remember.
    Au final, c’est plus proche du RAG ; on peut toujours dire que la structure des données est importante, mais jusqu’ici, presque tous les systèmes de mémoire de ce type ont fonctionné à peu près de la même manière.
    Je n’ai encore vu aucun cas montrant que la recherche était meilleure qu’une simple recherche dans une vector DB.

    • Le site est beau, il est écrit memory dessus, et il suggère que même si les LLM sont nuls, ce produit résout magiquement le problème.
      Si ça marche vraiment, au fond ce n’est pas loin d’un vectordb joliment emballé.
  • Il y a déjà une review ici : https://zby.github.io/commonplace/agent-memory-systems/reviews/stash/
    Beaucoup d’autres LLM memory systems sont aussi rassemblés ici : https://zby.github.io/commonplace/agent-memory-systems/
    Et il a aussi résumé ce qu’il attend de ce genre de systèmes : https://zby.github.io/commonplace/notes/designing-agent-memory-systems/

  • Ces agent memory systems donnent l’impression d’être à la fois surconçus et sous-conçus, et ça ressemble pas mal à une impasse.
    J’ai du mal à imaginer qu’ils ne finissent pas rapidement par diverger de ce dont les modèles les plus récents ont besoin, puis par pourrir.
    Par exemple, parce qu’on a mis en place un paiement une fois, une mémoire du genre don't use stripe peut ensuite pousser plusieurs sessions à dériver vers le sujet du paiement.

    • Pire encore, l’auteur lui-même ne donne vraiment pas l’impression de l’avoir utilisé en conditions réelles.
      Ça ressemble à une memory layer totalement non prouvée, avec seulement un site marketing tape-à-l’œil et des promesses exagérées, sans véritable capture d’écran du produit.
    • Moi, je vois ça comme un problème d’information, et j’ai créé un petit utilitaire qui cherche justement à ne pas stocker la plupart des choses : https://github.com/skorokithakis/gnosis
      L’idée de base est simple : ce que le LLM sait déjà, il continuera à le savoir, donc je ne stocke pas ce que dit le LLM ; et pour tout ce qui concerne le code, ça peut rester dans le code et les commentaires.
      Mais il reste des choses qui ne relèvent ni de l’un ni de l’autre, et qui pourtant ne sont jamais capturées.
      Quand on construit quelque chose, il est souvent plus important de savoir ce qu’on a décidé de ne pas faire que ce qu’on a fait ; cet utilitaire capture à la fin de la session les alternatives rejetées et les raisons, puis les stocke comme system knowledge.
      En gros, je veux conserver des informations qu’on ne peut pas retrouver avec un simple grep dans le code, des choses qui sinon ne restent que dans la tête des collègues. Jusqu’ici, ça marche plutôt bien, mais c’est encore tôt.
    • J’utilise un système de mémoire sur mesure que j’ai développé moi-même, et j’évite ce problème en faisant de toutes les mémoires des espaces de recherche contextuels.
      Une mémoire comme don't use stripe n’entre dans le contexte que si le modèle reçoit un prompt lié au payment processing.
  • Je cherchais ce genre de chose depuis longtemps, et je suis content de voir que ce compte publie du logiciel depuis avant le boom des LLM.
    Par contre, j’aimerais que chaque projet inclue quelque chose comme un historique d’usage des LLM.
    J’aimerais savoir s’il a été généré avec des LLM, et si oui dans quelle mesure, à quelles étapes ils ont été utilisés, à quel point la sortie a été soigneusement relue, et si l’auteur estime que la qualité est au moins équivalente, voire meilleure, que s’il l’avait fait seul.
    Ce n’est pas pour soupçonner une personne en particulier ; j’aimerais que ce soit une information commune à tous les projets, et j’ai moi-même l’intention de faire pareil.

    • Franchement, ça sonne un peu entitled.
      Personne n’oblige qui que ce soit à utiliser ce projet ; il suffit de lire et d’examiner le code soi-même, puis de décider si on veut s’en servir ou non.
    • La question est légitime, mais je ne pense pas qu’on puisse se contenter d’une auto-déclaration de la personne concernée pour y répondre.
      Je doute qu’il y ait beaucoup de gens prêts à admettre honnêtement qu’ils n’ont presque pas réfléchi à la conception ni aux tests, et que la qualité du code n’est pas fameuse.
      En réalité, il faudrait peut-être un système tiers pour répondre à ce genre de question, même si, bien sûr, s’il est lui aussi basé sur un LLM, ça risque d’être assez subjectif.
    • Il existe énormément de façons différentes de produire du logiciel avec des LLM.
      En ce moment, je fais tourner la plupart de mes projets autour de plusieurs fichiers Markdown : j’utilise l’IA d’abord pour la recherche, la planification et le suivi de l’implémentation.
      Ensuite, je réalise l’implémentation progressivement selon le plan, avec des revues continues à chaque étape.
      Si on me demandait de documenter mon workflow, ces fichiers seraient précisément cette documentation.
      99 % du code est généré, mais je fais attention à ce qu’il le soit d’une manière qui me convient, et je trouve souvent que le résultat est meilleur que si je l’avais fait seul.
    • Je ne vois pas très bien pourquoi ce serait important.
      On peut faire du bon logiciel comme du mauvais, avec ou sans LLM.
      On ne demande pas à un charpentier s’il a utilisé un marteau ou un nail gun, ni lequel il a utilisé pour le toit ou pour la terrasse.
      S’il n’y a pas de confiance de départ, il faut soit vérifier la qualité soi-même, soit tout faire soi-même ; le reste relève surtout de l’espoir.
  • Je n’ai toujours pas trouvé de memory vraiment utile.
    D’un côté, certains trucs comme agents.md ne gardent qu’un résumé de haut niveau, ce qui n’aide pas vraiment pour des détails concrets, par exemple si tu modifies cet élément, il faut marquer cet autre élément comme brouillon.
    À l’inverse, les approches trop détaillées finissent soit par être ignorées à cause de l’excès de détails, soit par contaminer les changements d’un domaine fonctionnel avec les détails d’un autre.
    Au final, ce qui a le mieux marché jusqu’ici, c’est sans mémoire, en sélectionnant manuellement uniquement le contexte important pour la session ou le prompt en cours.

    • Le sujet de la mémoire m’intéresse beaucoup, mais au moins pour les outils de programmation, je ne trouve pas ça très utile.
      La source de vérité sur ce qu’un dépôt fait ou doit faire, c’est au final le dépôt lui-même.
      Ce dont tu parles ressemble plutôt à des consignes de revue de code, et ce genre de choses peut être injecté explicitement dans le contexte au moment où le changement a lieu.
      Comparés à ça, les systèmes de mémoire sont trop complexes et trop peu fiables.
    • Une wishlist pour ce type de système est ici : https://zby.github.io/commonplace/notes/designing-agent-memory-systems/
    • J’ai un ressenti similaire.
      Je me demande si, un jour, ces modèles auront un vrai continual learning.
      Ils sont déjà suffisamment intelligents, mais l’absence de vraie mémoire les rend pénibles à utiliser.
    • Les mémoires que Claude créait pour moi relevaient presque toutes du genre remember-to-not-forget, donc j’ai fini par désactiver la fonctionnalité.
  • Chez moi, quelques choses simples marchent assez bien, l’outil étant Codex.

    1. Une functional specification détaillée et toujours à jour
    2. Une base de code structurée en plusieurs projets
    3. Du code bien nommé et bien documenté. Les noms de classes, variables et fonctions doivent être explicites quant à leur rôle, même s’ils deviennent longs ou un peu ridicules, et ce genre de règle figure dans les guidelines de codage de Agent.md.
      Ma functional spec joue le rôle de Project.md pour l’agent.
      Et avant chaque revue de code agentique, je génère l’arborescence du répertoire du projet, puis je la fusionne avec la base de code dans un fichier unique en ajoutant un timestamp au nom du fichier.
      C’est étonnamment important, parce que ça réduit les cas où le LLM se réfère à une ancienne version, et c’est aussi pratique pour voir rapidement les diff sans avoir à envoyer git.
      Jusqu’ici, ce workflow simple a très bien fonctionné même sur de grosses bases de code complexes.
      Ce n’est pas très efficace en tokens, mais ça marche, tout simplement.
      Il n’est pas nécessaire de fusionner toute la base de code à chaque fois ; on peut exclure les projets déjà terminés, testés ou sans rapport avec le travail en cours.
      Malgré tout, je les garde dans la printed directory tree, afin que l’agent sache au moins qu’ils existent et puisse demander un fichier précis si besoin.
    • Approche intéressante.
      Je suis curieux de savoir comment tu fais cette fusion.
      Est-ce manuel, seulement sur les fichiers modifiés, ou un mélange des deux ?
  • La mémoire des LLM paraît bien en théorie, mais en pratique, plus elle grossit, plus ça devient aussi sale que de travailler sans mémoire.
    Comme dans l’exemple de la page d’accueil, dire continue à travailler sur mon projet suppose qu’en réalité on ne fait qu’un seul projet, ce qui est rarement le cas.
    On peut très bien avoir 5 ou 10 projets en mémoire, et chacun a sans doute eu du sens au moment où il a été stocké.
    Au final, il faut quand même repréciser quelque chose comme continue sur le projet sass, et en échange d’un peu de contexte supplémentaire, on remplit le contexte LLM et on paie en plus des appels MCP.

    • C’est vrai, mais là on parle d’une implémentation trop naive.
      Une implémentation bien faite pourrait peut-être dépasser ce genre de limites.
    • Dès qu’on commence à préciser explicitement quoi retenir, au fond ce n’est plus très différent de faire write/read des fichiers à l’IA.
  • Je me demande si ce n’est pas uniquement pour des vibecoders qui travaillent seuls.
    Quand on travaille avec de vraies personnes sur de vrais projets, ce système ne peut pas avoir la mémoire complète du projet, et moi non plus je ne l’ai pas.
    Dès qu’une autre PR est mergée, ce que j’avais en tête devient aussitôt obsolète, et ce qui m’importe, c’est surtout mon ticket.
    Du coup, j’en viens à penser que ce genre d’outil n’est peut-être pas destiné à ce type de travail collaboratif.

  • Maintenant que le coût de fabrication du logiciel est pratiquement tombé à presque zéro, je trouve étonnant qu’on essaie encore de vendre ce genre de chose avec un site marketing vibe-coded.
    Qui a le temps d’essayer ça, puis d’attendre des semaines ou des mois pour vérifier si ça marche vraiment ?
    Il n’y a nulle part sur le site la moindre preuve que ce soit meilleur que du RAG, ou même qu’un simple dossier de fichiers mémoire plus un grep.
    Et pourtant, il aligne les promesses extravagantes, avec en prime un scroll qui rame à 14 fps.
    Franchement, ça donne l’impression d’un truc codé en 24 heures, et ça me paraît très paresseux.