Inspiration

A biologically-inspired stateful memory system for LLM agents. NMAFC gives conversational AI the ability to remember, forget, and prioritize information the way biological memory does — using exponential decay, spaced repetition, override suppression, and active pruning.

Unlike context-window stuffing or naive vector stores that grow without bound, NMAFC maintains a bounded, high-signal memory that improves with use. Frequently accessed facts become permanent. Contradicted facts are immediately suppressed. Stale information naturally decays away.

Why NMAFC

Problem Current Approaches NMAFC Solution
Context windows overflow Truncate oldest messages Hot RAM with bounded record count via cognitive decay
Contradictions persist Old facts coexist with new ones Override detection + gamma suppression (instant eviction)
Everything treated equally Flat vector stores Three-tier typing: CoreAnchor (permanent), ActiveContext (moderate decay), EphemeralState (aggressive decay)
No concept of importance Retrieval count ignored Spaced repetition — each retrieval strengthens retention (LTP)
Retrieval misses related facts Single-hop vector search Spreading Activation graph traversal (multi-hop entity linking)
No recoverability Mutable state only Dual-track: Hot RAM (fast, mutable) + Cold ROM (append-only event log, full rollback)
Expensive per-turn overhead Separate extraction + response calls Single LLM call with tool-use for simultaneous response + extraction

What it does

1. Three-Tier Memory Classification

Every extracted fact is classified by the LLM into one of three tiers, each with distinct decay behavior:

Tier Decay Rate (lambda) Half-life Examples
CoreAnchor 0.0 (never decays) Infinite Name, allergies, identity, relationships
ActiveContext 0.05 per turn ~14 turns Current goals, schedules, projects
EphemeralState 0.69 per turn ~1 turn Mood, passing comments, transient state

2. Cognitive Decay (Ebbinghaus Forgetting Curve)

Each memory's synaptic weight decays exponentially over time:

w(t) = w(t_0) * e^(-lambda * delta_t)

Where delta_t = current_turn - last_reinforced_turn and lambda is the tier-specific decay rate modified by the consolidation coefficient.

3. Spaced Repetition (Long-Term Potentiation)

When a memory is retrieved during a query, it receives LTP reinforcement:

  1. Weight resets to 1.0 (full strength)
  2. Consolidation index k increments
  3. Future decay rate slows: effective_lambda = lambda_base * e^(-eta * k) where eta = 0.15

A fact retrieved 10 times retains 80% weight after 20 turns vs. 37% for a never-retrieved fact. This naturally surfaces important information.

4. Override Detection & Suppression

When the LLM detects a contradicting fact (e.g., "I moved to Berlin" contradicts "I live in Paris"):

  1. New fact specifies overrides_entity pointing to the old record
  2. Old record's weight is multiplied by gamma = 0.1 (instant suppression)
  3. Next prune cycle evicts the old record (weight 0.1 <= prune threshold 0.1)

Zero hallucination for contradictions — suppressed facts cannot be retrieved.

5. Spreading Activation (Graph Traversal)

Retrieval goes beyond single-hop vector search:

  1. Hop 0: Vector similarity search returns top_k=10 results
  2. Hop 1: Each result's related_entities are fetched from Hot RAM
  3. Hop 2: Their related_entities are fetched (BFS continues to max_hops=2)

6. REM Sleep Consolidation

Every 5 turns (configurable), a consolidation pass runs:

  • Elevation: ActiveContext records with consolidation_index >= 10 are promoted to CoreAnchor (permanent protection). Frequently-accessed facts earn immortality.
  • Dead pointer cleanup: Removes related_entities references to entities that no longer exist in Hot RAM.

7. Dual-Track Storage

Layer Technology Remote Option Purpose Mutability
Hot RAM LanceDB (embedded vector DB) AWS S3 storage Fast retrieval, vector search, weight updates Mutable (decay, reinforce, delete)
Cold ROM SQLite (WAL mode, FTS5) Cockroach db PostgreSQL (tsvector + GIN) Complete event log, keyword fallback, rollback source Append-only

How we built it

                    ┌─────────────────────────────────────────────┐
                    │           NeuromorphicMemory                 │
                    │              (wrapper.py)                    │
                    └────────┬──────────┬──────────┬──────────────┘
                             │          │          │
                    ┌────────▼──┐  ┌────▼────┐  ┌─▼──────────────┐
                    │  Extract  │  │  Query  │  │    Engine       │
                    │  (LLM +   │  │  Router │  │  ┌───────────┐  │
                    │   Tool)   │  │         │  │  │   Decay   │  │
                    └───────────┘  │ Vector  │  │  │  Reinforce│  │
                                   │ Search  │  │  │   Prune   │  │
                                   │ + Graph │  │  │  Consol.  │  │
                                   │ + Cold  │  │  │  Rollback │  │
                                   │ Fallback│  │  └───────────┘  │
                                   └────┬────┘  └────────────────┘
                                        │
                         ┌──────────────┼──────────────┐
                         │              │              │
                    ┌────▼────┐    ┌────▼────┐    ┌───▼───┐
                    │ Hot RAM │    │Cold ROM │    │Embedder│
                    │(LanceDB)│    │(SQLite) │    │        │
                    └─────────┘    └─────────┘    └────────┘

Challenges we ran into

Designing the dual-track storage system (mutable Hot RAM + append-only Cold ROM) was the biggest architectural challenge. Getting the math right for the Ebbinghaus decay curves making sure the three tiers (CoreAnchor, ActiveContext, EphemeralState) decay at biologically-plausible rates while remaining tunable required extensive iterative testing. We also had to solve the override detection problem: when a user contradicts a previously stored fact, suppressing the old record immediately without false positives. Another major hurdle was building the Spreading Activation multi-hop retrieval system that traverses the entity graph up to 2 hops while staying performant at scale. Finally, running academic benchmarks (LoCoMo with 1986 QA pairs across 4 arms) taught us that naive neuromorphic memory without tuning actually underperforms RAG the tuned variant with adjusted lambda rates is what unlocked the breakthrough.

Accomplishments that we're proud of

  • Built a complete cognitive memory architecture grounded in neuroscience (Ebbinghaus forgetting curve, Long-Term Potentiation, synaptic pruning, REM consolidation) not just a vector store with a wrapper
  • Achieved within 2 points of full-context accuracy at 9x fewer context tokens (0.525 vs 0.545 judge accuracy) in our pilot benchmark
  • Designed a biologically-inspired 3-tier memory classification (CoreAnchor / ActiveContext / EphemeralState) with configurable decay rates that actually works
  • Shipped production-ready multi-tenancy with full isolation by agent + conversation
  • Built support for 10+ LLM providers (OpenAI, Anthropic, Bedrock, Azure, Groq, OpenRouter, Together, Ollama, LM Studio, vLLM) with a clean provider abstraction
  • Created a complete academic benchmark suite with LoCoMo + LongMemEval datasets, F1 + LLM-as-judge metrics, and ablation studies
  • Full rollback capability rebuild memory state from Cold ROM to any previous turn

What we learned

  • Memory management is not the same as RAG. Naive vector retrieval grows unbounded and degrades signal; bounded memory with decay and pruning maintains quality over time
  • The forgetting curve is surprisingly effective as a first-class memory primitive. Ephemeral facts naturally die, while important facts compound through reinforcement no manual TTL or expiry logic needed
  • The tuned variant (λ=0.005 for ActiveContext) outperforming both the default and raw RAG confirms that memory decay rates are critical hyperparameters, not afterthoughts
  • A single LLM call with tool-use for simultaneous response generation + memory extraction cuts latency and cost in half vs. two separate calls
  • Dual-track append-only Cold ROM is essential for trust and debuggability you can always reconstruct and audit what the system remembered

What's next for NMAFC

  • Procedural memory — extend beyond episodic/semantic to track learned procedures and skills across conversations
  • Emotional valence — attach sentiment scores to memories so emotionally significant facts decay slower
  • Cross-conversation knowledge transfer — allow agents to share relevant memories across isolated conversations (with consent scoping)
  • Streaming ingestion — real-time memory updates from live conversation streams instead of batch turns
  • Web UI — visual memory explorer showing the entity graph, decay curves, consolidation events, and suppression history
  • Additional benchmarks — expand evaluation to include MemoryBank and∞Bench datasets
  • REST API layer — wrap the library as a standalone service for teams that don't want to embed Python directly

Built With

Share this project:

Updates