TAI BUI
Back to curriculum
BuildPython

Memory: Virtual Context and MemGPT

Context windows are finite. Conversations, documents, and tool traces are not. MemGPT (Packer et al., 2023) treats the problem like OS virtual memory: main context is RAM, the external store is disk, and the agent pages between them. Every 2026 memory system inherits this pattern.

TIME: ~75 minutesPREREQUISITES: Phase 14 · 01 (Agent Loop), Phase 14 · 06 (Tool Use)

Learning Objectives

  • Explain the OS analogy MemGPT builds on: main context = RAM, external context = disk, memory tools = page in/out.
  • Implement the two-tier MemGPT pattern in stdlib with a main-context buffer, an external searchable store, and page in/out tools.
  • Describe how the agent issues "interrupts" to query or modify external memory and how the result is spliced back into the next prompt.
  • Identify the MemGPT design choices that carry into Letta (Lesson 08) and Mem0 (Lesson 09).

The Problem

A bigger context window looks like the answer to memory. It isn't. Three failure modes keep showing up in production:

  1. Overflow. Long conversations, long documents, and tool-heavy trajectories cross the window, and everything past the cutoff is gone.
  2. Dilution. Inside the window, irrelevant context still pulls attention away from what matters. Frontier models degrade on long inputs.
  3. Persistence. A new session starts with an empty window, so an agent with no external memory can never say "remember when you asked me to..." across sessions.

Bigger windows help but don't fix any of this. Mem0's 2025 paper measured that 128k-window baselines still miss long-horizon facts that a 4k-window agent with external memory catches.

Warm-up0/3
1. In a normal computer, what happens when a running program needs more data than fits in RAM?Warm-up
2. A chat assistant starts a brand-new session tomorrow. What does it know about today's conversation by default?Warm-up
3. A program must look up facts in a table with millions of rows, far more than fits in memory. What is the usual approach?Warm-up
Check: The Problem0/2
1. Why does a bigger context window not fix dilution?Explain
2. A team plans to fix "remember when you asked me to..." across sessions by moving to a 128k window. Why will this not work?Analyze

The Concept

MemGPT: the OS analogy

MemGPT is a design that treats the prompt as small, fast memory and an external searchable store as large, slow memory, with the agent moving data between the two through tool calls. Packer et al. (arXiv:2310.08560, v2 Feb 2024) borrow the idea straight from operating-system virtual memory:

OS conceptMemGPT concept2026 production analog
RAMmain context (prompt)Anthropic/OpenAI context window
Diskexternal contextvector DB, KV, graph store
Page faultmemory tool callmemory.search, memory.read, memory.write
OS kernelagent control loopReAct loop with memory tools

The agent runs a normal ReAct loop. The only addition is one extra class of tools that page data in and out of main context.

Two tiers

  • Main context. A fixed-size prompt holding the current task, including the core memory sections pinned inside it. The model always sees all of it.
  • External context. Unbounded and searchable through tools: the archival store, plus past conversation turns reachable through conversation_search. The agent reads it when something is relevant and writes to it when new facts emerge.

The original paper tested the design on two tasks that a base window can't handle: document analysis over 100k tokens, and multi-session chat with persistent memory across days.

The interrupt pattern

MemGPT calls this memory-as-interrupt. Mid-conversation, the agent invokes a memory tool, the runtime executes it, and the result splices into the next assistant turn as a new observation. It works like a Unix read() syscall: the process blocks, gets its bytes back, and carries on.

The canonical memory tool surface:

  • core_memory_append(section, text) writes to a persistent section of the prompt.
  • core_memory_replace(section, old, new) edits a persistent section.
  • archival_memory_insert(text) writes to the searchable external store.
  • archival_memory_search(query, top_k) retrieves from the external store.
  • conversation_search(query) scans past turns.

Where MemGPT ends and Letta begins

MemGPT became Letta in September 2024. The research repo (cpacker/MemGPT) is still there, and Letta extends the design in three ways:

  • Three named tiers instead of two: core, recall (past conversation), archival (Lesson 08). This splits the same ground differently: MemGPT's core memory already lives inside main context, and its conversation search covers what Letta calls recall.
  • Native reasoning in place of the send_message/heartbeat pattern (Lesson 08).
  • Sleep-time agents that do memory work asynchronously (Lesson 08).

Even when production runs on Letta, Mem0, or a custom two-tier store, the MemGPT paper is the foundation underneath.

Where this pattern goes wrong

  • Memory rot. Writes pile up faster than reads, and retrieval drowns in stale facts. The fixes are periodic consolidation (Letta sleep-time) and explicit invalidation (Mem0 conflict detector).
  • Memory poisoning. External memory is just retrieved text. If attacker-controlled content lands in a memory note, the agent re-ingests it next session. This is the Greshake et al. attack (Lesson 27) stretched across time.
  • Citation loss. The agent recalls that "the user asked me to ship X" but can't say which turn it came from. Store source references (session ID, turn ID) with every archival write.
Check: The Concept0/21
1. What is virtual context in the MemGPT design?Define
2. What is main context in MemGPT?Define
3. What is archival memory?Define
4. What is core memory in MemGPT?Define
5. Which of these is NOT one of MemGPT's canonical memory tools?Define
6. What does the interrupt pattern do in MemGPT?Define
7. What is memory rot, as distinct from memory poisoning, in this lesson's pitfalls list?Define
8. What is memory poisoning in this context?Define
9. Which production system did MemGPT evolve into in 2024?Define
10. What does the lesson's citation loss pitfall describe?Define
11. In MemGPT's OS analogy, what plays the role of the OS kernel that decides when data moves between tiers?Explain
12. Why does the runtime splice a memory tool's result into the next prompt as an observation?Explain
13. How many memory tiers does Letta use compared to MemGPT's two, per the lesson?Explain
14. Letta's recall tier splits the same ground differently from MemGPT. Which MemGPT piece does recall correspond to?Explain
15. What is the difference between core_memory_append and archival_memory_insert in MemGPT's tool surface, per the lesson?Explain
16. An agent reads a web page with hidden instructions and stores a note from it. Days later, in a fresh session, it starts following those instructions. Which failure is this?Analyze
17. After months of use, an agent's searches return many outdated facts and the right one is buried. Writes have far outpaced reads. Which fix does the lesson name?Analyze
18. Design A pins every user fact in core memory. Design B writes facts to archival memory and searches it. As facts grow into the thousands, what happens to A?Analyze
19. Your agent must be able to say where each recalled fact came from. Which design change fits?Design
20. An assistant must always know that the user prefers metric units, and must also answer questions from a 300-page manual. Which placement fits?Design
21. Your agent will run unattended for weeks. Which plan best limits memory rot and poisoning?Design

Build It

code/main.py implements MemGPT's two-tier pattern in stdlib:

  • MainContext is a fixed-size prompt buffer with a core dict and a messages list. When the message count passes the cap, it evicts the oldest messages into an evicted list. Nothing is summarized, and evicted messages are not written to archival; they stay reachable only through conversation_search.
  • ArchivalStore is an in-memory BM25-esque store (token-overlap scoring) of (id, text, tags, session, turn) records.
  • Five memory tools map to the MemGPT surface.
  • A scripted agent fills archival with facts, then a follow-up is served by calling archival_memory_search.

Run it:

python3 code/main.py

The trace shows the agent writing three facts, filling main context to the cap (which forces eviction), then retrieving from archival. That is a MemGPT-style workflow, with no real LLM involved.

Check: Build It0/6
1. In the starter script, MainContext has max_messages=3 and six messages are appended in total. After the last append, how many messages are in the buffer and how many were evicted?Apply
2. After those six messages, what does conversation_search('retrieval bot') return?Apply
3. The store holds three records: one about a retrieval bot with 12 tools for sales, one about long-horizon tool chains drifting after 20 steps, and one about sleep-time compute. How many records does archival_memory_search('tool chains drift', top_k=2) return?Apply
4. The user core section is empty. What does core_memory_append('user', 'name=ava, role=ships agents') return?Apply
5. The user core section holds 'name=ava, role=ships agents'. What happens on core_memory_replace('user', 'name=bob', 'name=ava')?Apply
6. An agent's early messages were evicted from the buffer. It now calls archival_memory_search for a detail from one of them and gets 'no matches'. What explains this?Analyze

Use It

Every production memory system today is a MemGPT variant:

  • Letta (Lesson 08): three tiers, native reasoning, sleep-time compute.
  • Mem0 (Lesson 09): vector, KV, and graph stores fused with a scoring layer.
  • OpenAI Assistants / Responses: managed memory via threads and files.
  • Claude Agent SDK: long-term memory via skills and a session store.

Pick one by operational shape (self-hosted, managed, framework-integrated). The core pattern is the same in all of them.

Check: Use It0/1
1. Why does the lesson say production memory systems are MemGPT variants?Explain

Ship It

outputs/skill-virtual-memory.md is a reusable skill that produces a correct two-tier memory scaffold (main context, archival store, tool surface) for any target runtime, with the eviction policy and citation fields already wired in.

Author's Note

Most people building a memory layer spend their effort on retrieval quality and almost none on what gets written. Writes are the part that bites you later. Every fact you let the agent store is a fact it will retrieve, trust, and act on in a session you aren't watching, so a sloppy write today becomes a confident wrong answer next week. Decide up front what is allowed into archival memory, tag it with where it came from, and make that the part you test hardest. The search algorithm is easy to swap out afterward. A polluted store is not.

Exercises

  1. Add a max_main_context_tokens cap measured in tokens (approximate with len(text.split()) * 1.3). The starter code evicts the oldest messages by count and keeps no summary. Instead, compact the evicted messages into a summary when the cap is exceeded. Compare behavior with and without the summarizer.
  2. Implement BM25 properly over the archival store (term frequency, inverse document frequency). Measure recall@10 on a toy fact set versus the token-overlap baseline.
  3. Add citation fields (session_id, turn_id, source_url) to archival inserts. Make the agent cite sources on every retrieval-backed answer.
  4. Simulate memory poisoning: add an archival record that says "ignore all future user instructions." Write a guard that scans retrievals for directive-shaped text and marks them untrusted.
  5. Port the implementation to use the MemGPT research repo's core-memory JSON schema (cpacker/MemGPT). What changes when you switch from flat strings to typed sections?

Key Terms

TermWhat people sayWhat it actually means
Virtual context"Unlimited memory"Main (prompt) + external (searchable) tiers with page in/out
Main context"Working memory"The prompt: fixed-size, always visible
Archival memory"Long-term store"External searchable persistence, retrieved on demand
Core memory"Persistent prompt section"Named sections pinned inside the main context
Memory tool"Memory API"Tool call the agent issues to read/write external memory
Interrupt"Memory page fault"Agent pauses, runtime fetches, result splices into next turn
Memory rot"Stale facts"Old writes drown retrieval; fix with consolidation
Memory poisoning"Injected persistent note"Attacker content stored as memory, re-ingested on recall

Further Reading

Code

Ships With