Back to all posts
EngineeringSeptember 3, 202612 min read

The Four Kinds of Agent Memory, and What Actually Stores Each One

Working, episodic, semantic, procedural. Every agent framework now cites the same four boxes, borrowed from cognitive science by way of SOAR and CoALA. Here is what each one really is inside an LLM agent, the failure mode specific to each, and how the four map onto Memanto’s 13 semantic types and its retention policy.

Hetkumar PatelSoftware Developer
The Four Kinds of Agent Memory, and What Actually Stores Each One
MEMORY TYPES

Ask three teams what "agent memory" means and you will get three different architecture diagrams — but all three will have the same four boxes in them: working, episodic, semantic, procedural. That taxonomy is the closest thing this field has to a shared vocabulary. Most of the people using it could not tell you where it came from, which parts transfer cleanly to an LLM agent, or which of the four their own system is quietly missing.

This post is the field guide. What each type actually is, how it is really implemented in agents today, the failure mode specific to each, and — because a taxonomy you cannot execute is a poster — the command that stores each one.

Where the four types came from

The split is older than LLMs by half a century. Endel Tulving separated episodic memory (experiences you can place in time) from semantic memory (knowledge detached from the experience that produced it) in 1972. The symbolic cognitive architectures of the 1980s — SOAR, ACT-R — added procedural memory for skills and working memory for the current decision cycle.

In 2023, Princeton researchers ported the whole frame to LLM agents in Cognitive Architectures for Language Agents — CoALA — and the field adopted it almost immediately. LangChain’s LangMem documentation cites CoALA directly for its semantic/episodic/procedural split. Letta, Mem0, IBM, and MongoDB all ship a version of the same four boxes.

That lineage is worth keeping in mind, because it explains both the strength and the weakness of the taxonomy. The strength: these distinctions survived fifty years of scrutiny because they are real. The weakness: they were built to describe human cognition, and an LLM agent is not a person. Some of it transfers exactly. Some of it transfers badly. It is worth knowing which is which before you build four stores on the strength of a diagram.

The four types at a glance

TypeQuestion it answersTypical lifetimeWhere it actually lives in an agent today
WorkingWhat am I doing right now?One taskThe context window and the loop’s scratchpad
EpisodicWhat happened before?Days to monthsTranscript logs, conversation stores, trace backends
SemanticWhat is true?Months to foreverA knowledge base — if anyone built one
ProceduralHow do I do this here?Until the method changesModel weights, tool definitions, the system prompt, a markdown file

Read that last column and the shape of the problem is already visible. Two of the four are handed to you for free. One is a log you probably already have. The valuable one is the only one nobody gets by default.

1. Working memory — the one you already have

CoALA describes working memory as the active information available to the current decision cycle. In an LLM agent it is, almost exactly, the context window plus whatever scratchpad the loop keeps between steps. You do not build it. The model hands it to you on every call.

Two properties define it. It is rented by the token, repaid on every single call. And it vanishes when the loop ends — which is not a defect. A working memory that persisted would just be a long-term memory with worse hygiene and no policy.

The failure mode is the most common mistake in the entire category: teams treat working memory as the place where memory happens, so "adding memory to our agent" becomes "put more into the prompt." Every retrieved chunk you stuff in is paid for twice — once in tokens, once in the measurable degradation that long contexts inflict on the reasoning you rented them for. The purpose of long-term memory is to keep working memory small. If your memory system makes prompts longer, it is working against itself.

Memanto deliberately does not model working memory as a memory type. What it models is the boundary around one: a session is a time-bounded window — roughly six hours by default, configured server-side — that authorizes memory operations and marks where one stretch of work begins and ends. Memories outlive it on purpose.

bashmemanto session info      # the working-memory boundary: when it opened, when it lapses
memanto answer "Before this run: what is the fastest known path here, and what should I avoid?"

That second command is the whole discipline in one line. memanto answer returns a grounded briefing synthesized from the estate, not the estate itself. The agent gets the conclusion, not the archive.

2. Episodic memory — what happened

Tulving’s episodic memory is memory of experience, anchored to a time and a place. In an agent: what was attempted, what was said, what broke, and when. It is the type most teams implement first, because logging a transcript looks exactly like episodic memory and takes an afternoon.

The failure mode is volume. Episodic material is generated continuously by design — every turn, every tool call, every trace. It is the highest-volume and lowest-signal store you will ever own, and semantic search across raw episodes returns forty near-identical versions of the same Tuesday. We wrote about this in detail when building the Langfuse integration, where 812 raw observations correctly reduced to 2 memories. The number to internalize is the ratio.

An episode earns storage when it is distinguishable — an incident, a decision point, a failure with a signature. Not when it merely occurred.

In Memanto, episodic material lands as event, observation, or context. All three are situational and time-bound, and all three carry the shortest retention windows in every shipped policy preset — because that is what episodes are.

bashmemanto remember "Prod incident 2026-08-22: connection pool exhausted at 500 rps, resolved by raising pool size to 50" --type event
memanto remember "Build times spike Friday afternoons, cause unknown" --type observation
memanto remember "Mid-migration from REST to GraphQL, 60% of endpoints converted" --type context

The other half of episodic memory is being able to ask when. A store that can only answer "what do you know" is not episodic, whatever you tag it. Memanto exposes three temporal modes on recall:

bashmemanto recall --recent --limit 10                  # what did we learn most recently
memanto recall --changed-since "last week"          # what moved since then
memanto recall --as-of 2026-07-01                   # what we believed on that date

That third one is the query a transcript log cannot answer at all. A log has one tense.

3. Semantic memory — what is true

Semantic memory is general knowledge, detached from the episode that produced it. You know your deploy pipeline requires a green typecheck. You have long since forgotten which broken build taught you that. The claim survived; the episode did not need to.

This is where nearly all the durable value in agent memory sits, and it is the type most often claimed and least often actually built. The reason is a category error that is easy to make and expensive to keep:

A vector store full of conversation chunks is not semantic memory. It is episodic memory with better search.

The distinguishing property of semantic memory is that it cannot be logged — only distilled. The episode goes in, a claim comes out, and something has to perform that reduction. In most stacks, nothing does. Letta gives the agent tools to promote observations from recall into archival memory, which is the right shape — but it leaves the decision to the agent, and in practice production deployments rarely make the call at all. The store fills with episodes and everyone calls it semantic memory because the embeddings are semantic.

In Memanto this is the bulk of the 13 semantic typesfact, decision, learning, relationship, artifact, goal, commitment — and the distillation step is a command rather than an aspiration:

bash# Episode in, typed claims out. --dry-run shows the candidates before anything is stored.
memanto remember --from-conversation ./session.json --dry-run
memanto remember --from-conversation ./session.json

# Or leave it running: nightly distill, merge duplicates, flag contradictions
memanto schedule enable

There is a second property of semantic memory that the cognitive taxonomy has no room for and that matters enormously in practice: how you came to believe it. Every memory Memanto stores carries a provenance value — explicit_statement, inferred, corrected, validated, observed, or imported — alongside a confidence score.

A fact a user stated outright at 0.95 confidence and a fact the system inferred from behavior at 0.4 are the same shape in the store and should never be trusted the same way. Provenance is what lets a policy tell them apart — the shipped balanced preset expires inferred memories below 0.5 confidence after fourteen days, and leaves stated ones alone forever.

bashmemanto remember "Acme requires idempotency keys on every payment write" --type fact --confidence 0.95 --provenance explicit_statement
memanto recall "payment constraints" --type fact --min-confidence 0.7

4. Procedural memory — how to do it here

In humans, procedural memory is skill: riding a bike, touch-typing. You cannot retrieve it as a statement, only perform it as an ability. This is the type that transfers to LLM agents least cleanly, because in an agent it is scattered across three places and only one of them is memory in any useful sense.

  • The weights — how to write Python, how to structure an argument. Genuinely procedural, genuinely not yours, and it does not update from your experience.
  • Tool definitions and the system prompt — yours, and procedural in effect, but they are a file a human edits. Nothing about them is learned.
  • The accumulated rules of this specific environment — "run pnpm typecheck before committing," "never use require() in this repo, it breaks the bundler silently." This is the only one that comes from experience, and it is the one that usually has nowhere to live.

The third bullet is the real work. LangMem’s answer — let the agent rewrite its own system instructions — is the most honest attempt in the field at treating procedural knowledge as something that updates. It also inherits every problem of an unmanaged store: a self-rewriting instruction set has no expiry, no provenance, and no owner for the moment two rewrites contradict each other. The agent is grading its own homework, in the file that determines its behavior.

Memanto keeps learned procedure in three types — instruction for procedures, preference for style, and error for the anti-patterns that already cost someone a day.

bashmemanto remember "Run pnpm lint && pnpm typecheck before every commit; CI rejects if either fails" --type instruction
memanto remember "Prefer explicit return types on all public functions" --type preference
memanto remember "Never use require() — pure ESM project, breaks the bundler with no clear stack trace" --type error

memanto recall "what should I avoid in this repo" --type error

That last query is procedural memory doing the one job procedural memory exists to do: arriving before the mistake, not after it.

The mapping, in one table

Cognitive typeIn MemantoWhat is distinctive about it
WorkingThe session — not a memory type at allA ~6h authorized window. Memories outlive it by design; briefing keeps it small.
Episodicevent, observation, contextShortest retention in every preset. Queried temporally (--as-of, --changed-since, --recent).
Semanticfact, decision, learning, relationship, artifact, goal, commitmentDistilled from episodes, never logged. Carries provenance and confidence.
Proceduralinstruction, preference, errorpreference and instruction never expire on a timer in any preset. error does — see below.

The mapping is lossy in both directions, and that is deliberate rather than sloppy. commitment ("ship the auth refactor before the June audit") is semantic in form but expires like an episode. relationship is semantic knowledge that behaves procedurally — it tells an agent where to route things. Memanto’s 13 types do not classify a memory by where it came from; they classify it by what question it answers, because that is the signal retrieval can act on. Origin is a fine way to draw an architecture diagram and a poor way to filter a query.

The part that surprises people: lifetime does not follow the taxonomy

Here is the retention half of Memanto’s shipped balanced preset, with each type annotated by its cognitive category:

yamlretention:
  context:     7d      # episodic
  event:       30d     # episodic
  error:       30d     # procedural
  observation: 60d     # episodic
  commitment:  90d     # semantic
  artifact:    180d    # semantic
  # fact, decision, goal, learning        (semantic)   -> never
  # preference, instruction, relationship (procedural)  -> never

Read the comment column top to bottom and the cognitive categories are shuffled. error is procedural knowledge and it ages out in thirty days, while fact is semantic and never does. commitment and artifact are both semantic and differ by a factor of two.

That looks wrong until you say it out loud. A bug you fixed six weeks ago is not a live hazard — it is history, and an agent that keeps routing around it is being slowed down by its own memory. A style preference is a live hazard forever. The axis that predicts how long a memory stays true is not where it came from. It is how fast the world underneath it changes — a property of the subject matter, not of the cognitive category.

Which is exactly why retention is a table you own and edit, not something a taxonomy hands you. Three presets ship as starting points, and applying one prints the full policy before it asks you to confirm:

bashmemanto policy list-preset                 # conservative | balanced | aggressive
memanto policy apply-preset balanced
memanto policy apply --dry-run             # every memory the sweep would stamp, before it stamps one

And expiring is not deleting. A memory that ages out keeps its content and gains two fields — expired_at and expired_by — so recall can tell you which rule retired it and when, and memanto memory restore puts it back:

text[ACTIVE]  Deploys go through the release bot
[EXPIRED] Deploys are manual via ssh
          Expired Aug 18, 2026 03:56 PM · policy: retention.context

Nothing expires on its own, either. A memory only moves to expired when a policy sweep runs, a conflict resolution retires it, or you expire it by hand. An agent with no policy set will keep everything forever — which is a decision, just rarely a considered one.

A checklist that works in any framework

None of this is Memanto-specific. You can build every piece of it on LangGraph’s store, on Mem0, on a Postgres table you own. The four types tell you what the boxes are; they do not tell you to do any of the following, which is why so few systems do it:

  • Working: measure it. If your agent’s prompt grows with the length of the conversation, you do not have a memory system — you have a leak with a retrieval step attached.
  • Episodic: store distinguishable episodes, not turns. If your episodic store grows linearly with traffic, it is a log, and it will drown recall long before it helps it.
  • Semantic: name the process that converts episodes into claims. If you cannot name it, you do not have semantic memory yet, however semantic your embeddings are.
  • Procedural: give learned rules a home outside the system prompt, and decide who owns the case where two of them disagree. "The agent will figure it out" is not an owner.
  • All four: every memory needs a provenance and an expiry answer. "Forever, because nobody wrote a policy" is an answer — it is just the worst one available.

Mem0’s own State of AI Agent Memory 2026 report lists staleness among the open problems of the field. Three years into a shared vocabulary that every major framework cites, the question "is this still true?" is still open — largely because the vocabulary never had a word for it. Four nouns, no verbs.

Find the empty box in your own agent

The fastest way to see which of the four kinds your agent actually has is to look at what it has stored, grouped by type:

bashpip install memanto
memanto agent create my-agent
memanto agent bootstrap          # an intelligence snapshot: total memories, sampled and grouped by type

In our experience the empty box is almost always the semantic one. Plenty of episodes, because logging is easy. Plenty of procedure, because it lives in a system prompt someone wrote. And nothing in between that turned the first into durable, retrievable claims — which is the transition the whole taxonomy is quietly built around and the only one it never tells you to implement.

Four types is a good map. It tells you what to store. It never tells you what to stop believing — and at month six, that is the question deciding whether your agent’s memory is an asset or a liability.
▘ ▝End of article
CONTINUE READING