Why Agents Need Lessons, Not Just Memory: Inside causal-memory's Causal Design
causal-memory replaces flat fact recall with a causal graph of decision→outcome edges, using a hippocampal-inspired engine, Pearl's causal ladder, credit assignment via Q-value backprop, and governance checks to cut repeated mistakes by half in real use.
Four Structural Defects in Agent Memory
The author identifies four flaws in current agent memory: (1) context compression discards "why" — causal details drop to 45% after five compression rounds while a causal memory store outside the context window loses nothing; (2) traps repeat across sessions — a trap-world benchmark shows 67% repeat error rate without causal memory vs 33% with it; (3) memory is stuck on one machine — experience lives in a local directory, lost on device or personnel change; (4) memory silently degrades — spurious correlations, echo chambers, missing failures, and contradictory entries pollute retrieval.
Related Work Landscape
Major 2025–2026 approaches compared:
mem0 (arXiv:2504.19413): fact extraction with graph upgrade (Mem0g); 2026 shift to single-pass ADD-only extraction.
Zep / Graphiti (arXiv:2501.13956): temporal knowledge graphs with episode→entity/fact (bi-temporal validity)→community summary three-layer structure.
Letta / MemGPT (arXiv:2310.08560): OS-style two-tier memory (core/archival) with function-call swapping.
TencentDB Agent Memory (open-sourced 2026-05): four-layer distillation L0 raw dialogue → L1 atomic facts → L2 scenarios → L3 profiles; symbolic short-term memory cuts token use ~61%.
Anthropic memory tool + Dreaming (2026-05): filesystem storage plus background consolidation; Harvey reports 6× task completion gains.
These focus on fact recall; benchmarks like LoCoMo and LongMemEval test fact retrieval, not learning from failure. Zep officially challenged mem0's LoCoMo scores (dataset only 16k–26k tokens, no knowledge update test, role confusion in eval). Academic work addresses causal abstraction and utility-weighted retrieval: CLIN (ICLR 2024) extracts causal abstractions from action→observation→reward; MemRL (arXiv:2601.03192) adds Q-value utility ranking to avoid noisy semantic matches; HeLa-Mem (ACL 2026, arXiv:2604.16839) introduces Hebbian learning for co-activation strengthening. HeLa-Mem handles the "excitatory" side; causal-memory adds the "inhibitory" side — knowing what prevents recurrence.
Core Design
3.1 Seven Edge Types with Spread Coefficients
All memories become edges in a graph with seven types, each with a spread_coeff for activation diffusion (defined in hippocampus/types.rs). prevented is the only negative coefficient — implementing the brain's inhibitory signal. co_occurrence captures "mechanism unknown, suspected common cause" observations; it is explicitly excluded from forward causal traversal SQL so unverified associations never masquerade as causal predictions. prevented edges use three implementation details: absolute-value max merging (so negative activation can win over positive), fan-out exemption (causal edges don't dilute by node degree), and an ablation switch disable_inhibition() proving warnings vanish without negative diffusion.
3.2 Hippocampal Engine: Neuroscience to Engineering
The engine maps hippocampal subregions to components ( hippocampus/mod.rs):
DG (dentate gyrus) → SimHash pattern separation: 128-bit SimHash, Hamming ≤2 treats near-duplicates as same, preventing redundant recording.
CA3 → K-hop spreading activation: forward CSR graph (decision→outcome) plus reverse CSR for attribution; default decay 0.7, max depth 5; seed activation weighted by Q-value (0.5 + 0.5·Q). CSR+SoA layout with pre-multiplied spread coefficients; new edges use patch overlay merged on rebuild.
CA1 → novelty detection: before writing, internally diffuse from decision to predict outcome; only record if surprise (similarity gap) exceeds threshold — "surprise is the most valuable experience." Hybrid gating sends only borderline cases to LLM for semantic judgment.
SWR (sharp-wave ripples) → offline consolidation: immutable pattern aligned with Anthropic Dreams — all changes (LTP ×1.05 capped at 2.0, LTD decay, triple-criterion GC: weak & zero replay & 30-day dormancy) computed as deltas on a clone, original graph untouched, full audit log kept.
3.3 Causal Three Layers: Climbing Pearl's Ladder
Tools map to Pearl's rungs:
R1 Association — search_causal: computes P(outcome | similar decisions) from recorded edges.
R2 Intervention — intervention_query: experience-based do-effect via forward simulation along similar historical actions, stratified by task_tag, with Simpson's paradox warning.
R3 Counterfactual — counterfactual_query: comparative A/B of actual outcome distributions of two candidate decisions.
Counterfactuals avoid full abduction (which drops scores 25–40 points per arXiv:2510.01539) by: (1) recording abduction raw material — record_decision takes a context parameter capturing environment, constraints, parameters; same task_tag + context fingerprint = natural experiment stored in decision_forks; fork pairs rank above distributional evidence. (2) Every counterfactual judgment logs a pending_predictions entry; when reality matches a pending option, it auto-settles correctness — prediction_report yields accuracy dashboards per method/domain. (3) Insufficient evidence triggers explicit "unidentifiable, falling back to comparative" — micro-SCM estimation (noisy-OR + EM) only triggers after 30 fork pairs in a domain.
R2 intervention acts as pre-action safety check. A synthetic calibration with ground truth shows 100% accuracy on true-danger, true-safe, and prevented scenarios; "confounded disguise" cases initially 100% false DANGER, fixed by downgrading mechanistic-unknown observations to co_occurrence and excluding them from forward-chain SQL — false alarms drop to 0%, locked as regression guard.
3.4 Credit Assignment: Four Feedback Loops
Remembering decision→outcome is step one; credit assignment decides what ranks next time.
Q-value Bellman backprop : during sleep, verified edges reward r=1.0 to both ends; standard Bellman update Q ← Q + α·(r + γ·max_Q(neighbor) − Q) (α=0.1, γ=0.9). The γ·max_Q term backpropagates outcome Q to parent decisions. Q persists in SQLite; next retrieval seed activation = 0.5 + 0.5·Q — useful experiences auto-rank higher.
Failure salience : consolidation replay scoring adds +0.5 for explicit failure, +0.3 for user-feedback source, +0.2 for contradictory outcomes elsewhere — "painful memories stick."
Influence-radius credit : new decisions can record influenced_by links; when a memory is falsified, all downstream decisions it influenced surface for review — error blast radius is explicit.
Source-tiered half-life : each edge records provenance (user-confirmed / LLM-inferred / temporal-proximity / rule); half-life tiers: user-confirmed 90 days + never GC, LLM-inferred 90 days, temporal-only 7 days — who said it determines how long it lives.
3.5 Write Gating: Three Gates Before Storage
Raw dialogue turns go only to audit table session_logs, never retrieval pool. Rule filter: must-record failures (40+ error/panic/timeout markers), must-record state-changing tools, explicit exclude read-only tools (early "record every tool call" produced noise like ran cargo build → exit 0). Final LLM extraction with 130-line V3 prompt yields five entry types (fact/preference/lesson/event/causal); causal few-shots strictly separate caused vs prevented — "added retry, timeout disappeared" is PREVENTED not CAUSED.
3.6 Retrieval: Per-Query Ephemeral BM25 Index
Hybrid BM25 (k1=1.2, b=0.75) + semantic vectors (local ONNX bge-small or HTTP embeddings, graceful fallback to pure BM25) fused via RRF. Counter-intuitive choice: rebuild BM25 index per query on the filtered candidate set (hundreds to thousands) — takes microseconds but yields exact IDF statistics on the post-filter sub-corpus; results can differ completely from global-index-then-filter.
Memory Governance: Post-Write Correctness
Core principle: system only flags, never silently deletes — all suspicious structures surfaced for human review, history never auto-erased.
4.1 Five Refuters: Confidence Physical per Edge
Adapted from DoWhy's refutation framework, translated to graph-structure tests. Each valid edge passes five tests, graded A–F:
1. confounder : Jaccard overlap of neighbor sets — true causal edges share context; zero overlap = suspected spurious.
2. corroboration : alternative path count after edge removal — true relations have redundant evidence; isolated single edge suspicious.
3. placebo : random node substitution reachability test — true edge has activation specificity; random node also reaches = non-specific.
4. backdoor : common ancestor bypass reachability (exact d-separation) — "A→B" actually fully explained by common cause C.
5. temporal : cause event_time must precede effect — effect before cause = temporally impossible, definitive fake edge.
Thresholds calibrated on synthetic ground-truth worlds: corroboration's "no alternative path ⇒ fake" rule dropped after killing 38% true edges in minimal DAG chains; backdoor kept absolute-count threshold (not density-normalized) because dense graphs connect almost all nodes via ancestors, normalized version also killed 38% true edges. Temporal is near-zero false-kill; adding it raised fake-edge flag rate from 35.7% to 64.3% with zero true-edge loss.
4.2 BiasAudit: Statistical Health Checks
Sleep consolidation's fifth phase runs three pure-observation detectors:
Polarity skew : domain outcome ≥90% same direction (≥5 samples) flags — 13 samples with 1 dissent is ~0.2% under fair process; either domain truly easy or failures unrecorded.
Zero-variance repetition : same decision recorded ≥3 times with identical outcome polarity — self-reinforcement suspect.
Confidence drift : recent 20 edges mean confidence vs historical mean shift ≥0.15 — reports only, no stamp — signals extractor model systematic bias, no single edge to blame.
Flagged edges enter human review queue; retrieval, decay, GC deliberately ignore the flag — same philosophy as soft-deprecation: annotate, don't adjudicate.
4.3 Contradiction-Aware Retrieval
search_causalwith explain=true appends contradictory history: highest-ranked polarity entry becomes "current belief"; opposite-polarity entries attached with [contradiction] label — both sides of a disputed question presented simultaneously, turning silent risk into explicit information.
Evaluation: Custom CausalEval Benchmark
Public benchmarks don't test causal ability, so the project includes CausalEval : deterministic typed DAG generation → LLM narrativizes to dialogue → ground truth derived directly from graph structure, zero human labeling. Results (v13, internal benchmark) show largest gains over fact-memory baseline on C2 Intervention, C4 Inhibition, C7 Update; weakest on C6 Cross-task transfer (20%). Public fact-recall benchmarks (LoCoMo, LongMemEval-S) reach usable levels but aren't the focus; the author warns all benchmark scores (including theirs) should be treated as self-reported due to judge model and protocol variance. Two practical experiments: compression survival (Fig 1: 5 rounds → text 45%, causal table 100%); trap-world repeat error 33% vs 67% baseline.
Real-World Deployment: Two-Month Production Log
Author's daily development agent ran causal-memory from 2026-07-27 to 2026-10-03 (read-only stats): 426 causal edges, 817 memory nodes, 2,901 facts, 56 cross-task meta edges. Edge distribution: caused 303 (71%), enabled 69 (16%), prevented 52 (12%). Notably, prevented edges have highest mean confidence (0.815) — avoidance lessons recorded with most certainty. Reuse data: 46% of causal edges recalled ≥6 times. Top reused: git -c http.proxy for GitHub connectivity (4 reuses, each spawning new "reused same fix" edge). Most recalled (19×): Go toolchain cache path detail.
Two vivid anecdotes:
One Prevented Production Incident (prevented · confidence 0.95) Multi-tenant storage rewrite: Agent recorded "new binary runs drift verification on tenant DB replica before container swap." Replica verification exposed an FK migration bug — avoided production outage across 9 tenant databases. Full migration completed zero failures.
"Didn't Check Memory, Lost 20 Minutes" (meta-lesson · negative) GitHub port 443 totally unreachable; Agent didn't query causal memory first, hand-wrote REST API workaround, cost ~20 min. Post-hoc found proxy solution already verified twice in memory — one command would have solved it. New discipline: network/deployment ops must search_causal first.
Failures also recorded honestly: distillation pipeline once completely broke due to silent upstream model upgrade; V3 prompt entered repeat loop on new model. Edge entered at 0.4 confidence, tagged "negative unexpected result", directly prompted engineering rule: prompts must be re-calibrated per current model. Gaps acknowledged: session_logs gating not enabled, Hebbian co-occurrence edges only 6 with zero weight growth, recall audit only 12 entries since September, decision_forks table still empty — mechanisms implemented but not yet statistically significant in live traffic.
Engineering: Single-Binary, Solo-Maintainable
Entire system is a Rust single binary: MCP server (stdio + Streamable HTTP), offline session extraction CLI (extract/judge/reasoning/distill cost tiers), sleep consolidation, benchmark harness. Key decisions:
Git-style snapshot sync, semantics fully self-implemented : commits are content-addressed SHA-256 objects; clone restores full context on new machine, checkout rolls back to any snapshot; single-writer assumption avoids merge complexity. Primary goal: context disaster recovery — agent runs anywhere, memory follows. Team sharing is natural extension: multiple AI tools point to shared remote, correction state aligns on pull, new member clone inherits org history.
Multi-tenant HTTP : token maps to tenant, each gets independent lazy-opened SQLite, config hot-reload, fail-closed on corruption — deployment shape for team-shared memory hub.
Observability : Prometheus /metrics, /debug/recall returns full trace per recall (seeds, hop summaries, per-result provenance) — memory system's own recall must be debuggable.
Ecosystem integration : Claude Code / Cursor / Kimi Code / Codex via MCP + skill; PyO3 Python bindings matching 17 MCP tools; native plugins for Hermes and DeepSeek Harness.
Testing : 460+ tests at HEAD, covering 16 design-layer end-to-end validations; calibration harness (synthetic ground-truth worlds) fully open in repo.
Extended View: Memory as Foundation for Recursive Self-Improvement
RSI (Recursive Self-Improvement) discussions rising (ICLR 2026 workshop, industry & open-source projects). Clean definition: system modifies its persistent components, evaluates the change, runs next iteration with improved process . Three loops: modify component, evaluate, iterate. By risk/cost: weight changes costliest/riskiest, code changes next, prompt/tool strategy cheaper, memory changes cheapest, doable today — no model/code touch, only improves "next-call experience ranking." Causal-memory's sleep consolidation + Q-value backprop is a minimal closed loop at memory layer: act → record outcome → credit-assign update ranking → next act uses new ranking → record again. Loop runs; the modified artifact is memory, not weights.
Evaluation signals must be grounded. Causal-memory produces three: outcome polarity judgment (success/fail), Q-value Bellman backprop (good outcomes credit parent decisions), prediction ledger (counterfactual judgments auto-settle accuracy). Without credit assignment, "improvement" is just "change" — system mutates but no one knows if better or worse.
How to avoid loop decay? Few ask. Without persistent memory, self-improvement spins: previous round's changes and effects forgotten, same flawed improvements reappear; worse, echo-chamber degradation — self-generated records reinforce themselves. Chapter 4 governance re-read in this light: BiasAudit's zero-variance repetition detector prevents "self-improvement becoming self-repetition"; confidence drift detector prevents "evaluation signal silently rotting."
Thus causal-memory positions modestly: doesn't promise agent becomes stronger model, only ensures every "edit" is auditable, accountable, and pitfall-avoidable.
Limitations & Outlook
System remains alpha (v0.9.3). Open items: C6 cross-task transfer only 20%, cross-domain analogy remains hardest open problem; intervention query accuracy benchmark designed but not completed; lacks 7×24 production long-horizon validation; Hebbian co-occurrence and decision forks haven't reached statistical scale in real traffic. Next steps: complete session-level snapshot/restore for context disaster recovery closure (switch machine/tool, carry full memory); distill reusable skill files from repeatedly successful decision patterns, codify "prohibited actions" from prevented edges; proactive memory freshness — expiry rotation and staleness detection, making "is this experience still fresh?" a queryable attribute. Enterprise fits: ops agent postmortem memory (each handling's decision→outcome auto-captured, same fault never re-learned), dev team shared memory hub, customer-service ops inhibitory alerts for "actions that previously triggered complaints."
Memory's goal isn't to make AI remember everything, but to make humans repeat no pitfalls.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
