Section 56.2: Spatial, episodic, and semantic memory

"The map knows where, the episode knows when, and the semantic store keeps insisting it knows why."

A Three-Drawer Memory Cabinet
Technical illustration for Section 56.2: Spatial, episodic, and semantic memory.
Figure 56.2A: Spatial, episodic, and semantic memory answer three genuinely different planning questions (where is it, what happened, what is typical); routing a question to the wrong store returns a confidently wrong answer.

This section assumes familiarity with why short-term and long-term memory differ, covered in section 56.1. The retrieval strategies that depend on the distinctions introduced here are developed in section 56.3, where queries are conditioned on the planner's current decision context. The representation boundaries between spatial, episodic, and semantic memory recur in Part XII alongside the capstone design challenges in section 57.1.

Big Picture

Figure 56.2A previews the central claim of this section: each memory type is built to answer a different planning question, and pointing the wrong store at a question is where systems fail. A household robot searching for scissors has three genuinely different questions to answer: Where is the kitchen drawer? (a spatial fact tied to geometry), Did this drawer jam last Tuesday? (an episodic trace tied to a past event), and Where do households typically store scissors? (a semantic prior built from many encounters). Collapse all three into one embedding index and a cosine-similarity search will typically confidently return the wrong answer for two of them. As embodied agents move into long-horizon, real-world deployment, getting this separation right is the difference between a system that generalises and one that confabulates. This section designs the three stores, their update cadences, and the query logic that routes each planning question to the right one.

Design Rule

If two memories answer different planning questions, they should not share one scoring rule. Spatial recall, episodic recall, and semantic recall need different freshness tests, confidence estimates, and failure alarms.

Theory

The three memory families can be written as

$$\mathcal M_{\text{spatial}}=(V,E,\psi), \qquad \mathcal M_{\text{episodic}}=\{(o_{1:T},a_{1:T},r_{1:T},c)\}, \qquad \mathcal M_{\text{semantic}}=\{(k,v,\sigma,\eta)\}.$$

Spatial memory is often metric or topological. Episodic memory preserves trajectories and outcomes. Semantic memory stores abstractions or facts with confidence \(\sigma\) and freshness \(\eta\).

In the spatial tuple \(\mathcal M_{\text{spatial}}=(V,E,\psi)\), \(V\) is the set of places or map cells, \(E\) is the set of edges connecting places that are reachable from one another, and \(\psi\) is a labeling function that attaches geometry (a coordinate, an occupancy value, or a semantic tag) to each vertex or edge. In the episodic tuple, \(o_{1:T}\), \(a_{1:T}\), and \(r_{1:T}\) are the observation, action, and reward sequences recorded over a trajectory of length \(T\), and \(c\) is the outcome or context label attached to that trajectory (for example, success, failure, or a specific fault code). In the semantic tuple, \(k\) is a key (a category or entity), \(v\) is the stored value or embedding, \(\sigma\) is a confidence score, and \(\eta\) is a freshness or staleness measure. These symbols recur throughout the rest of this section: the worked example below assigns concrete numbers to \(\sigma\) and \(\eta\) so the abstract notation maps onto an operational routing decision.

Figure 56.2B makes the routing concrete: a single planning query router inspects each incoming question and dispatches it to whichever of the three stores is built to answer it, and each store runs on its own update cadence.

Planning Query Router SPATIAL occupancy map scene graph EPISODIC trajectory log replay buffer SEMANTIC embedding index knowledge graph Where is it? What happened? What is typical? cadence: every cycle cadence: per trajectory cadence: after aggregation
Figure 56.2B: A planning query router dispatches geometric questions to spatial memory, temporal outcome questions to episodic memory, and category-level priors to semantic memory. Each store has a distinct update cadence.

A memory system that cannot say which kind of question it is answering is not a memory system: it is a search engine waiting to confabulate.

Why episodic memory carries extra weight

Of the three stores the router dispatches to, one carries a weight the others do not, because it is the only one that remembers what physically went wrong. Episodic memory matters in embodied AI because physical actions have irreversible consequences. A robot that has no record of previously jamming a drawer, tripping a circuit breaker, or dropping a fragile object cannot avoid repeating those failures. Spatial memory tells the robot where the drawer is; only episodic memory tells it that opening that drawer at speed caused a wrist-torque fault last Thursday. Without it, every interaction resets to the same prior, and hard-won failure signals vanish after each run.

Mechanically, episodic storage appends a timestamped tuple of observations, actions, and outcomes after each trajectory ends. At query time the retrieval layer searches for episodes whose context embedding is close to the current state. It ranks those episodes by recency and relevance, then returns the top-k records, where top-k means the k highest-scoring matches rather than every record above a threshold. The scale shows what retrieval buys. A robot exploring a 20-room apartment may accumulate 40,000 raw sensor frames per hour. The episodic index condenses those frames into roughly 200 to 400 labeled trajectory records, so the planner reasons over a 100-fold smaller search space without losing the failure signals. The planner then conditions its next action on the retrieved outcome rather than repeating an approach that previously failed.

Checkpoint

So far: episodic memory writes a timestamped record after every trajectory, retrieves the top-k closest matches by embedding similarity at query time, and this indexing is what compresses tens of thousands of raw sensor frames per hour down to a few hundred searchable trajectory records without losing the failure signals a planner needs.

Keeping episodic recall this sharp depends on not letting it bleed into the other two stores, which is why, in practice, the three live in separate places. Operationally, these memory types usually sit in different toolchains. Spatial memory may live in `tf2` transform trees, occupancy maps, voxel stores, or scene graphs (a scene graph is a node-and-edge structure whose nodes are objects and places and whose edges are spatial relations between them); episodic memory may be written into ROS bags, trajectory databases, or replay buffers; semantic memory may be indexed with FAISS (Facebook AI Similarity Search), pgvector (a PostgreSQL extension that stores embedding vectors and runs nearest-neighbor search inside the database), or a knowledge graph. Separating the stores makes provenance and failure analysis tractable.

When using FAISS or pgvector for semantic memory, always store a memory_type metadata field alongside each embedding and filter on it at query time (e.g., faiss.IDSelectorArray (a FAISS helper that restricts a search to a caller-supplied list of vector ids, so a single index can be queried as if it were three separate ones) or a pgvector WHERE memory_type = 'semantic' clause). Skipping this tag is the single most common setup mistake: a cosine-similarity search over a mixed index will happily return an episodic trajectory or an occupancy-map cell as the top hit for a category-level query, and the score will look plausible because embeddings from different memory families often cluster together. Add the filter from the first commit; retrofitting it into a populated index requires re-indexing every record.

Three Memory Types, Three Query Families
Memory TypeTypical RepresentationQuery ExampleFailure Mode
Spatialoccupancy map, scene graph, topological mapWhere is the charging dock relative to me?frame drift or map staleness
Episodictrajectory log, intervention trace, replay bufferWhat happened the last time I attempted this grasp?retrieval of a similar but irrelevant episode
Semantickey-value memory, embedding index, knowledge graphWhere are scissors usually stored?overgeneralized or stale fact

These memory types also differ in update cadence. Spatial memory may change every control cycle, episodic memory may be appended after each trajectory, and semantic memory may be updated only after aggregation or human verification. This mismatch is called the memory cadence alignment problem, and conflating those cadences causes either excessive churn or stale abstractions.

Think of a professional chef who keeps three kinds of knowledge on different update cycles: a whiteboard on the pass showing what is 86'd right now (updated every few minutes, like spatial memory), a personal notebook of dishes that went wrong during last night's service (written once per shift, like episodic memory), and a recipe binder built from years of cooking (revised only after a technique is proven across many services, like semantic memory). Scrubbing the recipe binder every time a single item sells out would corrupt hard-won culinary knowledge with momentary supply facts, while never updating the whiteboard would send servers to the table with a dish that no longer exists. Each store has to change at the rate that matches the kind of truth it holds.

Updating semantic memory at the same rate as spatial memory is like revising a dictionary every time you stub your toe: technically responsive, but the result mostly just reflects recent pain rather than accumulated wisdom.

Worked Example

A household robot hunting for scissors splits the search across all three stores: spatial for drawer locations, episodic for where it last saw the scissors, and semantic for where households typically keep them.

def validate_memory_queries(payload: dict[str, object]) -> dict[str, object]:
    assert payload, "payload must not be empty"
    return payload

memory_queries = {
    "where_is_drawer_3": "spatial",
    "what_happened_last_time_i_opened_this_drawer": "episodic",
    "where_are_scissors_usually_stored": "semantic",
}
print(validate_memory_queries(memory_queries))
{'where_is_drawer_3': 'spatial', 'what_happened_last_time_i_opened_this_drawer': 'episodic', 'where_are_scissors_usually_stored': 'semantic'}
Code Fragment 56.2.1: the memory_queries dictionary maps each concrete scissors-search question to the single memory type (spatial, episodic, or semantic) that should answer it, and validate_memory_queries asserts the routing table is non-empty before use.

On a Stretch RE2 mobile manipulator running ROS 2 Humble, each of these queries routes to a different subsystem with a different latency budget. The spatial query hits an OctoMap (a probabilistic 3-D occupancy grid stored as an octree) that a Realsense D435i updates at 10 Hz. A round-trip takes roughly 2 ms. The episodic query replays a compressed ROS 2 bag entry written after the previous grasp attempt. Retrieval from a 72-hour rolling buffer indexed by FAISS typically resolves in 8 to 15 ms. The semantic query calls a pgvector lookup over a 50 k-entry household-object knowledge base, with a median latency of 22 ms. Routing a spatial query through the semantic pathway would add 20 ms of unjustified latency. Worse, it would return a category-level prior ("scissors live in drawers") rather than the current metric pose of drawer 3. The arm trajectory planner would then target the wrong Cartesian goal and trigger a wrist-torque fault at contact (a safety stop triggered when the wrist joint's motor senses more resistance than an expected, unobstructed motion should produce).

Step-Through: Routing one query through all three stores

Trace the scissors query through the router with concrete values. The planner emits the question "where are the scissors right now?" and the router must pick a store. Spatial store returns drawer 3 at metric pose (x=2.10 m, y=0.85 m), freshness eta=0.4 s (updated last control cycle), confidence 0.99. Episodic store returns trajectory record #182 "scissors observed in drawer 3 at t=18:42 yesterday", freshness eta=15 h, relevance 0.88. Semantic store returns the prior "scissors usually live in kitchen drawers", confidence sigma=0.73, freshness eta=undefined (aggregated). The router scores each by the question's risk profile: the word "right now" flags a temporal-current question, so it ranks episodic recency above semantic generality, then cross-checks against spatial geometry. Final pick: episodic record #182 (drawer 3, 15 h old) confirmed by the live spatial pose (drawer 3, 0.4 s old). The semantic prior, confidence 0.73, is discarded because two fresher stores agree on a specific drawer. Had the router naively taken the highest raw cosine score from a merged index, the semantic prior would have won and returned "a kitchen drawer" with no metric pose, leaving the arm planner no Cartesian goal to aim at.

Library Shortcut

OctoMap, Habitat, Open3D, NetworkX, ROS 2 bags, and FAISS-style retrieval can each support part of this stack, but only when the interface preserves memory type, freshness, coordinate frame, and provenance. The wrong shortcut is one giant vector store that hides whether a returned item was geometric, episodic, or semantic.

Implementation Stack

Use Open3D or Simultaneous Localization and Mapping (SLAM) outputs for spatial memory, ROS 2 bag replay for episodic traces, NetworkX for explicit topological or semantic relations, and PyTorch or JAX embeddings only when the retrieved vector still points back to an inspectable record. Habitat can supply controlled scene-memory tasks, while Weights & Biases or TensorBoard logs should record which memory type changed the planner's action.

Algorithm: Choose The Right Memory Type
  1. Classify the target query as geometric, temporal, or conceptual.
  2. Use spatial memory for coordinate, occupancy, and topology questions.
  3. Use episodic memory for trajectory, intervention, and outcome questions.
  4. Use semantic memory for category-level or relational priors.
  5. Store explicit links across memory types rather than flattening them into one blob.

A common assumption is that spatial, episodic, and semantic memory are three labels for the same data structure, and that a single vector store can serve all three roles with the right query prompt. That assumption is wrong. Each memory type answers a categorically different question: where something is now (spatial), what happened during a past interaction (episodic), or what is generally true across many encounters (semantic). Conflating them forces one scoring function to optimize for metric precision, temporal recency, and categorical generality at once. Those goals pull in opposite directions. In practice, the function will return confidently wrong results for at least two of the three question types often enough that the failure mode should be treated as expected rather than exceptional. Treat the three stores as separate subsystems. Give each its own update cadence and confidence estimate, and route each planning question to the correct store before touching any index.

Common Failure Mode

A semantic prior can silently override current spatial evidence. If the map says the corridor is blocked now, a stored fact that it is "usually open" should not win.

Consider a specific case: a warehouse robot learned from 200 prior runs that Aisle 7 is passable 95% of the time, so its semantic store holds passable: confidence 0.95. On Tuesday a forklift parks there. The robot's LiDAR occupancy grid marks a 1.2-meter obstacle at grid cell (47, 12) with confidence 0.99. If the planner queries semantic memory first and only falls back to spatial memory when the semantic score is below a threshold, it may plan through Aisle 7, compute a path, and only detect the collision risk at the final obstacle-check stage, 300 ms and several planning cycles later. The fix is a strict query-routing rule: geometric reachability questions always go to spatial memory first; semantic memory may only contribute category-level priors when no current sensor evidence covers the relevant region.

Practical Example

In a warehouse, spatial memory may encode docks and aisles, episodic memory may preserve recent deadlock traces, and semantic memory may preserve higher-level knowledge such as "fragile cartons should avoid sharp turns."

Real-World Application: Mobile manipulation in homes

Google DeepMind's Mobile ALOHA and the RT-2 stack keep these stores separate in practice: a live occupancy and pose graph (spatial) drives base navigation, logged teleoperation and autonomous rollouts (episodic) seed the replay buffers used for policy training, and a VLM-derived object-affordance prior (semantic) answers "where would this object usually be." Routing a fetch query to the spatial pose rather than the semantic prior is what lets the arm target a real Cartesian goal instead of a category guess.

A useful evidence artifact here is a memory-routing ledger that records query text, chosen memory type, retrieved record id, freshness field, and downstream action change. That artifact makes it obvious when the robot answered a geometric question with a semantic prior or reused an old episode without checking whether the scene had changed.

Research Frontier

Active directions (2024-2026):

Lifelong scene graph consolidation. Methods that continuously merge episodic observations into updatable 3-D semantic scene graphs are moving from single-session to multi-day, multi-robot settings. The ConceptGraphs line of work (Gu et al., 2024, ICRA) demonstrated open-vocabulary object-relation graphs built from CLIP and SAM features; follow-on labs (CMU RPAD, MIT CSAIL) are extending this toward persistent, collaborative graphs shared across robot fleets.

Retrieval-augmented robot policies. Rather than distilling episodes into fixed semantic rules, 2024-2025 work feeds raw retrieved episodes directly into a diffusion or transformer policy at inference time. RoboFlamingo (Li et al., 2024) and SuSIE (Black et al., 2024) treat past interaction records as in-context demonstrations, sidestepping the episode-to-semantic translation problem at the cost of longer context windows.

Memory-type-aware foundation models. The Embodied Memory Transformer line (Google DeepMind, 2025) conditions a single model on an explicit memory-type token so that spatial, episodic, and semantic records can share one encoder while still routing queries to type-appropriate heads. This collapses the engineering overhead of three separate stores without collapsing the representational distinctions.

Open problem for a PhD student: No principled criterion yet exists for deciding when a cluster of episodic traces has accumulated enough evidence to justify writing a new semantic rule, versus when the episodes reflect a transient environmental anomaly that should decay. Designing an online Bayesian update rule that operates separately for each memory type, with calibrated uncertainty about which type a given observation belongs to, is an open and tractable dissertation problem.

Self Check

Can you name one planning query that should fail if answered by the wrong memory type? If not, the representation boundary is still descriptive rather than operational.

Self Check

Can you point to one query that each memory type should answer in your application, and explain what would go wrong if the wrong memory type answered it?

Research Frontier

An open problem is learning when to translate across memory types. A robot may need to convert repeated episodes into a semantic rule, or turn a semantic hypothesis into a targeted spatial search, without smearing uncertainty across incompatible representations.

Self Check

Can you name one planning query that should fail if answered by the wrong memory type? If not, rewrite the task until the representation boundary is operational rather than descriptive.

Key Takeaway

Spatial, episodic, and semantic memory are distinct system components because they answer different queries with different risk profiles.

Exercise 56.2.1

For a robot that restocks shelves, list three planning queries and assign each to spatial, episodic, or semantic memory. Justify the assignment in one sentence per query.

Lab: Watch the wrong store give a confident wrong answer

Goal: Show empirically that merging the three memory families into one vector index returns plausible-looking but wrong answers, and that a memory_type filter fixes it.

Tools: Python with faiss-cpu, numpy, and sentence-transformers (about 15-30 minutes). Optionally swap in pgvector if you prefer SQL.

Steps: (1) Build three small record sets: ~20 spatial entries ("drawer 3 at pose 2.1, 0.85"), ~20 episodic entries ("opened drawer 3 yesterday, scissors present"), and ~20 semantic entries ("scissors usually stored in kitchen drawers"). Embed all 60 with one encoder and add them to a single flat FAISS index. (2) Query "where are the scissors right now?" and record the top-1 hit and its score. (3) Re-run with an IDSelectorArray that restricts the search to spatial-only ids, then episodic-only, then semantic-only.

What to vary: the query wording ("right now" vs "usually" vs "last time"), the encoder model, and the spatial/episodic/semantic ratio in the merged index.

What to observe: how often the unfiltered top-1 is the wrong memory type, how high its cosine score still looks (often above 0.6, deceptively confident), and how the per-type filtered query always returns a record of the intended family. You should see that score magnitude is no defense against routing to the wrong store.

Section References

Chaplot, D. S. et al. Neural Topological SLAM for Visual Navigation. CVPR, 2020.

Use for map-like memory that supports navigation decisions rather than generic retrieval.

Parisotto, E. and Salakhutdinov, R. Neural Map: Structured Memory for Deep Reinforcement Learning. ICLR, 2018.

Use for differentiable spatial memory and the distinction between stored geometry and policy state.

Project Ideas

Beginner (weekend): Build a Gymnasium wrapper around a simple grid-world navigation task that maintains three separate Python dictionaries as spatial, episodic, and semantic stores, then log which store answered each query and verify that routing a spatial question to the semantic store degrades task success rate. The key challenge is writing a query classifier that assigns each planning question to the correct store without look-ahead knowledge of the answer.

Intermediate (1 to 2 weeks): Implement a three-store memory system for a MuJoCo or PyBullet tabletop manipulation environment (PyBullet is adequate for this exercise, though as of 2024 MuJoCo is the more actively maintained choice) using Open3D for occupancy-based spatial memory, a FAISS index with a memory_type filter for episodic and semantic records, and a ROS 2 bag logger to persist episodic traces across runs; then compare grasp-success rates with and without episodic retrieval over 50 trials. The key challenge is keeping coordinate-frame provenance intact when spatial records and episodic records share the same embedding space but must never be retrieved interchangeably.

Advanced (3 to 4 weeks): Deploy a mobile robot in Isaac Lab with a three-store memory architecture where the spatial store feeds an OctoMap updated at 10 Hz, the episodic store uses LeRobot replay buffers to condition a diffusion policy on past failure traces, and a pgvector knowledge base holds semantic priors extracted from prior rollouts; then measure how many episodes are needed to suppress a repeating joint-fault compared to a baseline with no episodic store. The key challenge is designing the episode-to-semantic distillation rule that decides when enough repeated episodes justify updating a semantic prior without collapsing short-term noise into long-term fact.

What's Next?

Next, continue with Section 56.3, where retrieval is conditioned on the planner's current decision.