Episodic + Semantic Memory for an Agent

Give an AI agent two memory types — episodic (what happened, when) and semantic (durable facts) — in one SQL store, and recall across both by meaning. Framework-agnostic: Claude Code, OpenClaw, LangChain, or a voice agent.

All recipes· agents· 14 minutesintermediateen
Instance: localhost:8080

Opens your running SynapCores (Episodic + Semantic Memory for an Agent will be staged for a preview — nothing runs until you click Run). No instance yet? Install free in ~30s.

Share

Objective

Human memory has two kinds: episodic ("on Tuesday the user cancelled their order") and semantic ("the user lives in Berlin"). Agents need both — episodes give you a timeline of events, semantic facts give you durable knowledge. Most stacks fake this with two databases. Here you'll hold both in one table, tag each memory by type, recall across both by meaning, and promote a repeated episode into a semantic fact — all in plain SQL. The same store works from any framework or a voice agent — see Use it from your agent at the end.

Step 1: Create one memory store for both memory types

A mem_type column distinguishes episodic events from semantic facts; both are embedded for recall.

CREATE TABLE IF NOT EXISTS recipe_agent_episodic (
  memory_id   INTEGER PRIMARY KEY,
  agent_id    TEXT,
  mem_type    TEXT,                                  -- 'episodic' or 'semantic'
  content     TEXT,
  occurred_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  embedding   VECTOR(384)
);

Step 2: Record episodes (things that happened)

Episodic memories are dated events from the conversation history.

INSERT INTO recipe_agent_episodic (memory_id, agent_id, mem_type, content, occurred_at) VALUES
 (1,'assistant','episodic','The user asked to reschedule the Monday standup.','2026-05-10 14:00:00'),
 (2,'assistant','episodic','The user complained the export was too slow.',     '2026-05-12 09:30:00'),
 (3,'assistant','episodic','The user asked about the export performance again.','2026-05-20 11:15:00'),
 (4,'assistant','episodic','The user thanked the agent for fixing the export.', '2026-05-22 16:45:00');

Step 3: Record durable facts (semantic memory)

Semantic memories are stable truths that don't belong to a single moment.

INSERT INTO recipe_agent_episodic (memory_id, agent_id, mem_type, content) VALUES
 (5,'assistant','semantic','The user manages the analytics team.'),
 (6,'assistant','semantic','The user is based in Berlin (CET timezone).'),
 (7,'assistant','semantic','The user owns the data export feature.');

Step 4: Embed every memory

One line embeds both episodic and semantic rows; the model runs in-database.

UPDATE recipe_agent_episodic SET embedding = EMBED(content);

Step 5: Recall the timeline of an episode (episodic only)

Filter to episodic memories and rank by meaning to reconstruct what happened around a topic, in order.

SELECT occurred_at, content,
       COSINE_SIMILARITY(embedding, EMBED('problems with the data export')) AS relevance
FROM recipe_agent_episodic
WHERE agent_id = 'assistant' AND mem_type = 'episodic'
ORDER BY relevance DESC, occurred_at ASC
LIMIT 4;

Step 6: Recall a durable fact (semantic only)

The same query against semantic rows answers "what do I durably know?" without timeline noise.

SELECT content,
       COSINE_SIMILARITY(embedding, EMBED('Where is the user located and what is their timezone?')) AS relevance
FROM recipe_agent_episodic
WHERE agent_id = 'assistant' AND mem_type = 'semantic'
ORDER BY relevance DESC
LIMIT 2;

Step 7: Consolidate — promote a repeated episode to a semantic fact

When an episode keeps recurring, write a durable fact summarizing it (memory consolidation, like sleep does for us).

INSERT INTO recipe_agent_episodic (memory_id, agent_id, mem_type, content)
SELECT 8, 'assistant', 'semantic',
       GENERATE('In one short factual sentence, summarize the recurring issue across these events: ' ||
                (SELECT GROUP_CONCAT(content, ' | ') FROM recipe_agent_episodic
                  WHERE agent_id='assistant' AND mem_type='episodic'));

Step 8: Embed and verify the consolidated fact

Embed the new fact, then recall it like any other semantic memory.

UPDATE recipe_agent_episodic SET embedding = EMBED(content) WHERE embedding IS NULL;
SELECT mem_type, content FROM recipe_agent_episodic WHERE memory_id = 8;

Cleanup (Optional)

DROP TABLE IF EXISTS recipe_agent_episodic;

Expected Outcomes

  • Step 5 reconstructs the export-problem episode as a dated sequence — relevant events, in order.
  • Step 6 returns "based in Berlin (CET)" — a durable fact, with no timeline clutter.
  • Step 7–8 create a brand-new semantic memory that consolidates the recurring export episodes into one durable fact, the way a human would after the third time it came up.

You now have an agent that distinguishes what happened from what's true, recalls across both, and consolidates episodes into lasting knowledge.

Use it from your agent (framework-agnostic — this is the whole point)

Two memory types are just one column + the same data ops, so any agent uses them with no framework lock-in:

  • REST / SDKPOST /v1/query/execute (any language), or @synapcores/sdk client.executeQuery(...). Your agent writes episodes after each turn (Step 2) and durable facts when it learns something stable (Step 3), then recalls per type (Steps 5–6) and runs consolidation (Step 7) on a schedule.
  • MCP (native, on by default) — point any MCP client (Claude Code, Cursor, a custom loop, a voice runtime) at ws://<your-instance>/mcp?token=<jwt> (JWT from one POST /v1/auth/loginaccess_token). The execute tool records episodes/facts; the query tool runs type-scoped recall — episodic vs semantic memory becomes a tool parameter, no SDK required.
  • Any framework — OpenClaw, LangChain / LlamaIndex / Semantic Kernel, a custom loop, or a voice agent all read and write the same two-type store. The database is the brain; the framework is swappable.

Key Concepts Learned

  • One table + a mem_type column gives an agent both episodic and semantic memory — no second database.
  • Filtering by type lets the same COSINE_SIMILARITY query answer "what happened" or "what's true."
  • GENERATE() over a group of episodes performs memory consolidation — promoting recurring events to durable facts.
  • Because it's plain data ops (SQL / REST / MCP), dual-memory works for any agent — the agent-agnostic backend pattern this cluster builds on.

Tags

ai-agentepisodic-memorysemantic-memoryagent-memoryvectorembeddingsmcp

Run this on your own machine

Install SynapCores Community Edition free, paste the SQL or Cypher above into the bundled web UI, and watch it run.

Download Free CE