AI agents

A Memory Write Policy for Agents: What to Record and Drop

Antonio Evans10 min read

A split diagram: on the left, an agent's conversation and tool outputs flow into a funnel labeled 'Write policy' with filters for 'capture', 'drop', 'dedupe', and 'conflict'; on the right.
Key points

Key points

  1. 1Record only information that changes what the agent does next time: stable preferences, explicit commitments, verified facts with a source, and short summaries of finished tasks.
  2. 2Drop transient chatter, low-confidence inferences and anything already contradicted by a newer entry, because append-only stores leave stale and current facts competing at retrieval time.
  3. 3Enforce the policy with a schema that requires a type, a source, a timestamp and a confidence score, so every write is auditable.
  4. 4Resolve conflicts by scope and recency, not by text similarity, and keep the losing version in a write log instead of deleting it silently.

Why the write side decides whether memory works

Most teams spend their effort on retrieval and almost none on capture. That is backwards. A retrieval system can only return what someone wrote, so every junk entry is a future false positive, and every missing entry is a future question the agent asks again. The memory loop has two halves, writing and reading, and the writing half is where the decisions are irreversible: a bad read costs one wrong answer, while a bad write costs wrong answers on every session that retrieves it KodeKloud's explanation of the memory loop.

Long-term memory is defined by what survives a session boundary. Short-term memory lives in the context window, is linear, and vanishes when the session ends; long-term memory is external storage retrieved by search and ranking Mem0's comparison of short and long term memory. That framing gives the write policy its first test: if a fact will not be useful after the current task ends, it does not belong in the long-term store at all.

A second test comes from how unreliable full-history prompting is. The "Lost in the Middle" result, summarized in the same Mem0 guide, shows accuracy falling when relevant facts sit in the middle of a long prompt, so simply keeping everything and stuffing it into context is not a substitute for selection. Anthropic's operating-system framing makes the same point from the other direction: the main context is small and fast, the external store is large and slow, and explicit store, retrieve, summarize and update operations move data between them the MemGPT paper. A write policy is the set of rules governing the store operation.

The three categories worth writing

Memory taxonomies vary in naming but converge on a few kinds of content. The CoALA framework, as described by Atlan's survey of agent memory types, splits long-term memory into semantic (facts), episodic (past interactions) and procedural (rules and skills), plus the in-context working memory. For a write policy you need something simpler and more operational, because the categories must map to different retention rules.

Facts. Durable statements about the user, team, project or entity. "Prefers direct flights." "The payments service deploys through staging first." "The customer's renewal date is in March." Facts are what an agent would otherwise ask about again, and they are the highest-value entries in the store JetBrains' practical guide to long-term memory. They are also the ones most likely to go stale, which is why each needs a timestamp and a source.

Summaries. Compact records of completed work: what the task was, what was decided, what was produced, and what remains open. A summary is lossy by design, and that is acceptable because its job is to orient the next session, not to reconstruct the last one. MemGPT's queue manager takes exactly this approach, creating a recursive summary when the prompt hits its flush threshold and keeping the evicted messages in recall storage for search the alphaXiv overview of MemGPT. The insight to carry over: summarize on eviction, not on every turn, and keep the raw material addressable.

Observations. Lighter-weight signals from interaction: that a tool call failed for a specific reason, that a particular retrieval query worked, that a document was rejected. Observations are the raw material for procedural memory, and they are the most dangerous category because they are voluminous and often low-confidence. Treat them as staging data, not as durable memory, until they have repeated or been confirmed.

A working model of the distinction: a user saying "I'm vegetarian" should be remembered; a user saying "hmm, let me think" should not AWS's deep dive on AgentCore long-term memory. The AWS write-up also names the harder problem that follows: when a user mentions a shellfish allergy in January and "can't eat shrimp" in March, the system must recognize these as related and consolidate them rather than storing both.

CategoryKeep whenTypical lifetimeExample
FactStable across sessions and scoped to a person, team or entityUntil contradicted or expired"Deploys go through staging first"
SummaryA task, decision or negotiation reached a checkpointLong, with links to source turns"Chose Postgres over MySQL for the reporting service; reasons in ticket 412"
ObservationRepeated at least twice or confirmed by a tool resultShort, reviewed at consolidation"The billing API returns 429 under batch writes"
DropTransient state, pleasantries, guesses, duplicatesNone"Let me check that"

A schema that makes the policy enforceable

A policy written in prose will be ignored by the model that generates the writes. A policy expressed as a schema is checked at the boundary, and rejected entries never reach the store. The fields below are the minimum that make a memory entry auditable and resolvable.

{
  "id": "mem_01J8ZK3Q",
  "type": "fact",
  "scope": {"user_id": "u_8821", "project_id": "payments"},
  "content": "Deployments for payments go through staging before production.",
  "source": {"kind": "user_message", "ref": "turn_47", "session_id": "s_3390"},
  "confidence": 0.95,
  "created_at": "2025-03-04T10:12:00Z",
  "valid_from": "2025-03-04T10:12:00Z",
  "supersedes": null,
  "status": "active",
  "sensitivity": "internal"
}

Each field earns its place. type routes the entry to the right retention rule and the right prompt slot. scope prevents a fact learned in one project from leaking into another, and it is the field that makes deduplication tractable: only entries with the same scope and the same subject can be duplicates. source is what turns a memory into evidence. confidence drives the write threshold and later the retrieval ranking. valid_from and supersedes make conflicts resolvable without deleting history. status lets an entry be retired without losing the audit trail. sensitivity lets you enforce redaction and access rules at write time rather than hoping retrieval filters catch it, a risk that grows with personal semantic memory in particular Mem0's guide to semantic memory.

Two fields are easy to skip and expensive to add later: source and supersedes. Without a source you cannot audit a wrong memory back to the turn that produced it. Without a supersession link you cannot answer "which version was current when the agent acted," which is the first question anyone asks after an incident.

Write rules with thresholds and a worked example

The rules below are meant to be run as a gate between the extraction step and the store. Anything that fails is logged with the reason and discarded, so you can tune thresholds with evidence instead of intuition.

  1. Reject if the entry fails schema validation. Missing source, missing scope, or confidence below 0.6 on a fact goes to the log, not the store.
  2. Reject if the content is transient. Anything describing current state of the conversation ("okay", "checking now", "as I said above") is dropped. The test is whether the sentence would still be true and useful in a new session with no prior context.
  3. Reject if it is an inference the user never confirmed. "The user probably wants a promotion" stays out. If an inference is worth keeping, store it as an observation with confidence below the fact threshold and let repetition or confirmation promote it.
  4. Deduplicate by scope and subject before insert. Compute a small number of subject keys per entry (user plus attribute, project plus decision) and compare new content against active entries with the same key. Near-duplicates above a similarity cutoff update the existing entry's timestamp and confidence rather than creating a new row.
  5. Resolve conflicts by scope specificity, then recency, then source strength. A newer user statement beats an older one for user-scoped facts. An explicit commitment beats an inference. A tool result beats a model guess. The loser is marked superseded, never deleted.
  6. Expire by type. Observations expire on a fixed clock (a common starting point is 30 days) unless promoted. Facts expire only when contradicted or when their subject disappears. Summaries persist with links to source turns.
  7. Consolidate on a schedule, not on every write. Batch observations into topic-level entries during a nightly or threshold-driven pass, which is the pattern both AgentCore's extraction and reconciliation pipeline and the topic-document design in Infini Memory converge on.

A worked example makes the arithmetic concrete. Suppose an agent handles 40 turns per session and naively writes a memory note every 3 turns, or roughly 13 notes per session. At 500 sessions a day that is about 6,500 notes daily, or roughly 2.4 million a year. If each note averages 40 tokens and retrieval pulls 20 candidates per query, the store alone is not the problem; the problem is that most of those notes are restatements. Applying rules 2 through 4 typically collapses this to a few hundred durable entries per user plus periodic summaries, because most of the 13 notes per session are either the same fact rephrased or conversational noise. The value of the thresholds is not academic: the difference between a 2.4 million-row haystack and a few hundred curated entries is the difference between retrieval that works and retrieval that returns plausible noise.

Deduplication: keys first, vectors second

Vector similarity is the wrong primary deduplication mechanism, because it is symmetric in a way that meaning is not. "User prefers window seats" and "User prefers aisle seats" are near-identical in embedding space and exact opposites in content. Deduplicate on keys, then use similarity only inside a key.

A practical pipeline has three stages. First, extract candidate subject keys during the write step: for facts, an entity plus attribute pair; for summaries, a task identifier; for observations, a tool or subsystem name plus a symptom. Second, look up active entries sharing a key. Third, compare text within that small set, merging when the meaning matches and treating a mismatch as a conflict rather than a duplicate. Agents that skip the key stage end up with the fragmentation problem described in Infini Memory, where evidence about the same user or task is spread across many small records and no single retrieval assembles the whole picture.

Merge behavior matters too. When a new statement refines an old one, the right move is often to update the existing entry's content and valid_from while keeping the original created_at and source, rather than writing a second entry. That preserves the fact that the preference has been stable since the original date, which is itself useful signal.

Conflict handling: the decision rule

Conflicts are inevitable once memory spans months, and the resolution rule should be written down before it happens. This ordering works for most assistant and workflow agents:

SituationWinnerAction on loser
Same scope, same subject, newer user statement contradicts olderNewerMark superseded, link both ways
User statement contradicts a model inferenceUser statementLower inference confidence or delete if below threshold
Tool result contradicts eitherTool resultMark both older entries superseded with the tool reference
Two entries from different scopes (personal vs team)Both stay, scopedNone; scope prevents collision
Two entries from the same session, unresolvedKeep both as observationsFlag for review at consolidation

The rule to remember is that recency is a tiebreaker within a scope, not a global override. A team-level convention recorded last year should not be overwritten by one user's preference stated this morning, because they are answering different questions. AWS's account of extraction and consolidation makes the same point about temporal ordering: memories have to be processed in order of their timestamps or the merge produces a state that was never true AWS's deep dive on AgentCore long-term memory.

There is also a case for keeping contradictions visible. When a user changes their mind, the period of validity is information. "Prefers Python until March, then Rust" tells a coding agent something that "prefers Rust" alone does not.

Auditing, privacy and the operational loop

A write log is not optional. Every rejected entry, every merge and every supersession should be recorded with the rule that fired, because the failure mode you will actually face is not a missing memory but a confidently wrong one, and the first question will be where it came from. Store the log as append-only records that reference memory IDs, and give support and engineering a query to trace any retrieved memory back to its source turn.

Privacy belongs in the same pipeline, not a later filter. Personal semantic memory is by definition facts about a specific user, and the risk profile differs by memory type, which is why sensitivity should be set at write time and enforced before the entry is embedded or indexed Mem0's semantic memory guide. The same discipline applies to shared memory across agents: if two agents write to one store, the schema's scope and source fields are what keep one agent's guesses from becoming another's facts MongoDB's overview of agent memory.

Two operational habits keep the store honest. First, run a periodic sample audit: pull a random set of active entries per type and check them against their sources, tracking the wrong-entry rate as a metric with an owner. Second, review the drop log, because the most common tuning signal is a category of entry being rejected at a rate that suggests the threshold or the extraction prompt is wrong. If a specific type of useful memory is being dropped consistently, the fix is usually in extraction, not in the threshold.

Framework choice affects how much of this you build. Mem0 reports substantial reductions in tokens and latency against full-context prompting by running an extract, consolidate, store, retrieve pipeline, so the extraction and consolidation steps are worth evaluating before writing your own Mem0's long-term memory guide. The same pattern shows up across implementations, from Redis-backed session and long-term stores to managed services that handle extraction and reconciliation for you Redis on agent memory. What none of them can decide for you is which of your domain's facts are worth keeping, and that is what the schema and the rules above are for.

If your agent already retrieves well and the remaining problem is deciding what to write, the natural next step is to run those extraction and consolidation calls through a single endpoint rather than wiring a separate provider for each model you test; Quanta Inference puts text, embedding and other model types behind one OpenAI-compatible API: https://quantaintelligence.ai/inference.

FAQ

FAQ

What should an agent never write to long-term memory?

Transient conversational state, unconfirmed inferences about the user, and restatements of entries already in the store. Also drop anything whose source you cannot record, because a memory you cannot trace back to a turn is a rumor you will eventually have to defend. The AWS guidance puts it simply: "I'm vegetarian" belongs in memory, "hmm, let me think" does not.

How do I deduplicate memories that mean the same thing in different words?

Compare entries only within a shared subject key, such as user plus attribute or project plus decision, and use embedding similarity just to merge text inside that small set. Comparing across keys is what creates the classic error of merging "prefers window seats" with "prefers aisle seats." When a new entry refines an old one, update the existing record and keep its original creation date.

How should conflicts between two memories be resolved?

Check scope first, because personal and team-level facts answer different questions and can both be true. Within the same scope, prefer the stronger source (tool result over user statement over inference), then the newer timestamp. The losing entry is marked superseded with a link to the winner, never deleted, so the change history survives.

When should a memory expire?

Observations should expire on a clock, commonly around 30 days, unless promoted by repetition or confirmation into a fact. Facts expire when contradicted or when their subject no longer exists. Summaries persist as long as the work they describe is relevant, with links back to the source turns so a reader can check the detail.

Do I need a write log if the schema is strict?

Yes. A schema catches malformed entries but says nothing about whether a well-formed entry is true. The write log records every rejected and merged entry with the rule that fired, which is how you tune thresholds and answer the question that follows any bad agent decision: where did this memory come from, and what replaced it.

Sources

Sources

  1. Agent Memory Explained in 5 Minutes - YouTube
  2. Long-Term Memory for AI Agents: The What, Why and How - Mem0
  3. 2310.08560 MemGPT: Towards LLMs as Operating Systems - arXiv
  4. Types of AI Agent Memory: Episodic, Semantic, Procedural and More
  5. What Is Long-Term Memory in AI Agents? A Practical Guide
  6. MemGPT: Towards LLMs as Operating Systems - alphaXiv
  7. Building smarter AI agents: AgentCore long-term memory deep dive - AWS
  8. Semantic Memory for AI Agents: Facts, Relationships - Mem0
  9. Maintainable Topic Documents for Long-Term LLM Agent ...
  10. What Is Agent Memory? A Guide to Enhancing AI Learning ...
  11. Build AI agents with short-term & long-term memory in Redis
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles