Designing an AI memory
If you are building one rather than buying one, these are the five decisions that determine whether it works. They are listed in the order they become painful, which is not the order they seem important.
One: what a memory is
The choice is between storing tellings and storing facts. A telling is that on the 3rd, Marcus said the price was 2,340. A fact is that the price is 2,340.
Storing only tellings makes contradiction impossible to represent: two tellings that disagree are just two rows. Storing only facts loses the ability to say where anything came from, which is the first thing anyone asks when a memory turns out to be wrong.
Store facts, each pointing at the tellings that support it. It is more work up front and it is the only shape that supports both questions.
Two: when to extract
Extraction can happen on write or on read. On read is tempting because it defers work you may never need, and it is wrong: every query then pays for extraction, and recall is the hot path.
On write means the write is slow, which means it should be asynchronous, which means a caller cannot read back what they just wrote. That is the cost. Pay it visibly by returning a job rather than hiding it behind a response that implies the write is done.
Three: entity resolution
This is the part that is always underestimated. The same person appears as an email address, a display name, a Slack handle and a first name in a transcript, and unless something unifies them, a search for one finds a quarter of what is known.
Matching on exact strings is not enough and matching on embeddings alone is worse: two different people at the same company are highly similar in vector space. What works is several signals combined, with a confidence attached, and a way for a wrong merge to be undone. Assume you will get some wrong.
Four: contradictions
Two sources will disagree. The design question is what happens then, and there are only three answers: newest wins, highest confidence wins, or keep both.
Newest wins is what almost everybody builds first, and it fails on the case that matters. A stale source that syncs late overwrites a correct newer fact, and there is no record that anything was replaced.
Keeping both, marking the older superseded, and surfacing the conflict costs a table and some interface work. In exchange the system is uncertain when it should be, which is the property you actually wanted.
Five: where authorisation lives
The tempting design applies permissions at query time: store everything, filter on read. It fails the moment anything is derived. A summary of ten private messages is a new row, and unless the scope came with it, that row has no permissions at all.
Carry scope through every transformation and never widen it. Extraction, consolidation and summarisation all have to preserve it. This is invasive and it is the difference between a system that leaks and one that does not, and a leak here happens through the feature the product is sold for.
Common questions
- Should memories be stored as text or as structured data?
- Both. Text is what retrieval works on and what a model reads; structure is what makes a fact comparable to another fact, which is what contradiction detection needs. Storing only one of the two means giving up either recall quality or the ability to notice a disagreement.
- How do you stop a memory store filling with noise?
- Extract conclusions rather than storing everything, deduplicate on write, and be willing to keep less. A store where recall returns five good memories is more useful than one where it returns fifty adequate ones.
- How do you handle a memory becoming wrong?
- Supersede rather than delete. The new fact points at the old one, the old one is marked superseded rather than removed, and both keep their sources. Deleting loses the ability to explain why the answer changed.
- What happens when you change embedding model?
- Everything is re-embedded, which is why embedding should be its own stage rather than part of the write. If it is inline, changing models is a migration that stops writes; if it is separate, it is a background job.