Building Memory for AI Agents: From Episodes to Knowledge

Wait 5 sec.

Why episodic, semantic, procedural, and working memory should not be dumped into the same bucket.An AI agent completes a task successfully. It finds a flight, compares the options, applies the travel policy, and books the right itinerary.What should it remember?Everything, of course. Embed the conversation, persist the tool calls, store the final response, the screenshots, preferences, policy documents, and all the steps taken. When a similar request comes up later, retrieve the most relevant pieces and put them back into context.It looks like memory. In practice, it becomes a costly junk drawer.The problem is not that it stores too few things — it treats entirely different types of information as if they did the same job. A user's seat preference is not the story of their last booking. The refund policy is not the sequence of steps to refund a flight. The agent's current scratchpad is not knowledge at all. Dump all of this into one searchable pool, and the agent gets plenty of similar-looking context but no signal for what each item means or how much to trust it.That's not a memory system. It is storage with a search box.Agent memory design must start with a different question: what type of memory do we want here and what decision should it inform?Agent Memory as a Routing Problem"Agent memory" sounds like a single feature: add a database, connect an embedding model, done. But an effective agent needs several distinct memory functions:Working memory — what matters for the task happening right nowEpisodic memory — what happened in a specific past experienceSemantic memory — facts and stable knowledge learned across experiencesProcedural memory — validated workflows, policies, and strategies for how to actWhile using terms from cognitive science, this analogy has many limitations I will discuss later. The practical importance is that every type of memory has different storage, retrieval, update, and expiration mechanisms. It is not just "find similar context" — the agent receives the relevant type of information with the appropriate level of authority at the right moment.What Each Type of Memory Should DoWorking memory is the current workspace — the goal, plan, recent tool responses, unresolved questions. For a flight-booking agent, that might include the requested route, three fares being compared, and a verification step that is still pending. It must be small, relevant, and disposable. It is easy to confuse this memory type with the model's context window — but the context window is where information can appear, while working memory is the system deciding what deserves to occupy that space right now. Keeping every old message active does not make the agent more informed. It makes the agent easier to distract.Episodic memory contains specific past events and the structure of those events: goal, context, action sequence, observations, and outcomes. "On July 8, the user rejected the cheapest fare because it didn't include checked bags; then the agent found itineraries with baggage included." It is a useful precedent — but just that. It does not mean that the user rejects any cheap fares just because of checked bags. It is exactly the place where a simple vector storage can cause serious problems — similarity of text can find an old experience without saying how precisely to interpret it.Semantic memory stores facts, relationships, and preferences that can live longer than the episode that generated it — the user prefers aisle seats, flights over $800 require approval, ORD airport is O'Hare. This kind of information requires more than text. Production systems must track provenance, confidence, scope, and freshness of every piece of information stored. "User prefers aisle seats" can mean very different things if it is stated once or inferred from ten bookings — without this information, a poorly supported fact can become as authoritative as a well-supported one.Procedural memory stores ways of acting — validated workflows, constraints, and approval thresholds. This information is not simply recalled — it actively shapes the plan. But this is also the place where luck easily becomes a policy: if every successful trajectory becomes a reusable procedure, one lucky run that skipped a required step can become a trusted workflow. The episodic memory tells us what happened in the past. Procedural memory is about the next step — and that is exactly where validation must occur.One task can create all four kinds of memory at once: a flight-change request generates temporary state in working memory, a completed event in episodic memory, and a user preference in semantic memory ("I always prefer morning flights"), and (if this handling of a change fee proved to be consistent) a candidate update of procedural memory.A Minimal Contract for Memory RecordsClassification is the foundation of this architecture. In practice, it means that any piece of information to be stored must have an explicit type and metadata fields before writing into the database — not inferred at the retrieval time:{ "id": "mem_9f1a2c", "type": "semantic", "content": "User prefers aisle seats on flights over 3 hours.", "scope": { "owner": "user_4821", "applies_to": "long_haul_flights" }, "provenance": { "source": "episodic", "derived_from": ["ep_7712", "ep_7810", "ep_8004"], "extraction_method": "explicit_statement" }, "confidence": 0.86, "created_at": "2026-06-02T14:11:00Z", "last_validated_at": "2026-07-19T09:00:00Z", "expires_at": null, "supersedes": null}It also needs a routing layer that determines where to search before determining which piece is similar — exactly what a flat vector storage omits:def retrieve(query, task_purpose, user_id): # 1. Determine which memory types are actually needed by this task candidate_types = classify_purpose(task_purpose) # e.g. "check baggage policy" -> ["semantic", "procedural"] # "has this user done this before?" -> ["episodic"] results = [] for mem_type in candidate_types: hits = vector_search( query, filter={"type": mem_type, "scope.owner": user_id}, top_k=8 ) results.extend(hits) # 2. Rank inside the selected subset — not inside the whole database return rank( results, weights={"relevance": 0.4, "confidence": 0.3, "recency": 0.2, "scope_match": 0.1} )The exact code is not the point. The design replaces "search everything, then let the model sort it out" with "classify first, search within that type, then rank." Classification happens at write time and again at retrieval time; similarity search runs only inside an already-scoped set.What Happens in PracticeThis failure mode is not theoretical: it emerges every time an agent accumulates different types of memory over time, especially when the agent resumes after a break and reconstructs its state from persisted information. If all this information is in the same index, a temporary workaround created by the agent to work around a failed tool call can rank higher than the actual approved procedure for such a tool — the wording is the same, the embeddings are close, with no signal indicating which one is temporary and which one is approved. The solution is not a better vector search — it is in refusing to write the temporary solution into the same database as the official procedure.Why One Bucket Doesn't WorkA single searchable memory index looks very elegant: one storage and retrieval interface for everything. But the complexity does not go away; it goes into the prompt — the model needs to determine at every moment what the retrieved piece is: a fact, an anecdote, an instruction, an obsolete preference, or simply a guess. Similarity is useful, but it does not guarantee the authority, scope, and purpose of retrieved information on its own.Five Design Principles for Real Memory ArchitectureIt is not necessary to use four different database products — a separation can be logical, not physical. What is important is the contract:Type everything explicitly. Use type, provenance, timestamp, owner, scope, confidence, and expiration time alongside the content of the information. Do not make the model infer the type later.Use different write rules for different memory types. Write the working memory information freely and expire it. Log the episodic memory after a meaningful experience. Extract the semantic facts with the proper conflicts checking. Promote procedures after the actual validation. The more influence this type of information can have on the agent's actions in the future, the harder it should be to write permanently.Search by purpose before searching by similarity. Decide what kind of information the agent needs (previously observed experience, a fact, or an approved procedure) — then search inside this kind, rank by relevance, recency, confidence, and scope.Define explicit promotion paths. Repeated episodes can support a semantic preference; several validated experiences can produce a candidate procedure. There should never be a silent promotion.Incorporate forgetting explicitly into your architecture. Expire the temporary data, supersede the outdated facts, archive unimportant experiences, validate procedures, and respect user deletion requests. More storage does not equal more memory.Where the Metaphor Breaks DownLet's be honest: the human-like memory is good up to a certain point. Human memory consolidates during sleep, decays gradually, and rebuilds on recall imperfectly. Agent memory does none of that by default: every write is intentional, every read is a query, and nothing expires unless the architecture says it should.This is the advantage: the memory system of the agent can enforce discipline a human brain never had — every fact has provenance, every procedure has an audit trail, there is a hard expiration date instead of natural forgetting. The taxonomy is useful. The anthropomorphism beyond it mostly gets in the way.The Database Is Not the Memory ArchitectureA vector database finds similar episodes. A graph represents entities and relationships in semantic memory. A relational database stores structured procedural versions with audit history. Most serious systems use different techniques — but none of them decides, on its own, whether the specific event is a precedent, a fact, a procedure, or noise. This is a responsibility of the layer on top of the database: classification, write rules, search routing, validation, promotion, forgetting.The agent doesn't need one big memory storage. It needs the right memory to appear at the right moment, with the right level of authority — and when something goes wrong, it needs to determine what part of the information led to that failure: experience, fact, procedure, or the current state of the agent. This is the difference between just storing the past and learning from it.But storing the right thing in the right bucket only solves half of the problem: the harder question remains: which memories deserve to become knowledge? A correct conclusion can come from a clean trajectory, a corrected mistake, or just a lucky guess — and if the system cannot distinguish these situations, even a well-structured memory architecture preserves the wrong lessons. Memory needs evaluation before it can become knowledge. That is the next piece.