Separate specific events (episodic) from general knowledge (semantic). Inspired by human memory architecture.
| Memory Type | What It Stores | Example |
|---|---|---|
| Episodic | Specific events, conversations, experiences | "User asked about pricing on June 15 and chose the enterprise plan" |
| Semantic | Facts, preferences, concepts, learned patterns | "User prefers enterprise pricing, needs SOC2 compliance" |
Mixing episodic and semantic memory creates:
- Cluttered context (too many specific events)
- Difficulty extracting general patterns
- Conflicting information (old event vs. updated fact)
class EpisodicSemanticMemory:
def __init__(self, embed_fn):
self.episodic = VectorMemory(embed_fn, top_k=3)
self.semantic = {} # key-value store for facts
def add_event(self, event_text, metadata=None):
"""Store a specific event."""
self.episodic.add(event_text, metadata)
def add_fact(self, key, value):
"""Store or update a general fact."""
self.semantic[key] = {
"value": value,
"updated_at": datetime.now(),
}
def get_context(self, query):
events = self.episodic.search(query)
facts = self._get_relevant_facts(query)
parts = []
if facts:
parts.append("[Known facts about the user/situation]")
for k, v in facts.items():
parts.append(f"- {k}: {v['value']}")
if events:
parts.append("[Relevant past events]")
for e in events:
parts.append(f"- {e['text']}")
return "\n".join(parts)
def _get_relevant_facts(self, query):
"""Simple keyword matching. Replace with semantic search for production."""
results = {}
for key, val in self.semantic.items():
if any(word in query.lower() for word in key.lower().split()):
results[key] = val
return results## Known Facts
{semantic facts about the user/project}
## Relevant Past Events
{specific past interactions}
Use facts as ground truth. Use events for context.
If an event contradicts a fact, the fact takes precedence
(events may be outdated).Periodically extract semantic facts from episodic memory:
1. Collect recent episodes
2. LLM prompt: "Extract facts, preferences, and decisions from these events"
3. Update semantic store
4. Archive old episodes or keep only high-signal ones
Pros: Clean separation, efficient context usage, facts are always current.
Cons: More complex implementation, consolidation requires LLM calls, cold start for facts.