Une mémoire persistante inspirée de la biologie
pour l'orchestration d'agents IA
01 — Le problème d'amnésie
Valora orchestre 11 agents IA spécialisés à travers des pipelines multi-étapes. Chacun est capable. Mais dès qu'une session se termine, tout ce qui a été appris disparaît.
Erreurs répétées
Un agent signale le même anti-pattern au sprint 1, au sprint 5, au sprint 12. À chaque fois, une découverte fraîche.
Motifs redécouverts
Des conventions émergent dans la base de code. Les agents les reconstituent à chaque exécution au lieu de capitaliser sur les connaissances accumulées.
Décisions perdues
L'équipe choisit une direction architecturale. Les agents proposent des alternatives déjà rejetées. Le répertoire knowledge-base/ était vide.
02 — Inspiration neuroscientifique
Sans répétition mentale, les connexions nouvellement formées dans le cerveau sont soumises à un processus d'oubli qui, suivant une courbe régulière, est le plus rapide immédiatement après l'apprentissage.Hermann Ebbinghaus — Über das Gedächtnis, 1885
02 — Courbe de l'oubli
Chaque catégorie de mémoire a une demi-vie calibrée à sa nature. Les observations s'estompent vite. Les motifs persistent. Les décisions survivent aux deux.
strength = 0.5^(elapsed / halfLife)
Neurosciences
Courbe de l'oubli d'Ebbinghaus
La force mémorielle décroît exponentiellement sans renforcement.
Répétition espacée
Récupérer un souvenir le renforce, repoussant la courbe de déclin vers le futur.
Amplification des erreurs (amygdale)
Les erreurs sont marquées d'une durabilité accrue. Nous nous souvenons des gênes plus longtemps que des anecdotes.
Consolidation hippocampique
Les souvenirs épisodiques se condensent en connaissances sémantiques durant les périodes d'activité réduite (le sommeil).
v1 — Équivalent Valora
strength = 0.5^(t / halfLife)
La spécification prise directement d'Ebbinghaus. Mathématiques pures, zéro abstraction.
halfLife += accessCount × 2d
Chaque récupération ajoute 2 jours à la demi-vie effective. Les motifs fréquemment interrogés persistent.
isError → halfLife × 2
Les entrées d'erreur reçoivent le double de la demi-vie de base. Les leçons difficiles survivent aux observations routinières.
valora consolidate
La fusion par similarité de Jaccard élève les observations en motifs sémantiques durables.
03 — Architecture v1
Toute la mémoire réside dans .valora/memory/ — ignoré par git par défaut, par projet, aucune infrastructure requise.
03 — Le moteur de déclin
export function computeStrength(referenceAt: string, halfLifeDays: number, now = Date.now()): number {
const elapsedDays = (now - new Date(referenceAt).getTime()) / MS_PER_DAY;
return Math.pow(0.5, elapsedDays / halfLifeDays); // injectable pour tests déterministes
}
export function computeEffectiveHalfLife(
base: number, accessCount: number, isError: boolean,
retrievalBoostDays = 2, errorMultiplier = 2
): number {
const b = isError ? base * errorMultiplier : base; // effet amygdale
return b + accessCount * retrievalBoostDays; // répétition espacée
}
03 — Entrée mémoire
Chaque entrée porte un niveau de confiance. Les agents pondèrent les mémoires en conséquence : les niveaux supérieurs l'emportent sur les niveaux inférieurs en cas de conflit.
type ConfidenceTier =
| 'verified' // ← confiance maximale
| 'observed'
| 'inferred'
| 'stale'; // ← jamais injectée
// Injection : verified → observed → inferred
// Les entrées périmées sont toujours exclues.
relatedPaths intersectent des fichiers modifiés depuis la dernière consolidation. Les décisions annulées deviennent automatiquement périmées.04 — Où v1 a échoué
v1 a fidèlement traduit Ebbinghaus. Mais la biologie n'est pas un classeur — le cerveau est un réseau, et le réseau est la mémoire.
Jaccard est trop grossier
Les synonymes ne se correspondent jamais. Les antonymes peuvent correspondre. Le choix des tags est arbitraire — deux mémoires sur le même concept avec des labels différents ne se consolideront jamais. L'ADR-011 reconnaissait explicitement cette faiblesse.
Les mémoires sont des îlots isolés
Aucun lien entre les entrées connexes. « Refonte du middleware auth » (decisions.json) et « format du token de session » (episodic.json) vivent dans des tableaux JSON séparés sans pointeur entre eux. Toute connexion existait uniquement dans la tête d'un développeur.
Aucun index hippocampique
Chaque rappel chargeait l'intégralité du seau, calculait la force de chaque entrée et triait. O(n) par requête, sans moyen structurel de passer les catégories non pertinentes. Le cerveau ne scanne pas tout son cortex pour se souvenir du petit-déjeuner.
05 — L'intuition du graphe
La règle de Donald Hebb (1949) décrit comment la force synaptique croît avec la co-activation — le même mécanisme que la potentialisation à long terme dans l'hippocampe.
Co-accès hebbien
Chaque paire co-récupérée incrémente co_access[otherId] dans le frontmatter. Les mémoires fréquemment associées développent des liens forts.
Activation par diffusion
Une requête active des graines cosinus-similaires. L'activation se propage ensuite sur les arêtes related et co_accessed, décroissant de γ=0,6 par saut.
Consolidation synaptique
Le regroupement cosinus (≥0,82) promeut les clusters épisodiques en mémoires sémantiques — le transfert cortical du sommeil biologique.
06 — Architecture v2
Chaque mémoire est un fichier .md avec frontmatter YAML et des liens wiki [[id|kind]]. Le coffre-fort s'ouvre dans Obsidian — aucun outil supplémentaire requis.
.valora/memory/
├── version
├── meta.json
├── embeddings.bin ← Float32Array
├── embeddings.index.json ← id → offset
├── episodic/
│ └── mem-abc123def456.md
├── semantic/
│ └── mem-xyz789pqr012.md
├── decisions/
│ └── mem-def456ghi789.md
└── .obsidian/ ← compat. Obsidian
---
id: mem-abc123def456
category: episodic
created_at: "2026-04-28T10:23:00Z"
last_accessed_at: "2026-04-30T09:10:00Z"
agent_role: code-reviewer
confidence: observed
tags: ["typescript", "testing"]
half_life_days: 7
access_count: 3
is_error: false
co_access: {"mem-xyz789pqr012": 2}
---
Found a flaky test in the auth suite — timeout
too short for the CI environment.
[[mem-xyz789pqr012|related]]
06 — Rappel
Le pipeline de rappel remplace les scans de seau par un parcours de graphe amorcé par les embeddings — puis renforce les paires co-récupérées.
nomic-embed-text. Retour lexical gracieux si aucun embedder configuré — aucun changement de chemin d'exécution.embeddings.bin (Float32Array). Top k=12 sélectionnés comme points de départ de l'activation.related et co_accessed jusqu'à profondeur 2. L'activation décroît de γ=0,6 par saut multiplié par le poids de l'arête.activation × decayStrength × confidenceWeight. Pondérations : vérifié=1,0 · observé=0,7 · inféré=0,4 · périmé=0,1.co_access[otherId] dans le frontmatter pour chaque paire co-récupérée — la mise à jour du poids synaptique.07 — Consolidation synaptique
valora consolidate — le transfert hippocampique du sommeil biologique. Les observations épisodiques se regroupent en motifs sémantiques durables.
related_paths intersectent des fichiers modifiés depuis la dernière consolidation sont déclassées en stale. Le code bouge ; les mémoires doivent suivre.semantic/*.md avec confidence inferred. Chaque membre reçoit un lien wiki [[centroïdeId|decays_from]].accessCount incrémenté et leur demi-vie prolongée.08 — Injection de contexte
Chaque invocation de pipeline prépend le bloc MÉMOIRE AGENT — construit par le rappel du coffre-fort, limité à 2 000 tokens, ordonné par niveau de confiance.
AGENT MEMORY · vault recall · 2 000 tok budget
──────────────────────────────────────────────────
[VERIFIED · 0.97] Integration tests must use
Testcontainers; mock-based integration tests
are forbidden. (recalled 8×)
[OBSERVED · 0.72] Auth middleware rewritten for
compliance, not tech debt — session tokens
stored differently. (recalled 3×)
[INFERRED · 0.51] Pattern: no-console lint
suppression is consistently followed by an
eslint-disable comment explanation. (cluster)
09 — Décisions de conception
Conservé de v1
Rejeté pour v2
10 — Résultats
$ valora consolidate
Élagage des entrées sous 0,05...
✓ élagué 3 entrées périmées
Invalidation Git des chemins modifiés...
✓ déclassé 2 → stale
Encodage des entrées épisodiques...
✓ encodé 47 / 47
Regroupement cosinus (seuil 0,82)...
✓ fusionné 4 clusters épisodiques → 4 sémantiques
Renforcement des survivants...
✓ renforcé 43 entrées épisodiques
consolidation terminée en 1,8s
Feuille de route
Fusion basée sur les embeddings
Livré en v2 — ANN cosinus + activation par diffusion.
Découverte de motifs
Analyse des clusters pour faire émerger les conventions implicites — les agents découvrent des règles jamais explicitement enregistrées.
valora memory reembed
Migrer les embeddings lors d'un changement de modèle sans toucher au contenu des mémoires.
Export Kuzu
Export analytique en lecture seule pour les requêtes et visualisations de graphe. Le coffre-fort reste l'autorité d'écriture.