An agent without memory asks the same questions every session. An agent with careless memory is worse. It remembers a wrong fact forever, repeats something a user said in confidence, and gets slower every week.
Memory isn't a feature you switch on. It's a small data system with its own rules. Here's how we design it.
Four kinds of memory, four different jobs
Most problems start when these get mixed together.
- Working memory. What the agent holds during one task: the request, the tool results so far, the plan. It lives in the context window and goes away when the task ends.
- Session memory. What happened earlier in this conversation or job. Usually a running summary plus the last few turns in full.
- Long-term facts. Things that stay true across sessions: a user's role, a project's naming rules, a decision the team made. Stored outside the model and looked up when needed.
- Procedures. How to do a recurring task well: the steps that worked last time, the mistakes to avoid. This is the one teams forget, and often the most valuable.
Store each one separately. They have different lifetimes and different owners.
Decide what's allowed to be written
The default should be to write nothing. Then add rules for what earns a place.
- Write what a person stated or confirmed. "Reports go out on Fridays" is a fact. The agent's guess about why is not.
- Don't write the agent's own conclusions as facts. They compound. One wrong inference becomes the premise for ten more.
- Don't write what expires on its own. A ticket number, today's file name, a temporary workaround.
- Never write what the user wouldn't want kept. Set the sensitive categories up front and block them in code, not in the prompt.
Tag every entry with where it came from and when. You'll need both later.
Keep entries small and specific
One fact per entry. "Prefers tables for comparisons" is useful. A three-paragraph summary of a conversation is not, because you can't tell which part is still true.
When a fact changes, update the entry. Don't append a second one that disagrees with the first. Two conflicting memories are worse than none.
Retrieve less than you think
Loading every memory into every prompt costs money and hurts answers. The model starts applying facts that don't fit the task.
Retrieve by relevance to the current request, cap how many entries come back, and prefer recent and confirmed entries over old and inferred ones. If nothing is relevant, load nothing.
Give memory an expiry and an owner
Facts go stale. A team lead leaves. A policy changes. Build that in.
- Entries past a set age get rechecked or dropped.
- An entry that keeps being retrieved and never used gets dropped.
- The user can see what's stored about them and delete it.
That last point isn't a courtesy. If people can't see and correct the memory, they stop trusting the agent the first time it's wrong.
Respect permissions
Memory written in one context shouldn't leak into another. What an agent learned helping one team doesn't belong in answers for a different team. Scope every entry to a user, a project or a group, and filter on that scope at retrieval, before the model sees anything.
Test whether memory helps
Memory can make an agent worse, so measure it. Take your evaluation set and run it twice: once with memory, once without.
- Did answers improve on tasks that need history?
- Did they get worse on tasks that don't?
- Did the agent ever apply a stale or out-of-scope fact?
Add cases built to trip it: a fact that changed, a fact from another user, a fact that sounds relevant and isn't. We cover the test method in how to test an AI agent before production.
The short version
Separate the four kinds. Write only what was stated. Keep entries small, dated and scoped. Retrieve sparingly. Expire on purpose. Let people see and delete. Test with memory on and off.
We build agents with governed memory for federal programs and operations teams. See how we engineer AI systems or tell us what you're building.