DEV Community

Sagar Kewat
Sagar Kewat

Posted on

The 3-Tier Agent Memory System: Working, Semantic, and Episodic Storage

The 3-Tier Agent Memory System: Working, Semantic, and Episodic Storage

When we first start building AI agents, we all make the same mistake. We take the entire chat history, dump it into a massive system prompt, and hope the LLM figures it out.

In a hobby project, this works fine. In production, it’s a recipe for disaster.

As your agent runs longer, that massive prompt turns into a black hole. It eats up your token budget, slows down response times, and triggers severe hallucination loops. In the engineering world, we call this context rot—the point where your agent gets so overwhelmed by past chatter that it forgets what it was supposed to do in the first place.

To build reliable, production-grade agents in 2026, you have to treat agent memory exactly like we treat computer memory. You need a structured, tiered storage system.

Here is how we break down agent memory into three distinct tiers: Working, Semantic, and Episodic.


1. Working Memory (The Active Scratchpad)

Working memory is what your agent is thinking about right now. It’s the immediate, short-term state needed to complete the current sub-task.

If your agent is processing an e-commerce refund, the working memory shouldn't contain the user's entire 3-year purchase history. It only needs:

  • The current step in the refund flow.
  • The specific order ID being processed.
  • The validation status of the return item.

How to build it: Keep this in a fast, structured, local-first state store (like a simple in-memory key-value store or a local SQLite instance). We enforce strict schemas using tools like Zod in TypeScript to ensure the agent's active state never drifts into weird, unexpected formats.

import { z } from "zod";

// Define a strict schema for the agent's active step
const WorkingMemorySchema = z.object({
  currentTaskId: z.string(),
  stepIndex: z.number(),
  extractedVariables: z.record(z.string(), z.any()),
  pendingToolCalls: z.array(z.string()),
});

type WorkingMemory = z.infer<typeof WorkingMemorySchema>;
Enter fullscreen mode Exit fullscreen mode

By keeping working memory lean and highly structured, you keep your immediate LLM prompts tiny, fast, and incredibly accurate.


2. Semantic Memory (The Deep Knowledge)

Semantic memory is your agent’s textbook. It’s where you store long-term facts, business rules, API documentation, and user preferences.

Unlike working memory, semantic memory is not passed directly into the prompt on every turn. Instead, it sits in a vector database or is accessed dynamically via the Model Context Protocol (MCP).

When the agent encounters a question like "What is our return policy for opened electronics?", it queries its semantic memory, pulls out the exact policy snippet, and injects only that snippet into the context window.

How to build it: Use a vector database (like pgvector or Qdrant) paired with a semantic search pipeline. When the agent acts, run a background step that searches this knowledge base based on the user's intent, pulling in relevant context only when confidence scores are high.


3. Episodic Memory (The Immutable Audit Log)

Episodic memory is the story of what happened. It is a chronological, immutable log of every single action, tool execution, and LLM response during a session.

Think of it as your agent's time-machine. If an agent goes off the rails—say, it tries to call an API with the wrong arguments three times in a row—you don't want it to keep spinning in a loop.

With episodic memory, you have a complete audit trail. If the agent steps out of line, your system can catch the error, roll back the agent's working state to a previous healthy "episode," and try a different path.

How to build it: Treat episodic memory as a append-only database table. Every time your agent loop executes a tool or receives an LLM output, write a record containing:

  • A timestamp
  • The action taken
  • The result or error code
  • A snapshot of the working memory at that exact moment

This makes debugging production agents incredibly simple. When a customer reports a bug, you don't have to guess what the LLM was thinking; you just replay the episodic log step-by-step.


Putting It All Together: The Agent Loop

Here is how these three tiers interact in a modern, production-ready agent loop:

[ User Input ] 
      │
      ▼
1. Query Semantic Memory ──► (Retrieve relevant docs/facts via MCP)
      │
      ▼
2. Load Working Memory   ──► (Get current task state & variables)
      │
      ▼
3. Run LLM / Execute Tool
      │
      ├────────────────────► 4. Write to Episodic Memory (Log the action)
      │
      ▼
5. Update Working Memory ──► (Set next step / save new variables)
Enter fullscreen mode Exit fullscreen mode

By separating these concerns, you stop wasting money on massive token payloads, eliminate the noise that causes LLMs to hallucinate, and build a system that you can actually monitor and debug.


Your Actionable Production Checklist

  1. Cap Your History: Never pass more than 3-5 of the most recent chat messages in your raw prompt. Let semantic and episodic retrieval handle the rest.
  2. Schema-Validate State: Use Zod or Pydantic to validate your agent’s working memory after every turn. If the state doesn't match the schema, halt and recover.
  3. Build an Audit UI: Create a simple internal dashboard where your team can view the episodic logs of active agent runs in real time. It will save you hundreds of hours of debugging.
  4. Adopt MCP: Use the Model Context Protocol to standardize how your agents fetch data from your databases and external tools.

Building in the AI space is incredibly exciting right now, but the winners will be the ones who build stable, predictable systems that don't break under real-world usage.

If you're building AI agents, SaaS, or production systems and want to chat about architecture, reach out over at sagarithm.in. Let's build something great.

Top comments (0)