Semantic memory and consolidation
Be able to distil episodes into facts, handle contradictions and forgetting, and connect the memory to the agent's decisions.
Prerequisites
- EVector databases and indexingrequired
- FEpisodic memory for agentsrequired
Intuition
Episodes are events. Semantic memory is what the agent knows about the user after seeing many events: «prefers code examples to formulas», «knows linear algebra», «goal: LoRA fine-tuning by December». It is built through consolidation: periodically the model reads the new episodes and updates a list of facts.
Every fact carries: the source (which episodes), the confidence, the time, the validity (permanent / for now / expires). That makes three things possible:
- Contradictions: a new fact «wants formulas» against an old «prefers code» → the new one wins if it is fresher and supported by several episodes; otherwise ask the user.
- Forgetting: facts without support for a long time fall in confidence and are removed — otherwise the list grows and becomes wrong.
- Decisions: the agent reads the facts before it chooses the depth of explanation, the difficulty, the tone. If the facts do not affect any decision the memory is decoration.
Measure: the decisions with vs without the facts; the share of facts that are correct on human inspection; the share of contradictions that were resolved correctly.
Code
import json, time
CONSOLIDATE = """Here are known FACTS about the user (a JSON list) and NEW EPISODES.
Update the list of facts: add, raise/lower the confidence, mark contradictions. Every fact:
{"text": ..., "confidence": 0-1, "sources": [episode-id], "valid_until": null|date, "type": "preference|knowledge|goal"}
Answer ONLY with the new JSON list."""
def consolidate(llm, facts, episodes):
out = llm(CONSOLIDATE + "\nFACTS: " + json.dumps(facts, ensure_ascii=False) + "\nNEW EPISODES: " + json.dumps(episodes, ensure_ascii=False), temperature=0, json_mode=True)
new = json.loads(out)
return forget(new)
def forget(facts, half_life_d=90, min_conf=0.3):
now = time.time(); out = []
for f in facts:
age = (now - f.get("last_supported", now)) / 86400
f["confidence"] *= 0.5 ** (age / half_life_d)
if f["confidence"] >= min_conf and not (f.get("valid_until") and f["valid_until"] < time.strftime("%Y-%m-%d")):
out.append(f)
return out
def to_decision(facts):
pref = [f["text"] for f in facts if f["type"] == "preference" and f["confidence"] > 0.6]
return {"explanation_depth": "code" if any("code" in p for p in pref) else "intuition"}
Mastery means
- Distils episodes into facts with a source and a validity
- Handles contradictions and forgetting
- Connects the memory to the agent's decisions and measures the effect
Sign in to do the exercises and build your mastery up.
Sources
- arXiv — MemGPT: Towards LLMs as Operating Systems — arXiv (open access; licence per article)
- arXiv — Generative Agents: Interactive Simulacra of Human Behavior — arXiv (open access; licence per article)