Skip to content
Naveen Raj

Building AI Agents from Scratch with Python · Building the Core Loop

Giving the Agent Memory

"Memory" for an agent is nothing exotic — it's what you choose to keep in messages (or wherever you persist it) across turns. There are three tiers worth knowing:

  • Working memory — the messages list itself. Everything the model can see right now. This is what we built above.
  • Short-term memory — persisting messages across process restarts (e.g. to a file or Redis key), so a conversation survives a server restart.
  • Long-term memory — a separate store (usually a vector DB) the agent can search, rather than something that's always in context. This is what lets an agent "remember" something from three weeks ago without paying the token cost of keeping it in every request.

A minimal short-term version — persisting to a JSON file — looks like this:

import json
from pathlib import Path

MEMORY_FILE = Path("conversation.json")


def load_history() -> list[dict]:
    if MEMORY_FILE.exists():
        return json.loads(MEMORY_FILE.read_text())
    return []


def save_history(messages: list[dict]) -> None:
    MEMORY_FILE.write_text(json.dumps(messages, default=str, indent=2))

Call load_history() at startup instead of history = [], and save_history(history) after every turn. That alone is enough for the agent to pick up a conversation across restarts.

A common mistake: reaching for a vector database on day one. Working memory plus a JSON file covers the large majority of real agents — most tasks don't actually need semantic search over history, and adding it before you need it is pure complexity for no measured benefit.