AI Agent Memory: Sessions, Long-Term State, and Retrieval

By

What is AI agent memory?

AI agent memory is application-managed state carried across steps, turns, or sessions so an agent can resume work and recall relevant facts. It may include thread history, workflow checkpoints, durable user or project facts, and retrieved prior experiences, each with separate scope and lifecycle.

TL;DR

  • -Conversation history, workflow checkpoints, long-term facts, and document retrieval solve different problems; storing all four in one vector index creates ambiguity
  • -A memory needs scope, provenance, timestamps, sensitivity, and lifecycle—not only text and an embedding
  • -Write memory from explicit user statements or verified outcomes; treat model-extracted facts as candidates until policy accepts them
  • -Retrieve with identity filters and task relevance before semantic similarity, then fit results into a fixed context budget
  • -Measure write precision, useful recall, contradiction rate, cross-user leakage, staleness, and deletion completion with fixed scenarios

“Give the agent memory” sounds like one feature. In production it is at least four different data systems:

current run state
conversation or workflow checkpoint
long-term facts and preferences
retrieval over documents and prior experiences

Mix them together and the agent starts treating an old chat summary as current account state, a private preference as organization policy, or a failed attempt as a proven procedure.

Memory is not a bigger prompt and not a vector database with every conversation dumped into it. It is a governed path from event → candidate → stored record → retrieval → context → correction or deletion.

This article focuses on that path. The broader context engineering guide covers how memory competes with instructions, tools, and retrieved documents inside the context window. For multiple cooperating agents, pair it with the multi-agent architecture guide.

Separate the four state problems

LayerScopeExampleStorage shape
Working stateOne run or stepCurrent plan, intermediate IDs, retry countTyped in-memory state
Thread stateOne conversation or workflowMessages, approvals, checkpoint, pending tool callOrdered log and checkpoints
Long-term memoryUser, project, agent, or organizationPreference, verified fact, reusable experienceStructured records with lifecycle
Knowledge retrievalCorpus and access domainProduct docs, tickets, repository filesSource documents plus index

The boundaries matter more than the names. OpenAI’s Agents SDK, for example, uses a Session to store conversation history for one session. Its current state-management guide distinguishes client-managed sessions from server-managed conversations and warns against mixing both persistence strategies in one run because context can be duplicated.

LangGraph makes a similar split: checkpoints persist thread state, while a Store holds data that can be recalled across threads. The memory overview calls these short-term and long-term memory. The framework may differ; the scopes should not.

Model memory as records, not prose

A single memory_text field is quick to ship and hard to operate. Use a record that can answer who it belongs to, where it came from, whether it is still valid, and how it may be used:

{
  "memory_id": "mem_01...",
  "subject_id": "usr_internal_42",
  "namespace": ["user", "travel_preferences"],
  "kind": "preference",
  "fact": {
    "field": "seat_preference",
    "value": "aisle"
  },
  "source": {
    "type": "explicit_user_statement",
    "event_id": "evt_01..."
  },
  "confidence": "confirmed",
  "sensitivity": "personal",
  "valid_from": "2026-08-21T10:00:00Z",
  "valid_until": null,
  "created_at": "2026-08-21T10:00:02Z",
  "supersedes": null
}

Keep the embedding as an index derived from this source record. It is not the source of truth. That distinction makes corrections, access changes, and deletion possible without trying to reverse-engineer a vector.

Choose memory types deliberately

Three long-term types are useful:

  • Semantic: facts such as a user’s language or a project’s deployment region.
  • Episodic: an earlier attempt, its actions, and verified outcome.
  • Procedural: instructions for how the agent should perform a task.

Procedural memory deserves the strongest gate. An agent that can rewrite its own shared instructions can turn one poisoned conversation into persistent behavior. Keep organization policy and high-impact procedures versioned, reviewed, and read-only to the runtime. Let the agent propose a change; do not let it silently publish one.

Design the write path before retrieval

Most memory failures begin when too much is written. “The user mentioned it” is not a retention policy.

Use three write paths:

1. Explicit and immediate

The user says “remember that I prefer aisle seats.” Validate that the data class is allowed, show what will be stored when the consequence is not obvious, then write a confirmed record.

2. Deterministic outcome

Application code records a completed booking, approved decision, or successful tool result. Store the verified state or a reference to its system of record. Do not ask the model to rephrase an identifier and then trust the paraphrase.

3. Inferred candidate

The model infers a preference or extracts a lesson from several events. Write a candidate with provenance, not an accepted fact. A background job can deduplicate, check policy, compare current records, and request user review where needed.

Background consolidation keeps memory work off the response path and can examine more than one event. It also introduces lag and races. Assign each candidate an event ID, make writes idempotent, and ensure an older job cannot overwrite a newer confirmed record.

The OpenAI Agents SDK’s current sandbox memory feature uses a similar separation: conversation extracts are consolidated into smaller memory files, while its ordinary Session remains conversation history. Its agent memory documentation also treats saved memory as guidance and tells the agent to trust the current environment when they conflict.

Resolve conflicts instead of appending forever

Memory changes. A user moves, a project migrates, a preference was temporary, or an earlier extraction was wrong.

Define a precedence policy in code. One workable order is:

current system of record
> explicit current user statement
> approved organization or project record
> recent verified outcome
> model-inferred candidate
> old summary

Do not merge incompatible values into prose. Preserve versions or a supersession link, select the active record deterministically, and surface the conflict when policy cannot resolve it. “I found two different billing contacts; which is current?” is better than choosing the closest embedding.

Use validity intervals and TTLs for facts that naturally expire. Recency alone is not truth: an attacker should not be able to override an approved policy merely by writing a newer note.

Retrieve by scope before similarity

The retrieval pipeline should narrow authority first:

verified principal
→ allowed namespace and tenant
→ memory kind and validity
→ task filters
→ lexical or semantic retrieval
→ reranking
→ context budget

Never retrieve a broad global index and filter the results after they have reached the model. Enforce identity and tenant boundaries in the storage query. A namespace should be derived from verified runtime context, not from user_id supplied in a prompt.

Use structured lookup for exact facts:

  • current timezone;
  • approved language;
  • active workflow ID;
  • policy version;
  • object ownership.

Use semantic search for fuzzy experiences and notes: similar incidents, previous approaches, or relevant preferences expressed in different words. Combine it with metadata filters and lexical search when identifiers or exact phrases matter.

Return a small typed packet with provenance:

{
  "fact": "Prefers aisle seats",
  "status": "confirmed",
  "source_date": "2026-08-21",
  "memory_id": "mem_01..."
}

Give memory a fixed token budget. If ten records fit, retrieval should not return fifty and hope the model ignores forty. Log candidates, selected records, and rejection reasons so missed or noisy retrieval can be debugged.

Summaries are lossy indexes

Conversation compaction is useful, but a summary should not silently become the only record of approvals, tool results, or user commitments.

Keep an append-only event log or source messages according to your retention policy. Store the summary with:

  • the source range it covers;
  • prompt or summarizer version;
  • creation timestamp;
  • explicit unresolved items;
  • references to important source events.

Regenerate summaries after a correction or deletion. Otherwise the source fact may be gone while its paraphrase survives in every future prompt.

Resume workflows from checkpoints, not chat guesses

A durable agent needs exact state for side effects:

workflow_id
current_step
completed_steps
pending_approval
tool_call_id and idempotency key
artifacts produced
last verified outcome

This is thread state, not long-term memory. Persist it transactionally around tool effects and authorize every resume. A model-generated summary saying “payment probably completed” cannot decide whether to charge again.

LangGraph’s persistence model writes checkpoints per thread and uses a separate Store for cross-thread memory. That separation is a useful architecture even when you do not use LangGraph.

Privacy and deletion are part of the schema

Before storing a class of memory, decide:

  • purpose and allowed readers;
  • whether the model may write, read, or only propose it;
  • sensitivity and encryption requirements;
  • default TTL and maximum retention;
  • export, correction, and deletion paths;
  • whether it may cross user, project, or organization boundaries.

Do not store passwords, access tokens, recovery codes, payment data, raw government IDs, or secrets as conversational memory. Use the appropriate system of record and return only the minimum needed fact to the agent.

A delete operation must fan out to the source record, vector and lexical indexes, summaries, caches, checkpoints where applicable, and asynchronous replicas. Use a deletion job with status and retry. Keep a content-free tombstone long enough to stop a delayed indexing event from recreating the record. Verify completion with a read path, not only a successful queue submission.

Evaluate memory as a retrieval-and-write system

Build fixed scenarios from real failure shapes:

MetricWhat the scenario checks
Write precisionDid the system store only facts worth retaining?
Write recallDid it retain the explicit permitted fact it should remember?
Useful retrievalDid the task receive the relevant active record?
NoiseDid irrelevant memories consume context or change the answer?
Contradiction handlingDid newer or higher-authority data win correctly?
IsolationCan one principal ever retrieve another principal’s record?
StalenessAre expired or superseded records excluded?
DeletionDoes removed content disappear from every read surface?

Add adversarial cases: indirect instructions inside a remembered note, a prompt trying to change namespace, a poisoned shared procedure, and a deletion racing a background consolidation job. The memory store is untrusted input to the model and sensitive data to the application at the same time.

Production checklist

  • Working state, thread checkpoints, long-term memory, and knowledge retrieval are separate.
  • Every durable memory has owner, scope, provenance, timestamps, and sensitivity.
  • Explicit facts and inferred candidates use different write paths.
  • Conflicts and supersession are resolved by deterministic policy.
  • Identity and tenant filters run before semantic search.
  • Retrieval has a fixed context budget and exposes provenance.
  • Workflow resume uses checkpoints and idempotency, not summaries.
  • Shared procedures are reviewed and versioned.
  • Correction and deletion propagate through indexes, summaries, and caches.
  • Fixed tests cover quality, isolation, staleness, and deletion.

Good memory is selective and boring. The agent recalls the right fact, can show where it came from, forgets it on command, and does not turn yesterday’s chat into today’s authority.

Frequently Asked Questions

Is conversation history the same as long-term memory?
No. Conversation history is usually thread-scoped and preserves turns for continuity. Long-term memory stores selected facts or experiences across threads. Keeping the distinction prevents a private detail from one conversation from becoming a global agent fact.
Should every agent memory use a vector database?
No. Exact profile fields, workflow status, permissions, and timestamps belong in structured storage with deterministic filters. Embeddings help retrieve fuzzy notes or experiences, but they should complement rather than replace identity, scope, and lifecycle queries.
When should an agent write memory?
Write immediately when the user explicitly asks to remember a permitted fact or when deterministic application logic records a verified outcome. For inferred facts, queue a background candidate, attach provenance and confidence, and accept it only after policy checks or user review.
How do I delete an agent's memory?
Delete by subject and scope across the source record, search index, summaries, caches, checkpoints, and backups according to policy. Keep tombstones or deletion jobs long enough to prevent an asynchronous indexer from recreating the item, without retaining the deleted content itself.