Skip to content
advanced

Memory Engineering for AI Agents: Short-Term, Semantic, Episodic, and Procedural Memory

The agent remembered everything and still got the user wrong. It recalled a preference the user had abandoned six months ago, re-derived a workflow it had…

Published 2026-09-11Updated 2026-09-1219 min read
Explore a futuristic corridor with vibrant green lighting and modern design elements.
Explore a futuristic corridor with vibrant green lighting and modern design elements. Photo by Vladimir Srajber on Pexels.

The agent remembered everything and still got the user wrong. It recalled a preference the user had abandoned six months ago, re-derived a workflow it had already learned twice, and answered a policy question with a story about a Tuesday. Nothing was broken in the retrieval pipeline. The store was full, the embeddings were fresh, and the context window had room. The memory layer was simply undifferentiated — one bucket holding facts, events, and instructions, retrieved by cosine similarity and injected in whatever order the scores happened to fall.

That is the failure mode memory engineering exists to fix. Memory is not a bucket. It is a set of typed stores, and each type earns its place by changing a specific future decision. If you cannot name the decision a memory changes, you are keeping a log, not building memory.

This article assumes you already have working context assembly and retrieval. The write/select/compress/isolate vocabulary and the transient-versus-persistent distinction are the substrate here, not the subject. What follows is the layer above: how to split memory by type, what earns a write, what triggers a read, how wrong memory gets corrected, and what must be allowed to die.

Memory Is Not One Store

The default architecture is a single vector store of conversation chunks. It works until it doesn't, and it fails in a specific way: retrieval returns the wrong kind of thing at the wrong time. A user asks "what's my deployment process?" and gets back an episode — the time they deployed on a Friday and it went badly — instead of the procedural rule that governs deployments. Both are semantically similar to the query. Only one answers the question.

The fix starts with an admission test. Before anything enters memory, name the future decision it must change. If no decision changes, it is a log entry. Logs are valuable for debugging and audit; they are not memory. The distinction matters because logs can grow without bound and memory cannot.

A trace is evidence of what happened. It becomes memory only when a lesson is converted into context a later run can retrieve and act on. Most of your traces should stay traces.

Every memory type in this article is defined by a four-question contract:

  1. What decision does it serve? The future action this memory is supposed to change.
  2. What writes it? The trigger that admits new content.
  3. What reads it? The trigger that pulls it into context.
  4. What retires it? The rule that expires, supersedes, or deletes it.

If you cannot answer all four for a store you are maintaining, you have a store with no owner, and it will drift.

The Lifecycle: From Run State to Retired Memory

A left-to-right flowchart moves from run state to trace to an admission decision. Rejected traces remain logs; admitted candidates become typed memory, can be retrieved or promoted through a gate, and can later be superseded or retired.
Memory is not persistent by default: traces must pass admission and promotion gates before they can influence future runs, and every durable entry needs a retirement path.

Before the taxonomy, the state machine. The most common implementation mistake is collapsing three distinct states into one store: live working context, persisted session history, and durable memory eligible for future retrieval. They have different lifetimes, different write rules, and different failure modes.

run state ──(run ends)──> trace ──(admission test)──> candidate
                                                          │
                                          ┌───────────────┴───────────────┐
                                          │                               │
                                    rejected                        admitted
                                    (stays a log)                   (typed entry)
                                          │                               │
                                          │                    ┌──────────┴──────────┐
                                          │                    │                     │
                                          │              retrieved            superseded
                                          │              (used in a           (dated prior,
                                          │               decision)            new value current)
                                          │                    │                     │
                                          │                    │              ┌──────┴──────┐
                                          │                    │              │             │
                                          │                    │         promoted      retired
                                          │                    │         (gated)       (expired)

The invariant that matters: visibility in the current context is not persistence, and persistence is not eligibility for future retrieval. A tool result visible in the current turn is run state. A compressed session summary persisted to disk is session history. Neither is automatically memory. Promotion from trace to durable memory requires passing the admission test, and promotion from one memory type to another requires passing a gate — not just repetition.

Never auto-promote transient control state — retry counters, scratch variables, intermediate reasoning — into durable memory. It is run-scoped by definition, and persisting it pollutes retrieval with artifacts that were never meant to outlive the task.

Knowledge check

Check your understanding

Answer this question before you continue.

Which statement correctly applies the lifecycle invariant?
Misconception Check

Focus: Distinguish current run state, persisted history, and durable memory eligibility when designing an agent memory pipeline.

The Four Memory Types and the Decisions They Serve

The taxonomy is borrowed from cognitive science, and the borrowing is useful precisely because it forces a separation that flat stores collapse. The analogy breaks in one important place: agents have no biological consolidation. Human memory consolidates whether you plan for it or not. Agent memory consolidates only if you build the pipeline step. That is the whole game.

Short-term (working) memory is the live state of the current task: the thread, recent tool results, intermediate artifacts, scratch files. It serves one decision — what do I do next in this run. It is scoped to the run and dies with it.

Semantic memory holds durable facts, preferences, and entity relationships. It serves the decision what is true about this user, project, or domain. "The user prefers TypeScript." "The staging cluster is in eu-west-1." "This project uses Postgres, not MySQL."

Episodic memory holds specific past interactions, actions, and outcomes with time and context attached. It serves the decision has this happened before, and what happened then. "Last time we migrated this schema, the foreign key constraint failed on the orders table."

Procedural memory holds instructions, workflows, tool-use rules, and learned skills. It serves the decision how should I behave on this class of task. "When asked to deploy, run the test suite first, then tag, then push." Procedural memory is where most visible behavior improvements come from, because it is the type that changes what the agent does rather than what it knows.

TypeDecision servedEvidence required to admitScope / preconditionTypical read triggerRetirement ruleFailure when misclassified
Short-termWhat next in this runAny turn outputCurrent run onlyAlways presentDies with runLeaks into long-term as noise
SemanticWhat is trueExplicit instruction or repeated confirmationEntity or domainEntity match or query matchSupersede on contradiction; confidence decayStale facts outrank current ones
EpisodicHas this happened beforePost-action capture with outcomeTime-bounded eventSimilar-task recall or event triggerTime-based expiry; access reinforcementEpisodes answer policy questions
ProceduralHow to behaveSuccessful action pattern + scope + reviewTask class with preconditionsTask-class match; always-on for pinned rulesSupersede on better rule; review cadenceOver-generalized rules misfire in new contexts

The table is the taxonomy. The prose does not need to repeat it. What the table cannot show is the consolidation pathway that makes the system compound — and that pathway needs gates, not assumptions.

Promotion Gates: Why Repetition Is Not Enough

The attractive teaching model says repeated episodic patterns become semantic facts, and repeated semantic patterns become procedural rules. That model is too smooth for an engineering decision guide. A repeated observation may support a preference. A procedural rule requires more: an action, a scope, preconditions, and evidence that the action improved outcomes.

Episode → candidate fact requires repeated evidence or explicit user confirmation. Three sessions where the user corrected the agent's date format is enough to propose a semantic fact about their preference. One session is not.

Fact or episodes → procedure requires a successful action pattern, a defined scope, preconditions, and a review or rollback path. The fact that the project's test command is pytest -x does not automatically become "always run tests before deploying." That procedural rule needs evidence that running tests before deploying actually prevented failures in this project's context.

Here is a promotion that should be rejected. An agent observes three sessions where the user asked for a summary before a detailed answer. The system proposes a procedural rule: "always summarize first." But the user only asked for summaries in the context of long documents, not in code review or debugging sessions. The repetition is real; the scope is wrong. Without a precondition — "when the input is a long document" — the rule will misfire in every other context.

Promotion is a policy decision, not an automatic hierarchy. Mark it as optional. If you cannot state the scope and preconditions of a procedural rule, you do not have a rule — you have a correlation.

Knowledge check

Check your understanding

Answer this question before you continue.

An agent observes that a user requests summaries in three long-document sessions and proposes “always summarize first.” What is the key reason to reject or revise this promotion?
Scenario Interpretation

Focus: Apply promotion gates by identifying the scope and preconditions required before an observed pattern becomes a procedural rule.

Write Policies: What Earns a Slot

Memory grows by accident unless you make writing a decision. The first lever is the trigger, and the triggers have different cost profiles.

End-of-session consolidation runs after the run completes. It is cheap in latency terms because nothing is waiting on it, and it sees the whole trajectory, which makes it better at extracting durable signal than inline extraction. It is worse at capturing things that only make sense mid-run.

Inline extraction runs during the run. It is fast and contextually accurate but expensive per turn and prone to over-eager capture — a passing remark becomes a permanent preference.

Explicit user instruction is the highest-precision trigger. When a user says "remember that I prefer X," that is a write with a clear owner and a clear justification.

Post-failure reflection runs when something goes wrong. It is the primary source of procedural memory, because failures are where the gap between the agent's rules and reality becomes visible.

Whichever trigger you use, the admission criteria are the same. A candidate memory must be durable (will this still be true later), specific (does it name an entity, constraint, or rule), and decision-relevant (does it change a future action). A memory that fails any of the three is a log entry.

Then there is the update semantics question, and it is a real tradeoff, not a preference. Append-only accumulation preserves auditability — you can see every version of a fact and when it was written — but it lets contradictions coexist, and retrieval has to resolve them at read time. Update-in-place keeps a clean current state but destroys the evidence trail, which makes debugging memory failures nearly impossible. Supersede-with-history is the middle path: the new value becomes current, the old value is retained as a dated prior. I default to supersede-with-history for anything a user might ask about later, and update-in-place only for high-churn, low-stakes fields.

Temporal validity is the part most implementations skip. Store when a fact became true and when it stopped being true. Without those two timestamps, retrieval cannot rank the right dated instance for a current-state question, and the agent will confidently report a preference the user abandoned last quarter.

One more write rule that pays off: when the agent confirms an action, that confirmation is a first-class memory candidate, not a side effect. "I created the branch" is a fact about the world that a later run may need.

The failure mode to plan for is memory poisoning through over-eager extraction. A one-off remark — "I'm thinking about switching to Rust" — becomes a permanent preference, and every subsequent response is colored by a decision the user never made.

Retrieval Triggers: When Memory Should Enter the Context

The read side has two failure modes and they are opposites. Starvation: relevant memory exists but never gets pulled in, so the agent re-derives what it already knew. Flooding: too much memory gets injected, and the signal drowns in its own context.

The defense against flooding starts with pinning. A small set of identity and policy facts can be always-present — the user's name, the project's language, the non-negotiable rules. Everything else should be selected per decision. Pinning is expensive because it consumes attention budget on every turn, so the pinned set should be small enough that you can list it from memory.

But here is the boundary that matters more than pinning: immutable or safety-critical constraints belong in application logic or versioned instructions, not in memory. Authorization rules, compliance requirements, and safety guardrails must be enforced by the runtime, not retrieved from a mutable store. Memory may supply user or project-specific preferences and candidate procedures. It cannot be the sole enforcement layer for anything that must not fail.

For everything else, retrieval triggers fall into three classes. Query-driven retrieval fires when the current request has a semantic match in the store. Entity-triggered lookup fires when a named entity appears — a user, a project, a service — and pulls the facts attached to it. Event-triggered recall fires at task boundaries, pulling episodic memory relevant to the task about to start.

The retrieval mechanism matters as much as the trigger. Semantic similarity alone misses exact identifiers and entity relationships; a query for "the orders table" may not match a memory that says "orders_v2" if the embedding space does not place them close. Multi-signal retrieval — fusing vector search with keyword and entity matching — covers query shapes that similarity alone cannot. This is not a novel claim; it is the same lesson reranking taught, applied to memory instead of documents.

Then cap the injection. Every retrieved memory should be measured for whether it changed the output. Unused retrieved memory is pure cost and interference — it occupies attention budget and gives the model more surface area to be distracted by. If a memory is retrieved and never used across many runs, that is an investigation signal that the trigger may be wrong. It is not a diagnosis — some memories are retrieved for latent influence or defensive context — but it is the first thing to check.

The subtle failure is retrieval that returns a plausible but wrong-typed memory. An episode answering a policy question. A stale fact outranking a current one. The output looks fine until you check it against the decision it was supposed to serve.

Knowledge check

Check your understanding

Answer this question before you continue.

Which design best follows the article’s boundary between retrieval and enforcement?
Comparison Reasoning

Focus: Decide which constraints must remain in application logic rather than relying solely on mutable memory retrieval.

Correction Paths: Fixing Memory That Is Wrong

Every memory system will store something wrong. The question is whether correction is a designed subsystem or an afterthought. Silent overwrites are dangerous because they destroy the evidence needed to explain a past decision, and because they hide the fact that the system was wrong.

There are three correction sources. Explicit user edit is the highest-authority source and should be treated as such. Agent-detected contradiction happens when a new fact conflicts with a stored one; the system needs a precedence rule — recency, source authority, or explicit user confirmation — and it needs to apply that rule consistently. Offline review of traces catches the errors that neither the user nor the agent noticed, and it is the only source that can find systematic extraction problems.

The correction action itself has two modes. Supersede when the history matters for audit or for explaining a past decision: keep the old value as a dated prior and mark the new value current. Hard-delete when the content is sensitive or the user asked for removal. The distinction should be a policy, not a judgment call made at the moment of correction.

User-visible memory is the highest-leverage correction feature you can ship. Exposing what the agent retained, with read, edit, and delete controls, converts silent memory drift into a debuggable surface. It also gives the user a reason to trust the system, because they can see what it knows and correct it directly.

Sensitive-data policy belongs here too. Some categories should be excluded by default and stored only on explicit opt-in, with notification when they are saved. This is not just a compliance concern; it is a correctness concern, because sensitive facts are the ones most likely to be wrong and most damaging when they are.

The failure mode that bites hardest: correction that updates the store but not the retrieval index. The agent keeps reading the old value because the index was never rebuilt. If your correction path does not include index invalidation, it is not a correction path.

Knowledge check

Check your understanding

Answer this question before you continue.

A user edits a stored preference, but the agent continues retrieving the old value. The database contains the new value. Which missing step most directly explains the failure?
Debugging

Focus: Diagnose why corrected memory remains retrievable and include index invalidation in the correction path.

Forgetting: Decay, Consolidation, and Retention Policy

Unbounded memory degrades. An ever-growing store dilutes retrieval precision, increases latency, and preserves facts that are no longer true. Forgetting is not a concession to storage limits; it is a requirement for retrieval quality.

Three decay mechanisms cover most cases. Time-based expiry retires memories after a fixed window — appropriate for episodic memory tied to a specific project phase. Access-frequency reinforcement keeps memories that are repeatedly retrieved and lets the rest fade, which mirrors how relevance actually works. Confidence decay lowers the weight of a memory that is never confirmed, so an unverified fact gradually loses precedence to a verified one.

Consolidation is the pipeline that makes memory compound instead of accumulate — but only when it runs through the promotion gates described earlier. Repeated episodic patterns get promoted into semantic facts: three sessions where the user corrected the agent's date format becomes a semantic fact about their preference. Repeated semantic patterns get promoted into procedural rules: a fact about the project's test command becomes a procedural rule about running tests before deploying — but only after the gate confirms scope, preconditions, and evidence that the action improved outcomes.

Retention tiers make the policy explicit. Session-scoped memory dies with the run. Project-scoped memory lives as long as the project. User-lifetime memory persists across projects. Permanent pinned facts never expire but are reviewed on a cadence. Each tier needs its own expiry rule and its own review schedule, and the review schedule is what catches the memories that should have died but didn't.

The failure mode here is consolidation that over-generalizes a single episode into a permanent rule. One bad deployment becomes "never deploy on Fridays," and the agent is confidently wrong in a context where Friday deploys are fine. Consolidation needs a threshold — repeated evidence, not a single instance — before it promotes anything.

Evaluating a Memory System

Memory design arguments are unwinnable without measurement. The measurement that matters is at the decision level, not the store level.

Build a test set where each case depends on a specific memory type being present, absent, or superseded. For semantic memory: a case where the correct answer depends on a stored preference. For episodic: a case where the correct answer depends on recalling a past outcome. For procedural: a case where the correct behavior depends on a learned rule. Then write the negative cases explicitly — stale fact present, contradictory facts present, sensitive fact present, no relevant memory present. The negative cases are where most memory systems fail, and they are the cases most teams skip.

Measure retrieval precision at the decision: did the injected memory change the output in the intended direction? Recall at the store is a vanity metric. A memory that is retrieved and ignored is worse than a memory that was never retrieved, because it consumed budget and added noise.

Track operational signals over time: write volume per session, retrieval latency, memory count growth, correction frequency. A memory count that grows without bound while correction frequency stays flat is a sign that nothing is being retired.

Long-horizon evaluation is the hardest and the most informative. Run multi-session scenarios where the correct answer depends on something learned several sessions earlier, and check whether consolidation preserved it. This is where you find out whether your promotion pipeline actually works or just looks like it does.

Published benchmark numbers for memory systems are results under specific test conditions and datasets. They do not transfer directly to your workload. Treat them as directional evidence about what is possible, not as guarantees about what you will get.

Choosing a Memory Architecture for Your Agent

Start from the smallest thing that works. A filesystem with clear naming conventions handles a surprising number of agents. A single store with disciplined metadata handles more. Add typed stores only when a specific decision is failing — when you can name the decision and the failure that occurs without the type.

The decision rule is the four-question contract from the first section. Add a memory type when you can answer all four questions for it. If you cannot name the decision it serves, you are adding complexity without a payoff.

There are cases where typed memory is overkill. Short-lived sessions, single-turn tasks, and agents whose state is fully reconstructible from the current request do not need it. Building typed memory for these is premature architecture, and it will cost you maintenance without changing behavior.

Build-versus-buy is a real decision with a real tradeoff. Managed memory layers handle extraction, deduplication, and retrieval plumbing, which is genuinely hard to get right. But they also own your write policy and your correction semantics, and their defaults may not match your retention and sensitivity requirements. Check the defaults before you adopt. If the managed layer's write policy is append-only and you need supersede-with-history, you are fighting the tool.

The migration path I would follow: instrument first. Log every retrieval and whether it was used. Once you can see which retrievals are being ignored or misused, split the store by type. The instrumentation tells you which type to build first, and it gives you the baseline to measure against.

The Next Move

Pick one recurring failure in an agent you already run. Trace it back to a missing or misclassified memory type. Then write the four-line contract for that type — decision served, write trigger, read trigger, retirement rule — and implement only that one type. Measure whether the failure rate drops.

The durable rule is this: memory is justified by the decision it changes, and every memory you keep is a claim about the future that you are obligated to maintain. Keep fewer, typed, dated claims. Retire the ones that stop being true. The agent that remembers less, but remembers the right things, is the one that gets the user right.

Knowledge check

Final check

Finish the article by checking the ideas you just learned.

A team wants to add a new typed memory store, but cannot state what future decision it changes, what writes it, what reads it, or what retires it. What should the team do first?
Question 1 of 2Scenario Interpretation

Focus: Use the four-question contract to determine when introducing a typed memory store is justified.

Which evaluation plan best matches the article’s recommended measurement approach?
Question 2 of 2Comparison Reasoning

Focus: Select decision-level evaluation measures that reveal whether retrieved memory improves the intended output without adding harmful noise.

References

  1. How to Build Memory into AI Agentswww.langchain.com
  2. GitHub - mem0ai/mem0: The Memory Layer for AI Agentsgithub.com
  3. Claude Cowork finally remembers what you told the app in chat - TechCrunchtechcrunch.com
8sources checked
8source domains
10searches run

Research updated Sep 11, 2026

Related sites

Build the foundations behind advanced AI systems

Use LearnLLMFast for practical LLM application foundations and LearnPyFast for the Python mechanisms that support implementation work.

LLM tutorialstutorial

LearnLLMFast

Practical LLM tutorials for builders who want to understand prompting, workflows, agents, and AI applications.

LLMAIBuilders
Visit LearnLLMFast
Python tutorialstutorial

LearnPyFast

Beginner-friendly Python tutorials, examples, and learning paths for practical programming foundations.

PythonProgrammingBeginners
Visit LearnPyFast

Keep exploring

Related AI engineering tutorials

Continue with adjacent system layers, implementation patterns, and current AI engineering ideas.