Memorymemorypitfallsprivacyttldrift

Memory Pitfalls

More memory is not automatically better: pollution, poor retrieval, summarisation drift, missing expiry, privacy exposure and no user control each turn a helpful feature into a liability.

Interview question
Progress

Context pollution

The most common memory failure is not forgetting; it is remembering too much. Every retrieved memory item competes for attention with the user's actual request. Inject fifteen loosely related facts and the model starts answering the memory instead of the question — bringing up a resolved billing issue during an SSO ticket, or applying a preference the user stated once, jokingly, a year ago.

The fix is a strict read path (Memory Architectures): a relevance floor, a small k, a token budget, and an eval that measures task success *with and without* memory on a golden set (Golden Datasets). If memory does not move the metric, turn it off for that route. "It feels more personal" is not a metric.

Retrieval quality and summarisation drift

Memory inherits every retrieval problem RAG has (RAG Evaluation) plus one of its own: the corpus is self-generated. Facts were extracted by a model, episodes were summarised by a model, and each pass is lossy. After a few cycles of summarise-the-summary, an episode that began as "customer asked whether SSO supports Okta" can become "customer uses Okta SSO" — a confident falsehood with no source left to check.

Guard against drift structurally: never summarise a summary more than once; keep a pointer to the original source (ticket id, message id) on every record; store extraction confidence and drop low-confidence facts at read time; and reconcile against the system of record when one exists rather than trusting the memory.

  • Store the source span or id with every fact; a fact you cannot trace is a rumour.
  • Prefer extracting facts once from raw material to re-extracting from prior extractions.
  • Periodically re-verify high-impact facts against the source of truth.

Expiration, eviction and TTL

Facts decay. A stated preference is probably still true after a month; a "currently investigating" status is stale after a day. Give every record a time-to-live appropriate to its type, and let reads down-weight age even before expiry. Without TTLs, the store only grows, retrieval gets noisier, and the stale-fact incident (stale-memory) is a matter of time.

Capacity is the other axis. Per-user memory should have a bound, and when it is hit you need an eviction policy. The classic answer is the same as in caching: evict least-recently-used, so items that keep being retrieved survive and items nobody has needed in months go first. An LRU cache with a TTL is a perfectly good first memory store — and a useful mental model even when the real store is Postgres.

Bounded, expiring memory: LRU eviction on capacity, TTL on age. The same structure as an LRU cache.
1import time
2from collections import OrderedDict
3
4class BoundedMemory:
5 def __init__(self, capacity: int = 200, ttl_s: int = 90 * 86400):
6 self.cap, self.ttl, self.items = capacity, ttl_s, OrderedDict()
7
8 def put(self, key: str, value, ttl_s: int | None = None):
9 self.items[key] = (value, time.time() + (ttl_s or self.ttl))
10 self.items.move_to_end(key)
11 while len(self.items) > self.cap:
12 self.items.popitem(last=False) # evict least recently used
13
14 def get(self, key: str):
15 if key not in self.items:
16 return None
17 value, expires = self.items[key]
18 if time.time() > expires:
19 del self.items[key]; return None # expired
20 self.items.move_to_end(key) # touch → most recently used
21 return value

Privacy, user control and deletion

Long-term memory is personal data by construction. That brings obligations that are architectural, not policy footnotes: users must be able to see what is stored about them, correct it, and delete it — and deletion must actually propagate to every copy, including vector indexes, backups within your retention window, and any summaries derived from the deleted item.

Design for it from day one. Store memory keyed by user id in a single place with a delete_user(user_id) that is tested; keep derived summaries traceable to their sources so a deletion can invalidate them; never let memory cross tenant boundaries; and avoid storing what you never needed — secrets, payment details, health information that leaked into a chat. A memory feature that cannot be inspected and erased by the user is a compliance incident with a launch date.

  • Expose "what do you remember about me?" and "forget that" as real product features backed by real deletes.
  • Do not persist content the extraction step flags as sensitive; redact before storing.
  • Log memory reads and writes per user for audit (Logging, Metrics and Alerts).

Key points

  • Memory competes with the request for attention; over-injection makes answers worse, not more personal.
  • Evaluate memory on/off per route; keep it only where it moves task success.
  • Self-generated corpora drift: never summarise summaries repeatedly, keep source pointers, store confidence.
  • Every record gets a TTL by type; per-user stores are bounded with LRU-style eviction.
  • Users must be able to view, correct and delete memory, and deletion must propagate to derived data.
  • Memory is untrusted content and personal data at the same time — treat it as both.

When to use — and when not to

Use it when
  • Reviewing any memory design before launch — run through pollution, drift, TTL, privacy, deletion.
  • When an agent "knows" something false and nobody can say where it came from.
  • When memory volume per user is growing without bound.
Avoid it when
  • These are guardrails, not a reason to skip memory when continuity is genuinely required.
  • Do not apply aggressive TTLs to stable facts the user explicitly asked you to remember.
  • Do not solve pollution by dropping memory entirely if a relevance floor fixes it.

Failure modes

  • Agent raises an unrelated past issue in every conversation because k is too high.
  • A summarised summary asserts a fact that was originally a question.
  • No TTL: the agent uses a plan tier that changed eight months ago.
  • Deleting a user removes the profile row but leaves their episodes in the vector index.
  • Memory contains an injected instruction that replays into every future session.
  • Memory copied from a system of record diverges from it and nobody reconciles.