QA How-To
Testing an LLM agent memory (2026)
Learn testing an LLM agent memory with isolation, retrieval, deletion, temporal, privacy, concurrency, evaluation, and runnable pytest techniques in CI.
24 min read | 3,536 words
TL;DR
Testing an LLM agent memory requires deterministic checks at the storage boundary plus behavioral evaluations at the agent boundary. Verify write policy, retrieval ranking, temporal updates, isolation, deletion, summarization, concurrency, and privacy with seeded facts and auditable traces.
Key Takeaways
- Test memory as a stateful subsystem with explicit write, retrieval, update, expiry, and deletion contracts.
- Separate memory correctness from response quality so a fluent answer cannot hide a storage or retrieval defect.
- Build temporal and contradictory facts into the evaluation corpus to verify supersession and provenance.
- Make tenant, user, workspace, and session isolation release-blocking security properties.
- Evaluate retrieval with labeled relevant memories, distractors, ranking measures, and no-answer cases.
- Test summarization for preserved commitments, constraints, uncertainty, and source references, not just readability.
- Record memory decisions and identifiers without exposing sensitive memory content in logs.
Testing an LLM agent memory means proving that the agent remembers the right facts, for the right subject, for the right duration, and forgets them when required. A good test strategy separates storage behavior from model behavior, because a polished answer can be correct by chance even when the memory subsystem is broken.
Treat memory as security-sensitive state, not as extra prompt text. This guide builds a practical risk model, a labeled evaluation corpus, deterministic component tests, behavioral agent tests, and production checks that expose leakage, stale facts, bad ranking, destructive updates, and unreliable deletion.
TL;DR
| Memory property | Core oracle | High-risk failure |
|---|---|---|
| Write policy | Only eligible facts are persisted | Secrets or transient guesses become durable |
| Retrieval | Labeled relevant items rank above distractors | The agent acts on unrelated history |
| Temporal accuracy | Current fact supersedes stale fact | Old address, role, or preference drives action |
| Isolation | Every result matches the active scope | One user receives another user's memory |
| Deletion | Deleted content is absent from all serving paths | Data survives in indexes, caches, or summaries |
| Summarization | Critical constraints and provenance survive | Compression silently changes intent |
| Concurrency | Version rules resolve competing writes | Updates are lost or duplicated |
Use two layers of evidence. Component tests call the memory service directly and assert IDs, scopes, versions, filters, and returned records. End-to-end evaluations send conversations through the agent and score whether the final action is grounded in authorized, current memory.
1. Why testing an LLM agent memory needs its own risk model
Agent memory is rarely one database table. A production path may include a short conversation window, a generated summary, structured profile fields, vector search, keyword search, a reranker, tool state, and caches. A fact can be correct in the source store yet missing from the prompt because a filter is wrong. It can also be absent from the store but echoed by the model from the current conversation. A single black-box chat assertion cannot identify which layer failed.
Start with assets and harms. Assets include personal data, authorization context, user preferences, unfinished commitments, business decisions, and tool results. Harms include cross-user disclosure, incorrect actions based on stale data, retention beyond policy, prompt injection that becomes persistent, and silent loss of commitments during compaction. Severity depends on what the agent can do. A shopping assistant remembering a color preference has different consequences from an operations agent remembering an approval.
Define invariants before examples. Every stored item must have an owner scope, source, creation time, sensitivity label, and lifecycle rule. Retrieval must enforce authorization before similarity ranking. A newer verified value must beat an older conflicting value. Deletion must remove the item from serving indexes and derived summaries within the documented contract. These invariants become property tests and release gates.
The result is a model with observable checkpoints: input conversation -> write decision -> canonical record -> index -> retrieval candidates -> reranked context -> agent response or tool action. Instrument each checkpoint with stable identifiers so failures are explainable without logging raw secrets.
2. Map the memory architecture and define contracts
Create an inventory before writing cases. For each memory type, record its schema, owner, purpose, source, write trigger, retrieval trigger, expiration, update rule, deletion path, and downstream copies. Distinguish at least working memory, episodic history, semantic facts, procedural instructions, and application state. Teams may use different names, but the behavioral differences matter.
A useful contract for a structured preference might say: the agent may store an explicit user preference after confirmation, scoped to one account; a later explicit statement replaces it; inference alone cannot overwrite it; the user can view and delete it; and retrieval exposes both value and provenance. A conversation summary contract might say: preserve open tasks, explicit constraints, decisions, unresolved questions, and uncertainty while excluding secrets and expired tool output.
Map trust boundaries too. If the model proposes writes, deterministic code must validate scope and schema. If retrieval uses vector search, authorization filters must be applied inside the query or before any candidate content reaches the model. Post-filtering after untrusted records have entered model context is too late for confidentiality.
For engineers designing a broader AI test portfolio, the AI test review checklist helps connect these contracts to data, safety, and observability reviews. The memory plan should name an owner for each oracle. Product owns what is worth remembering, security owns isolation and sensitive classes, platform owns lifecycle guarantees, and QA owns evidence that the composed behavior satisfies them.
3. Build a labeled memory evaluation corpus
A useful corpus is a set of conversations, memory state snapshots, candidate records, expected retrievals, forbidden retrievals, and expected final behaviors. Do not rely only on friendly facts such as a favorite color. Include realistic ambiguity, conflict, correction, irrelevant similarity, injection, and time.
For each case, seed one or more target facts plus hard distractors. If the query is about a user's preferred airport, distractors could mention the same city in a canceled trip, another user's airport, an old preference, and a document containing the phrase but no preference. Label which records are relevant, which are allowed but irrelevant, and which are forbidden regardless of relevance. The forbidden label is essential because ordinary precision metrics do not capture confidentiality.
Create counterfactual pairs. In one conversation the user explicitly says, Remember that I prefer aisle seats; in the paired case the agent infers the preference from a single booking. The first may be eligible for durable storage, while the second should remain an observation or not be stored. Pair current and corrected facts, consent and no consent, same tenant and different tenant, and valid and expired records.
Keep the corpus versioned with policy. Each case needs a stable ID, risk tag, source state, simulated clock, expected memory mutations, acceptable response rubric, and prohibited behavior. Avoid expecting exact prose from a generative model. Assert grounded facts, citations to memory IDs, requested clarification, or absence of an unauthorized action. Add production incidents only after redaction and minimization. A compact, reviewed corpus with sharp labels is more valuable than thousands of synthetic conversations with uncertain truth.
4. Test write policy, extraction, and provenance
Write-path tests ask whether the right information becomes memory. Cover explicit save requests, implicit but eligible facts, transient context, secrets, third-party data, uncertain inferences, prompt injection, malformed extraction, duplicates, and repeated turns. Assert the record, not just the assistant's acknowledgment.
If a model extracts candidate facts, validate its output against a strict schema and deterministic policy. A candidate should include subject, predicate, value, source message ID, confidence or evidence class, scope, and sensitivity. The service should reject missing scopes, unknown fields, excessive lengths, and values prohibited by policy. Test with Unicode, control characters, markup, quoted instructions, and data that resembles system commands. Memory content remains untrusted data when retrieved later.
Provenance is an oracle, not decoration. Given My office is now Pune, not Mumbai, the new office record should point to that message, while the old value should be marked superseded rather than silently edited if audit requirements demand history. An inferred fact must never appear as user-confirmed. When an agent says why it acted, the cited source should match the actual record used.
Test idempotency by replaying the same event and by retrying after an ambiguous timeout. A stable event key should prevent duplicate durable memories. Test partial failure between the canonical store and search index. The system must reconcile the index or keep the unindexed record out of claims about search completeness. Finally, verify that a failed write does not produce a false I will remember that response. The acknowledgement should be based on the committed result, not on model intent.
5. Measure retrieval relevance and no-answer behavior
Retrieval tests need known candidates. Run the retriever against a fixed snapshot and capture prefilter candidates, similarity or lexical signals, reranker output, final top-k records, and exclusion reasons. Calculate ranking measures only where labels are reliable. Recall at k answers whether the needed item appeared. Mean reciprocal rank rewards placing the first relevant item early. Precision at k reveals distractor load. Add a separate forbidden-retrieval count that must remain zero.
| Measure | Question it answers | Limitation |
|---|---|---|
| Recall@k | Did the context include the needed memory? | Does not reward a better position within k |
| Precision@k | How much returned context was useful? | Relevance labels can be subjective |
| Reciprocal rank | How early was the first useful item? | Ignores additional relevant records |
| Forbidden exposure rate | Did any unauthorized item appear? | Must be evaluated before model generation |
| Abstention accuracy | Did the agent avoid inventing absent memory? | Requires strong no-answer cases |
Test paraphrases, abbreviations, misspellings, multilingual queries, negation, entity collisions, and semantic near-neighbors. A statement about Java the language should not retrieve a travel note about Java the island unless the query supports it. Vary k and token budgets, because a relevant record at rank nine is effectively missing if only five records fit.
No-answer behavior is equally important. With no authorized supporting memory, the agent should ask, search an approved source, or state that it does not know. It should not convert a plausible default into remembered fact. This principle aligns with testing RAG hallucinations, where retrieval evidence and answer grounding are scored separately.
6. Verify temporal updates, contradictions, and expiry
Memory is temporal. Freeze the clock in component tests and seed records with explicit effective times. Test future-dated facts, late-arriving events, daylight-saving transitions where relevant, different time zones, expiry exactly at the boundary, and a correction that arrives after an old record has already been summarized.
Define conflict rules per memory type. A profile field may use the latest explicit user statement. A medical or financial fact may require source authority and human confirmation rather than last-write-wins. A project decision may be append-only with status transitions. Tests should assert the chosen rule, the prior version's status, and the evidence returned to the agent. Never assume one generic timestamp sort is correct for all data.
Construct conversations that tempt the model to blend contradictions: I used to work nights, but since June I work mornings. A current scheduling request should use mornings, while a question about May may require the older fact. The retrieval query needs an as-of time or a temporal filter. Test both current and historical questions.
Expiry must work across every serving copy. When a memory expires, query the canonical store, vector index, keyword index, cache, generated profile, and conversation summary. Confirm that background cleanup is not the only protection. Serving paths should filter expired items immediately even if physical deletion is asynchronous. Test extension and renewal rules separately, because reading a memory should not silently refresh retention unless policy explicitly says so.
7. Make isolation, deletion, and privacy release gates
Isolation tests should be adversarial and deterministic. Create users with similar names, identical facts, shared organizations, transferred workspaces, and recently revoked membership. Query from every scope and assert that each returned memory carries the active tenant, subject, workspace, and authorization version. Test direct ID lookup as well as search, export, admin tools, caches, analytics, and backup restore procedures.
Use canary records that are unique and safe, such as isolation-canary-user-b-7f2. Search for them from user A through exact text, paraphrase, filters, pagination, and malformed scope inputs. The correct exposure count is zero. Run these tests before any content reaches an LLM, because even a response that omits leaked text does not undo the disclosure to the model provider or trace system.
Deletion tests start with a graph of copies. Delete the source memory, wait only for documented asynchronous windows, then probe all read paths. Verify tombstones prevent a delayed indexing event from resurrecting the item. Re-import old events, replay a queue, rebuild an index, and restore a backup into an isolated environment to confirm the deletion ledger is reapplied. Test account deletion and single-item deletion separately.
Privacy checks also cover logs and evaluation datasets. Trace views should show record IDs, policy decisions, and redacted attributes, not full sensitive values by default. Ensure lower environments do not receive production memory dumps. For security-focused test design, use the API negative testing guide to expand malformed identity, authorization, and lifecycle cases around the memory service.
8. Test summaries and context compaction
Summarization is a lossy transformation, so testing only grammatical quality is insufficient. Create source conversations with explicit commitments, constraints, named owners, deadlines, unresolved questions, conditional decisions, corrections, and sensitive fragments that must be excluded. Compare the generated summary against an atomic fact checklist.
Score four dimensions. Coverage asks whether required atoms remain. Faithfulness asks whether every summary claim is supported. Status accuracy asks whether completed, open, canceled, and uncertain items retain their state. Privacy asks whether excluded information is absent. A concise summary that changes do not email the customer into email the customer is a critical failure even if similarity scores are high.
Test repeated compaction. Feed a long session through multiple summarize-and-replace cycles and look for cumulative drift. Put an important constraint early, apply many unrelated turns, then verify it survives until its expiry or completion. Add near-duplicate names and numbers to catch entity merging. Preserve links to source message IDs so disputed summaries can be audited and corrected.
Run behavioral checks after compaction. Ask the agent to perform a task whose correct plan depends on the preserved constraint. Separately inspect the actual context assembled for the model. If the final behavior is correct only because the user repeated the information, the memory test should not pass. If summaries are editable, verify optimistic concurrency and revision history. If they are model-generated asynchronously, test ordering so an older summarization job cannot overwrite a newer state.
9. Exercise concurrency, retries, and degraded dependencies
Stateful agents encounter overlapping tabs, mobile and web sessions, queued events, tool retries, and multiple workers. Create races intentionally. Two requests update the same preference from the same starting version. A summary job reads version 8 while version 9 commits. A delete occurs while an indexer processes an earlier create event. A retriever reads during index lag. State the expected winner or conflict response for every race.
Use version numbers or compare-and-set behavior where lost updates matter. Tests should assert that a stale writer receives a conflict, retries with fresh state, or creates a reviewed merge. If the product intentionally uses last-write-wins, verify which timestamp is authoritative and prevent client clock skew from deciding server truth.
Inject dependency failures at boundaries: vector service unavailable, embedding timeout, canonical database slow, reranker error, malformed cached record, and telemetry outage. The agent should degrade according to policy. It may use recent working context, perform keyword retrieval, ask the user, or stop. It must not claim to remember a fact that was not retrieved.
Retry testing must include side effects. Repeat write and delete calls with the same idempotency key. Deliver events out of order and more than once. Restart a worker after commit but before acknowledgement. Then reconcile canonical records and indexes. Capture the final state plus event history, because a superficially correct final answer can hide duplicate records that will cause later retrieval noise.
10. A runnable harness for testing an LLM agent memory
Save this as test_memory_store.py, install pytest, and run pytest -q. It models a deterministic memory boundary with the standard library.
from dataclasses import dataclass, replace
from datetime import datetime, timezone
from typing import Iterable
import pytest
@dataclass(frozen=True)
class Memory:
id: str
tenant_id: str
user_id: str
text: str
version: int
expires_at: datetime | None = None
deleted: bool = False
class MemoryStore:
def __init__(self, records: Iterable[Memory] = ()):
self._records = {record.id: record for record in records}
def search(self, tenant_id: str, user_id: str, query: str, now: datetime):
words = set(query.casefold().split())
visible = []
for record in self._records.values():
allowed = record.tenant_id == tenant_id and record.user_id == user_id
current = record.expires_at is None or record.expires_at > now
if allowed and current and not record.deleted:
score = len(words & set(record.text.casefold().split()))
if score:
visible.append((score, record))
return [item[1] for item in sorted(visible, key=lambda item: (-item[0], item[1].id))]
def update(self, memory_id: str, expected_version: int, text: str):
current = self._records[memory_id]
if current.version != expected_version:
raise ValueError("version conflict")
updated = replace(current, text=text, version=current.version + 1)
self._records[memory_id] = updated
return updated
def delete(self, memory_id: str):
current = self._records[memory_id]
self._records[memory_id] = replace(current, deleted=True)
NOW = datetime(2026, 7, 13, 12, 0, tzinfo=timezone.utc)
def test_search_enforces_tenant_user_and_expiry():
store = MemoryStore([
Memory("mine", "t1", "u1", "prefers aisle seat", 1),
Memory("other-user", "t1", "u2", "prefers aisle seat", 1),
Memory("other-tenant", "t2", "u1", "prefers aisle seat", 1),
Memory("expired", "t1", "u1", "aisle seat old", 1, NOW),
])
assert [m.id for m in store.search("t1", "u1", "aisle seat", NOW)] == ["mine"]
def test_stale_writer_cannot_overwrite_newer_value():
store = MemoryStore([Memory("m1", "t1", "u1", "office Mumbai", 3)])
store.update("m1", expected_version=3, text="office Pune")
with pytest.raises(ValueError, match="version conflict"):
store.update("m1", expected_version=3, text="office Delhi")
def test_deleted_memory_is_not_served():
store = MemoryStore([Memory("m1", "t1", "u1", "project cedar", 1)])
store.delete("m1")
assert store.search("t1", "u1", "project cedar", NOW) == []
Reuse the isolation assertions through adapters for direct, vector, keyword, and cache reads. Add a simulated clock. Behavioral cases should store expected memory IDs and require traces to cite only authorized IDs, which localizes failures to retrieval, ranking, context, or reasoning.
11. Run memory evaluations in CI and production
Use a test pyramid. Fast schema, policy, filtering, version, and lifecycle tests run on every change. Retriever evaluations run against a fixed index snapshot when embedding, chunking, filtering, or ranking changes. A smaller end-to-end agent suite runs with controlled model settings and repeated trials where variance matters. Security isolation and deletion probes gate release. Load and soak tests cover index lag, hot users, large histories, and background compaction.
Pin every relevant artifact: application build, model identifier, prompt version, embedding model, index snapshot, retriever settings, policy version, and corpus commit. Compare a candidate system with the current production baseline on the same cases. Report per-risk slices, not only one average. A gain on preference recall cannot offset a new cross-tenant exposure.
In production, monitor rates and distributions rather than memory content. Useful signals include write rejection reasons, retrieval result count, stale or expired candidates filtered, supersession conflicts, index lag, summary compression ratio, deletion backlog, and unsupported-memory claims detected by sampling. Protect trace access and retain it according to the same privacy model as memory.
Create an incident replay process. Given a run ID, reconstruct authorized memory state and retrieval configuration in an isolated environment. Add the minimized failure to the regression corpus, fix the lowest responsible layer, and verify no adjacent risk slice regressed. The AI flaky test root cause guide is useful when repeated agent evaluations vary, but do not label genuine nondeterminism as ordinary test flakiness without investigating model, data, and timing changes.
Interview Questions and Answers
Q: How would you test memory in an LLM agent?
I would split the system into write, canonical storage, indexing, retrieval, context assembly, and behavioral layers. Deterministic tests would verify schemas, scope filters, temporal rules, deletion, and concurrency. Labeled evaluations would verify ranking and final grounded behavior with relevant facts, distractors, contradictions, and no-answer cases.
Q: How do you distinguish a memory failure from a model reasoning failure?
I inspect the trace at each boundary. If the correct record was never stored, it is a write problem. If stored but absent from candidates, it is filtering or indexing; if ranked out, it is retrieval; if present in the prompt but ignored, the failure is context use or model reasoning.
Q: What is the most important security test for agent memory?
Cross-scope isolation is release-blocking. I seed unique canary facts for multiple users and tenants, then probe every serving path with direct IDs, exact search, semantic paraphrases, pagination, caches, exports, and revoked access. I assert zero unauthorized candidates before content reaches the model.
Q: How would you test a memory summarizer?
I label atomic facts for commitments, constraints, decisions, status, uncertainty, and forbidden sensitive content. I score coverage and faithfulness, repeat compaction cycles to detect drift, and run a downstream task that depends on a preserved constraint. I also verify source references and ordering between asynchronous summary jobs.
Q: Which retrieval metrics would you use?
I use recall at k, precision at k, and reciprocal rank for labeled relevance. I add forbidden exposure rate and abstention accuracy because ordinary information-retrieval metrics do not represent privacy or unsupported claims. I report slices by query type, memory age, language, conflict, and scope.
Q: How do you test deletion when vector indexes are asynchronous?
The serving layer must immediately exclude a deleted or expired record even if physical cleanup is pending. I probe canonical reads, indexes, caches, summaries, and exports, then verify cleanup within the documented window. I also replay delayed events and rebuild the index to ensure tombstones prevent resurrection.
Q: How do you reduce flaky memory evaluations?
I freeze data, time, scopes, index snapshots, prompts, and model identifiers. I assert structured facts and used memory IDs rather than exact wording. For genuinely stochastic behavior, I run repeated trials and compare rates with uncertainty, while deterministic memory contracts remain exact.
Q: What production signals reveal memory quality problems?
I monitor rejected writes, duplicate rates, version conflicts, retrieval counts, filtered stale items, index lag, unsupported-memory claims, summary drift samples, and deletion backlog. Signals are sliced by memory type and policy version. Raw sensitive content is minimized and access-controlled.
Common Mistakes
- Testing only the final chat response. Inspect stored records, candidate lists, filters, ranked context, and used memory IDs.
- Using easy facts without distractors. Add contradictions, near-neighbors, same-name subjects, stale values, and forbidden records.
- Applying authorization after retrieval. Enforce it before unauthorized text can reach the model or its traces.
- Treating the latest timestamp as universal truth. Define type-specific authority, effective time, and conflict rules.
- Assuming deletion from the main table is complete. Probe indexes, caches, summaries, exports, backups, and delayed event replay.
- Scoring summaries by readability or embedding similarity alone. Check atomic constraints, status, provenance, uncertainty, and excluded data.
- Hiding all model variation under a flaky-test label. Stabilize controllable inputs, repeat only where needed, and localize variance by layer.
- Logging full memory for observability. Prefer opaque IDs, decision metadata, redaction, strict access, and short retention.
Conclusion
Testing an LLM agent memory is a state, security, retrieval, and behavioral testing problem. The strongest approach establishes deterministic lifecycle and isolation contracts, then evaluates whether the agent uses authorized, current, relevant memories without inventing absent ones.
Start with a small corpus containing explicit saves, corrections, expiry, deletion, hard distractors, and cross-tenant canaries. Instrument the full memory path, run the component harness in CI, and make any unauthorized candidate or resurrected deletion a release blocker.
Interview Questions and Answers
How would you design a test strategy for LLM agent memory?
I would decompose the path into write decision, canonical storage, indexing, retrieval, context assembly, and agent behavior. Deterministic tests would cover schemas, isolation, lifecycle, temporal rules, and concurrency. A labeled corpus would cover relevance, distractors, contradictions, no-answer cases, and final grounded behavior.
How do you localize a memory-related failure?
I trace the expected record through each boundary. I check whether it was stored, indexed, authorized, returned as a candidate, ranked into context, and actually used. That separates write, retrieval, context, and reasoning failures instead of treating every wrong answer as a model problem.
What memory isolation tests are release blockers?
Any cross-user or cross-tenant candidate exposure is release-blocking. I test direct lookup, semantic and exact search, filters, caches, exports, revoked membership, and pagination with unique canaries. Authorization must run before content reaches the model.
How would you evaluate memory retrieval quality?
I create queries with labeled relevant, irrelevant, and forbidden records. I measure recall at k, precision at k, reciprocal rank, forbidden exposure, and abstention on empty cases. I slice results by age, conflict, language, entity ambiguity, and memory type.
How do you test temporal correctness in memory?
I freeze time and seed old, current, future, corrected, and expired records. Tests assert type-specific conflict rules, effective time, supersession status, and answers to both current and historical questions. I also probe every serving copy at expiry boundaries.
How do you validate conversation summary memory?
I label atomic commitments, constraints, decisions, owners, status, uncertainty, and excluded sensitive facts. I test coverage and faithfulness through repeated compaction cycles, verify source references, and run downstream behaviors that depend on preserved constraints.
How would you test deletion across an asynchronous index?
The read path should filter a tombstoned record immediately, while physical cleanup completes within its contract. I probe all stores and caches, replay delayed create events, and rebuild the index. The deleted record must never return to a serving path.
What belongs in an LLM memory trace?
I record run and memory IDs, scope, policy version, write or filter decisions, ranking positions, timestamps, and stop reasons. Sensitive values should be redacted or omitted by default. Access and retention for traces must match the memory privacy model.
Frequently Asked Questions
What is the best way to start testing an LLM agent memory?
Map every memory store and serving path, then define invariants for scope, provenance, freshness, retention, and deletion. Begin with deterministic component tests before adding end-to-end conversations, because they make failures much easier to localize.
How do you test whether an AI agent remembers correctly?
Seed known facts with realistic distractors and assert which memory IDs are stored, retrieved, and used. Then verify the final response or action against a rubric that distinguishes supported facts, clarification, and prohibited claims.
Which metrics are useful for agent memory retrieval?
Recall at k, precision at k, and reciprocal rank measure relevance and position. Add forbidden exposure rate, temporal correctness, and abstention accuracy because standard ranking metrics do not cover security or unsupported memory claims.
How can QA test memory deletion?
Delete a seeded canary and probe the canonical store, vector and keyword indexes, caches, summaries, exports, and direct lookup. Replay delayed events and rebuild indexes to confirm that tombstones prevent the deleted item from returning.
Should LLM memory tests assert exact assistant text?
Usually no. Assert structured facts, tool actions, memory identifiers, provenance, and forbidden behavior. Exact prose assertions are brittle and can pass or fail for reasons unrelated to memory correctness.
How do you test cross-user memory leakage?
Give each user and tenant a unique canary fact, then search from other scopes using exact terms, paraphrases, IDs, pagination, exports, and caches. Assert that unauthorized records never become retrieval candidates, not merely that the final answer omits them.
How often should agent memory evaluations run?
Run fast policy and lifecycle tests on every change. Run retrieval and end-to-end evaluation when models, prompts, embeddings, filters, ranking, schemas, or policy change, plus scheduled production-like regression runs against controlled snapshots.