Engram — Neuroscience-Grounded Memory for AI Agents
Engram is a memory system for AI agents built on cognitive science models — not vector similarity. It implements the mechanisms that make biological memory work: activation decay (ACT-R), forgetting curves (Ebbinghaus), associative strengthening (Hebbian/STDP), sleep consolidation, and automatic insight synthesis from memory clusters.
The result: an agent that remembers — where frequently-used knowledge stays accessible, unused memories naturally fade, related concepts strengthen each other, and patterns across experiences surface as insights. All in a single SQLite file, pure Rust, zero external dependencies.
18,000+ lines of Rust · 309 tests · Zero unsafe
· ˚ ✦ . · ˚
· ENGRAM MEMORY ✦
˚ ╭─────────────────╮ ·
✦ ╱ ✦ strong memory ╲ ˚
· │ ··· ← recalled ← ···│ ·
│ · · · fading · · · · ·│
│ ░░░░░ forgotten ░░░░░░░│
╰──────────────────────────╯
↑ recall ↑ store
│ strengthens │ decays
╰──── ACT-R ───╯
From Neuroscience to Code
Engram isn't "inspired by" neuroscience — it implements specific, published models. Each mechanism maps directly to a biological counterpart:
┌──────────────────────────┐ ┌────────────────────────────────┐
│ 🧠 THE BRAIN │ │ ⚙️ ENGRAM │
├──────────────────────────┤ ├────────────────────────────────┤
│ │ │ │
│ Prefrontal cortex │ ──────▶ │ ACT-R activation model │
│ "What's relevant now?" │ │ frequency × recency scoring │
│ │ │ │
│ Hippocampal decay │ ──────▶ │ Ebbinghaus forgetting curves │
│ "Use it or lose it" │ │ exponential decay + spaced rep │
│ │ │ │
│ Synaptic plasticity │ ──────▶ │ Hebbian learning │
│ "Fire together, wire │ │ co-recall builds bidirectional │
│ together" │ │ associative links │
│ │ │ │
│ Spike-timing dependent │ ──────▶ │ STDP temporal ordering │
│ plasticity │ │ A before B → A causes B? │
│ "Order encodes causality"│ │ directional link strengthening │
│ │ │ │
│ Sleep consolidation │ ──────▶ │ Dual-trace consolidation │
│ Hippocampus → Neocortex │ │ "sleep" cycle: replay strong │
│ "Replay to remember" │ │ memories, decay weak ones │
│ │ │ │
│ Synaptic homeostasis │ ──────▶ │ Homeostatic scaling │
│ (Turrigiano 2008) │ │ bounded link strength, │
│ "Keep the network stable"│ │ adaptive thresholds │
│ │ │ │
│ Emotional tagging │ ──────▶ │ Emotional bus │
│ Amygdala modulation │ │ per-domain valence tracking, │
│ "Feelings color memory" │ │ drive alignment scoring │
│ │ │ │
│ Insight / "Aha!" moments │ ──────▶ │ Synthesis engine │
│ Default mode network │ │ cluster → gate → generate → │
│ "Connections emerge" │ │ provenance-tracked insights │
└──────────────────────────┘ └────────────────────────────────┘
The Life of a Memory
┌──────────┐
│ Input │ "Rust 1.75 added async traits"
└────┬─────┘
│
┌────────▼────────┐
│ Store & Index │ embed + FTS5 + entity extract
└────────┬────────┘ + type classify (factual)
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Activate │ │ Forget │ │ Link │
│ (ACT-R) │ │(Ebbinghaus)│ │ (Hebbian) │
│ │ │ │ │ │
│ recalled │ │ not used │ │ co-recalled│
│ 3x today → │ │ for weeks →│ │ with "Rust │
│ activation │ │ activation │ │ async" → │
│ ▲▲▲ │ │ ▽▽▽ │ │ link ▲▲ │
└──────┬─────┘ └──────┬─────┘ └──────┬─────┘
│ │ │
└───────────────┼───────────────┘
│
┌────────▼────────┐
│ Consolidation │ "sleep" cycle
│ (dual-trace) │ strong → long-term ✓
│ │ weak → decay further ✗
└────────┬────────┘
│
┌─────────────┼─────────────┐
▼ ▼
┌────────────────┐ ┌────────────────┐
│ Long-term │ │ Synthesize │
│ Memory │ │ │
│ survives │ │ cluster with │
│ indefinitely │ │ related → │
└────────────────┘ │ "Aha!" insight│
└────────────────┘
Why Not Just a Vector DB?
| Vector DB | Engram | |
|---|---|---|
| Store | Embed + insert | Embed + insert + extract entities + type-classify |
| Retrieve | Cosine similarity | 3-signal fusion: FTS5 + vector + ACT-R activation |
| Frequently used memories | Same score every time | Stronger — ACT-R boosts by access pattern |
| Unused memories | Same score forever | Fade — Ebbinghaus exponential decay |
| Related memories | Independent | Strengthen each other — Hebbian + STDP |
| Over time | Database grows forever | Consolidation — "sleep" prunes weak, keeps strong |
| Patterns across memories | You write the code | Automatic — synthesis engine with provenance |
| Emotional context | None | Per-domain valence tracking |
Quick Start
use ;
// 1. Create memory (just a file path — no services needed)
let mut mem = new?;
// 2. Store
mem.add?;
// 3. Recall (hybrid: FTS + vector + ACT-R activation)
let results = mem.recall?;
That's it. No Docker, no Redis, no API keys. Just a .db file.
With LLM Extraction
use ;
let mut mem = new?;
// Use local Ollama for extraction
mem.set_extractor;
// Or Anthropic Claude
// mem.set_extractor(Box::new(AnthropicExtractor::new("sk-ant-...", false)));
// Raw text → automatically extracted as structured facts
mem.add?;
With Emotional Bus
use ;
let bus = new;
// Track emotional valence per domain
bus.record_emotion?;
bus.record_emotion?;
// Get trends → coding: net +0.5, trending positive
let trends = bus.get_trends?;
// Drive alignment — scores how well content aligns with agent's goals
let drives = vec!;
let identity = Identity ;
let score = bus.score_alignment?;
With Synthesis Engine
use ;
let settings = default;
// Discover clusters → gate-check → generate insights → track provenance
let report = mem.synthesize?;
for insight in &report.insights
// Undo a synthesis if the insight was wrong
mem.undo_synthesis?;
🔍 Hybrid Search
Three signals fused with configurable weights:
Final Score = w_fts × FTS5_score + w_vec × cosine_sim + w_actr × activation
(15%) (60%) (25%)
- FTS5: BM25 ranking + jieba-rs CJK tokenization — Chinese, Japanese, Korean work out of the box
- Vector: Cosine similarity via Nomic, Ollama, or any OpenAI-compatible endpoint
- ACT-R: Biases toward memories that are currently relevant, not just semantically similar
🎯 Confidence Scoring
Two-dimensional: "how relevant?" and "how reliable?" are different questions:
- Retrieval Salience: Search score + activation + recency
- Content Reliability: Access count + corroboration + consistency
- Labels:
high/medium/low/uncertain
🧩 Synthesis Engine (3,500+ lines)
Memories → Cluster Discovery → Gate Check → LLM Insight → Provenance → Store
(4-signal) (quality) (templated) (auditable)
- Clustering — 4 signals: Hebbian weight, entity Jaccard, embedding cosine, temporal proximity
- Gate — Minimum cluster size, diversity, density, temporal spread
- Insight Generation — Type-aware LLM prompts (factual patterns, episodic threads, causal chains)
- Provenance — Full audit trail. Insights are reversible (
UndoSynthesis)
💚 Emotional Bus (2,500+ lines)
- Emotional Accumulator — Per-domain valence over time. Detects negative trends → suggests SOUL.md updates
- Drive Alignment — Cross-language embedding scoring (Chinese SOUL + English content)
- Behavior Feedback — Action success/failure rate tracking
- Subscriptions — Cross-agent notification on high-importance memories
⚖️ Synaptic Homeostasis
- Forgetting as feature — Ebbinghaus decay = garbage collection
- Consolidation threshold — Rising bar as memory count grows
- Hebbian normalization — Bounded link strength prevents runaway reinforcement
- Synthesis pruning — Insight preserves information; sources can safely decay
How Engram Compares
| Engram | Mem0 | Zep | Letta | |
|---|---|---|---|---|
| Core approach | Cognitive science models | Vector + graph | Vector + knowledge graph | LLM OS / stateful agents |
| Forgetting | ✅ Ebbinghaus curves | ❌ | ❌ | ❌ |
| Activation modeling | ✅ ACT-R | ❌ | ❌ | ❌ |
| Associative learning | ✅ Hebbian + STDP | ❌ | Partial (graph) | ❌ |
| Consolidation | ✅ Dual-trace | ❌ | ❌ | ❌ |
| Insight synthesis | ✅ Cluster → gate → prove | ❌ | ❌ | ❌ |
| Emotional tracking | ✅ Per-domain | ❌ | ❌ | ❌ |
| Search | FTS5 + vector + ACT-R | Vector + graph | Vector + MMR | Vector |
| Embeddings required? | Optional | Required | Required | Required |
| Infrastructure | SQLite only | Redis/Postgres + API | Postgres + API | Postgres + API |
| Language | Rust | Python | Python | Python |
🏗️ Architecture
┌─────────────────────┐
│ Agent / LLM │
└─────────┬───────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Memory │ │ Emotional │ │ Session │
│ (core) │ │ Bus │ │ Working M. │
└─────┬─────┘ └─────┬─────┘ └───────────┘
│ │
┌────────┴────────┐ │
▼ ▼ ▼
┌──────────┐ ┌───────────────────┐
│ Hybrid │ │ Synthesis Engine │
│ Search │ │ cluster → gate │
│FTS+Vec+AR│ │ → insight → log │
└────┬─────┘ └───────────────────┘
│
┌────┴───────────────────────────┐
▼ ▼ ▼ ▼
┌──────┐ ┌────────┐ ┌────────┐ ┌────────┐
│ACT-R │ │Ebbing- │ │Hebbian │ │Embed- │
│decay │ │haus │ │+ STDP │ │dings │
└──────┘ └────────┘ └────────┘ └────────┘
│
▼
┌──────────┐
│ SQLite │
│(WAL mode) │
└──────────┘
Memory Types
| Type | Use Case | Example |
|---|---|---|
Factual |
Facts, knowledge | "Rust 1.75 introduced async fn in traits" |
Episodic |
Events, experiences | "Deployed v2.0 at 3am, broke prod" |
Procedural |
How-to, processes | "To deploy: cargo build --release, scp, restart" |
Relational |
People, connections | "potato prefers Rust over Python for systems" |
Emotional |
Feelings, reactions | "Frustrated by the third CI failure today" |
Opinion |
Preferences, views | "GraphQL is overengineered for most use cases" |
Causal |
Cause → effect | "Skipping tests → prod outage last Tuesday" |
Configuration
Agent Presets
use MemoryConfig;
let config = chatbot; // Slow decay, high replay
let config = task_agent; // Fast decay, low replay
let config = personal_assistant; // Very slow core decay
let config = researcher; // Minimal forgetting
Embedding Configuration
Embeddings are optional. Without them, search uses FTS5 + ACT-R only.
use EmbeddingConfig;
// Local Ollama (recommended for privacy)
let config = EmbeddingConfig ;
// Or any OpenAI-compatible endpoint
let config = EmbeddingConfig ;
Search Weight Tuning
use HybridSearchOpts;
let opts = HybridSearchOpts ;
Multi-Agent Architecture
Shared Memory with Namespaces
// Agent 1: coder
let mut coder_mem = new?;
// Agent 2: researcher
let mut research_mem = new?;
// CEO agent subscribes to all namespaces
let subs = new;
subs.subscribe?; // Only importance >= 0.7
subs.subscribe?;
// Check for new high-importance memories from other agents
let notifications = subs.check?;
For Sub-Agents (Zero-Config Sharing)
// Parent agent creates a memory instance for a sub-agent
// that shares the same DB but with its own namespace
let sub_mem = parent_mem.for_subagent_with_memory?;
Project Structure
src/
├── lib.rs # Public API surface
├── memory.rs # Core Memory struct — store, recall, consolidate
├── models/
│ ├── actr.rs # ACT-R activation (Anderson 1993)
│ ├── ebbinghaus.rs # Forgetting curves (Ebbinghaus 1885)
│ ├── hebbian.rs # Associative learning (Hebb 1949)
│ └── stdp.rs # Temporal ordering (Markram 1997)
├── hybrid_search.rs # 3-signal search fusion (FTS5 + vector + ACT-R)
├── confidence.rs # Two-dimensional confidence scoring
├── anomaly.rs # Z-score sliding-window anomaly detection
├── session_wm.rs # Working memory (Miller's Law, ~7 items)
├── entities.rs # Rule-based entity extraction (Aho-Corasick)
├── extractor.rs # LLM-based structured fact extraction
├── synthesis/
│ ├── engine.rs # Orchestration: cluster → gate → insight → provenance
│ ├── cluster.rs # 4-signal memory clustering
│ ├── gate.rs # Quality gate for synthesis candidates
│ ├── insight.rs # LLM prompt construction + output parsing
│ ├── provenance.rs # Audit trail for synthesized insights
│ └── types.rs # Synthesis type definitions
└── bus/
├── mod.rs # EmotionalBus core (SOUL integration)
├── mod_io.rs # Drive/Identity types, I/O
├── alignment.rs # Drive alignment scoring (cross-language)
├── accumulator.rs # Emotional valence tracking per domain
├── feedback.rs # Action success/failure rate tracking
└── subscriptions.rs # Cross-agent notification system
Design Philosophy
-
Grounded in science, not marketing. Every module maps to a published cognitive science model. ACT-R (Anderson 1993), Ebbinghaus (1885), Hebbian learning (Hebb 1949), STDP (Markram 1997), dual-trace consolidation (McClelland 1995).
-
Memory ≠ retrieval. Vector search answers "what's similar?" — memory answers "what's relevant right now?" The difference is activation, context, emotional state, and temporal dynamics.
-
Provenance is non-negotiable. Every synthesized insight records exactly which memories contributed. Insights can be audited and undone. No black-box "the AI said so."
-
Zero deployment dependencies. SQLite (bundled), pure Rust. No external database, no Docker, no Redis. Copy the binary and the .db file — done.
-
Embeddings are optional. Works without any embedding provider (FTS5 + ACT-R). Add embeddings for semantic search, but cognitive models work independently.
License
AGPL-3.0-or-later. See LICENSE for details.
Citation