Skip to content

Latest commit

 

History

History
91 lines (69 loc) · 2.78 KB

File metadata and controls

91 lines (69 loc) · 2.78 KB

Episodic vs Semantic Memory

Separate specific events (episodic) from general knowledge (semantic). Inspired by human memory architecture.

The Distinction

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"

Why Separate Them?

Mixing episodic and semantic memory creates:

  • Cluttered context (too many specific events)
  • Difficulty extracting general patterns
  • Conflicting information (old event vs. updated fact)

Implementation

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

Prompt Template

## 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).

Consolidation Strategy

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 & Cons

Pros: Clean separation, efficient context usage, facts are always current.

Cons: More complex implementation, consolidation requires LLM calls, cold start for facts.