Summary of Today’s Gen AI Agents Session: Five Kinds of Memory – Building a Stateless Support Agent (27 Oct 2026)

Today we started the memory module properly: the taxonomy first, then a deliberately forgetful agent to make the problem concrete.

1. Five Types of Memory

TypeWhat it holds
WorkingThe immediate context passed to the model on this one call
Short-termThe conversation, for the length of this session
SemanticDurable facts about a user — preferred language, contact channel
EpisodicA record of specific past events
ProceduralHow to carry out a task

The framing that matters: memory is a lifecycle, not a database.

The hard questions are when do I write this, and what is it for — not where it’s stored. Files, SQL, a vector store: the storage choice is downstream of the lifecycle design, and it’s the easy part. Get the lifecycle wrong and no database saves you.

This is also why the model itself has no memory to speak of. Working memory is just what you chose to send this time.

2. The Build: Quick Byte Support

A customer support agent for a fictional food-delivery app. We’re building it stateless first, deliberately, so the gaps are obvious before we fill them.

The system prompt rules:

  • The agent is a support representative for Quick Byte.
  • For anything about order status, ETA or items, it must always call get_order_status.
  • It must never answer order details from memory.

That last rule is the interesting one. Order status changes in real time. A model answering from what it saw earlier in the conversation will confidently tell a customer their food is on the way after it’s already been delivered. The rule exists to force a fresh lookup every time.

3. The Tool

@tool
def get_order_status(
    customer_id: str,
    order_id: Annotated[str, "The order reference, e.g. QB-5521"],
) -> dict:
    """Look up the live status of an order for a given customer."""
    order_id = order_id.strip().upper()
    ...
  • .strip() and .upper() mean qb-5521, QB-5521 and QB-5521 all resolve. Users are not careful typists.
  • Annotated isn’t decoration — the description lands in the schema the model reads when deciding how to call the tool.
  • Success returns the order as JSON through a shared ok() helper.
  • Failure goes through fail(), which marks the result as an error so the model knows the lookup failed rather than treating the error text as order data.

4. Project Structure

common.py holds shared logic and the mock data:

ORDERS = {
    "101": {"order_id": "QB-5521",
            "status": "Out for delivery",
            "items": "2 veg biryani"},
}

A build_tools() function returns the full list of tools in one place. Adding a tool means appending to one array, not hunting through files. Small discipline now, large payoff at twenty tools.

Environment: CLAUDE_CODE_DISABLE_AUTO_MEMORY controls the SDK’s automatic memory handling. We’re setting it now so the next session’s memory work is explicit rather than fighting something invisible.

One practical note: the first run failed on an invalid API key. Check your .env before assuming the code is wrong — the error message isn’t always obvious about it.

5. Where This Goes

Next session adds the chat loop, then working memory — and from there, the move from stateless to genuinely stateful.

✅ Action Items

  1. Build the same agent in a different domain — bus booking, for instance. Same structure, different tools. That’s the fastest way to make the pattern yours.
  2. Get the stateless version running end to end, including the failure path for an unknown order.
  3. Be ready to explain the five memory types and when you’d reach for each.

⏭️ Next up: the chat loop, working memory, and making this agent remember.

By continuous learner

enthusiastic technology learner

Leave a comment