I Built a Memory Layer for LLM Agents That Knows Which Facts Go Stale A developer built VoltMem, a memory layer for LLM agents that distinguishes between volatile and stable facts to avoid stale or corrupted knowledge. Unlike existing systems like Mem0, VoltMem assigns domain-aware protection weights and down-ranks stale volatile memories at retrieval time. In scripted scenarios, it correctly updated a location change from Berlin to Paris, resisted a blip contradicting a stable preference, and updated a mood shift, achieving 0% stale@1 retrieval versus 20% for cosine-only ranking. VoltMem didn't start because I kept hitting bugs in production agents. It started with a conversation about how memory actually works — why some beliefs stick for decades while others evaporate in hours, and what triggers the audit when an old calibration stops matching present reality. That led to continual-learning research on the stability–plasticity tradeoff, and then to a structural parallel in agent memory: most layers treat every fact the same at write and search time. Your AI assistant knows you live in Berlin. You moved to Paris three months ago. It still thinks you live in Berlin. Meanwhile, the fact that you prefer concise answers — stable for years — gets the same grip as "currently working on a database migration," which you finished last week. Everything is stored the same way. Everything decays or doesn't at the same rate. There's no concept of how volatile a piece of knowledge actually is. Mem0 remembers relevant facts. VoltMem remembers current truth. Think about how different types of facts actually behave over time: An LLM memory system that treats all of these with the same protection strength makes systematic errors in a predictable direction: it holds volatile facts too long stale knowledge , or overwrites stable facts on thin evidence corrupted knowledge . You can't fix both with one dial. What you need is domain-aware protection — and, at search time, down-ranking of stale volatile memories even when they're semantically close. Protection weight per domain : Write / audit decision — escalate audit + update when Et θt : Where: High-volatility domain → low threshold → easy to update. Low-volatility domain → high threshold → hard to update. Retrieval — down-rank stale volatile memories: The practical effect: a confident blip like "the user seemed extroverted today" won't overwrite a deeply confirmed "user is introverted" — but "user moved to Paris" will cleanly supersede "user lives in Berlin" because location is a volatile domain where a single explicit statement clears the update bar easily. On Split-MNIST, this isn't a free-lunch accuracy booster. It's a validated control knob : run the same pipeline with volatility priors shuffled or inverted, and the ordering breaks REAL SHUFFLE SWAP . Pre-arXiv draft: volatility ewc portfolio.pdf https://github.com/Rouche01/voltmem/blob/main/paper/volatility ewc portfolio.pdf . Full reproduction: docs/RESEARCH.md https://github.com/Rouche01/voltmem/blob/main/docs/RESEARCH.md . I compared VoltMem against Mem0 open-source LLM memory on three concrete scenarios — a case study , not a leaderboard claim: Scenario 1: Location update User says they moved from Berlin to Paris. | Mem0 | VoltMem | | |---|---|---| | Result | Stale "Berlin" stored, 2 conflicting facts | Updated to "Paris", 1 clean fact | Scenario 2: Stable preference blip User says they "really like short replies" in one session, contradicting an established preference for thorough explanations. | Mem0 | VoltMem | | |---|---|---| | Result | Adopts the blip | Keeps original resists weak contradicting evidence | Scenario 3: Volatile mood User's mood shifts from "great" to "stressed". | Mem0 | VoltMem | | |---|---|---| | Result | Stale "great" persists | Updates to "stressed" | VoltMem: 3/3 current top answer on these scripted scenarios. Challenge the scripts: python experiments/mem0 side by side.py Retrieval haystack same chunks, different ranker : cosine-only returns the stale fact first 20% of the time; VoltMem 0% stale@1 mailto:stale@1 . python experiments/retrieval haystack bench.py LongMemEval-S n=60 : 70% answer@5 — ties cosine, does not beat it. If your only metric is public benchmark SOTA, this isn't the pitch. The pitch is update policy + retrieval freshness on mixed-volatility personal memory. python experiments/longmemeval.py --split s --per-type 10 pip install voltmem embeddings Core library: zero required dependencies . Embeddings optional sentence-transformers . python from voltmem import create memory mem = create memory "app.db", user id="alice" mem.add "I live in Berlin" mem.add "I prefer concise, direct answers" mem.add "Actually I moved to Paris last month" updates location, not prefs hits = mem.search "where does the user live?", limit=3 print hits 0 "memory" "Actually I moved to Paris last month" Inject into any LLM system: memories = mem.search user message, limit=5 context = "\n".join f"- {m 'memory' }" for m in memories system = f"What you know about this user:\n{context}" VoltMem ships with sensible defaults you can override: | Domain | Volatility | Behavior | |---|---|---| personality trait | 0.05 | Strongly protected | core preference | 0.08 | Strongly protected | biographical | 0.10 | High protection | professional context | 0.30 | Medium — changes every few years | current project | 0.55 | Updates readily | emotional context | 0.80 | Fast-moving | current task | 0.90 | Minimal protection | Custom domains: python from voltmem import create memory, DomainRegistry domains = DomainRegistry domains.register "client relationship", 0.35 domains.register "active deal stage", 0.70 mem = create memory "crm.db", user id="rep 01", domains=domains The priors are hand-tuned today — that's an open gap, and one of the places I'd most like real-world feedback. pip install voltmem langchain python from voltmem.integrations.langchain import VoltMemMemory memory = VoltMemMemory session id="user-42", db path="app.db" memory.load memory variables {"input": "Where do I live?"} memory.save context {"input": "I moved to Paris"}, {"output": "Noted."} This grew out of a philosophical conversation about how human minds handle stale beliefs — when to trust an old habit and when to question it. The observation: animals mostly rely on impulses and simple reinforcement to build routines. Human minds add a monitoring layer on top — but that layer can go wrong when calibrated by social contexts that no longer apply. An old rule, reinforced enough times in a specific environment, can feel like an unquestionable fact even when the environment has fundamentally changed. That maps almost exactly onto the LLM memory problem. A memory system calibrated by early conversation data can become rigid in the same way — protecting old "truths" that are now stale because they were confirmed enough times in the past. The escalation equations above formalize the same idea: use historical reinforcement as one input, but also factor in domain volatility, source reliability, and actual mismatch — rather than letting any one factor dominate. The continual-learning experiments validated that as a causal control knob; VoltMem is the engineering artifact applied to agent context memory. pip install voltmem embeddings python examples/contradiction demo.py python -m examples.chat app If you're building anything with persistent LLM memory, I'd genuinely like to hear how the stale-knowledge problem shows up in practice — the use cases I haven't thought of are usually the most interesting ones.