Agent Memory

I didn't give my agents a vector database. I gave them 126 text files.

The memory my agents actually run on is a folder of plain text files and one index that loads every session. Why I skipped the vector database, the schema that makes it work, and the failure modes nobody warns you about.

A filing cabinet that remembered what the terminal forgot.

Every conversation my agents have starts from nothing. The model that helped me debug a deploy on Tuesday has, on Wednesday, no idea that the deploy or the debugging or Tuesday ever happened. A context window is a whiteboard, not a notebook: it holds everything while you are in the room and is wiped the moment you leave.

This is the most disorienting thing about building with agents in 2026. They are brilliant and they have amnesia. So the question that actually matters is not which model. It is what the model is allowed to remember between the times you talk to it, and how.

The memory my agents run on is a folder. As of this morning it holds 126 Markdown files and one index. No database, no embeddings, no retrieval service. I want to walk through why it is shaped the way it is, because nearly every instinct I had at the start turned out to be wrong.

The answer I didn't build

The reflexive 2026 answer to 'give the agent a memory' is a vector database. Embed every note and transcript and fact into a pile of numbers; at question time embed the question too and pull back the nearest few by cosine similarity. It is a genuinely good tool for the problem it solves, which is finding a needle in millions of documents you will never read yourself.

That is not my problem. My problem is a few hundred facts, all of which I could read in an afternoon, most of which I will want to edit or delete within a month. At that scale a vector store optimizes the one thing I don't have, which is scale, and taxes the four things I actually need.

And there is a quieter reason. Retrieval is a step, and every step is a place to be silently wrong. A vector search that returns the wrong three chunks does not throw an error. It just answers with the wrong context, and you never see the retrieval that didn't happen. I have written enough here about systems that fail without telling me. I did not want memory to be another one.

What it actually is

Strip the mystique and it is a directory:

memory/
  MEMORY.md            <- the index, loaded every session
  user-role.md         <- one fact
  git-no-coauthor.md   <- one fact
  ... 124 more files

126 files, roughly 65,000 words in total. That total is misleading, though, because the point is that no single fact is longer than a screen or two. Each file holds one thing the agent learned, with a short frontmatter header so the fact knows what kind of fact it is:

---
name: git-no-coauthor-trailer
description: Never add Co-Authored-By trailers to my commits
metadata:
  type: feedback
---

Does not want Co-Authored-By trailers on git commits, ever, in any repo.
This overrides the default commit template that adds one. When committing:
write a normal message with no trailer.

That is a real memory, lightly trimmed: a note the agent wrote about me after I corrected it exactly once. It earns its own file because of what it does. It silently overrides a default I would otherwise have to re-correct in every repository, forever. That is the entire value proposition of agent memory in one example. A correction you make once should cost you once.

Every file declares one of four types, and the types are a forcing function for taste more than they are a technical feature:

That distribution, 90 project against 20 reference, 12 feedback, and 3 user, is itself a readout of what an agent actually needs told to it. Almost none of it is about me as a person. Almost all of it is the running state of work that the code alone leaves unexplained.

The whole trick is the index

Here is the part that lets it work with no retrieval service at all, and it is almost embarrassingly simple: the index is small enough to load in full, every single session.

MEMORY.md is one line per memory. A title, a link to the file, and a one-sentence hook:

- [git-no-coauthor-trailer](git-no-coauthor.md) - never add Co-Authored-By trailers
- [project-x-state](project-x-state.md) - where the thing I'm building currently stands

The whole index is about 19 kilobytes. That fits inside a session's context with room to spare, so the agent never has to search. It simply always has the table of contents in front of it and opens the one or two full files a task actually needs. Recall stops being a search problem and becomes a reading problem.

This is exactly the trade a vector database is built to avoid, and at my scale the trade is free. When the index eventually outgrows the context budget, at tens of thousands of memories, you have to shard it, and maybe then you want embeddings over the index itself. But I have 126 memories. Most people asking how to give their agent a memory have far fewer than they fear, and are reaching for infrastructure to solve a problem they will not have for years.

It also means the one-sentence hook is the most load-bearing text in the system. That line is what the agent reads to decide whether to open the file at all. A memory with a vague hook is a memory that never gets opened: functionally invisible, however good its contents. I now spend more care on the index line than on the file it points to.

Why each rule earns its place

A handful of conventions do the real work, and each one is here because its absence bit me first:

Writing is easy. Not writing is the skill.

The hard part of a memory system is not the save path. It is the restraint. Every junk memory you keep does not merely waste a file. It adds a line to the index, and the index is a fixed budget of attention. Ten low-value memories dilute the signal of the good ones the agent has to scan past them to reach.

So the two most important operations are the ones that add nothing. Before saving, check whether a file already covers this and update that one instead of spawning a near-duplicate, because duplicated beliefs are how a store starts quietly contradicting itself. And when a memory turns out wrong, delete it; do not just write a fresher one beside it. A memory system's quality is set by what it refuses to keep.

The failure modes nobody warns you about

Six months in, the interesting problems are not about storage at all. They are about truth over time.

Memory rot is the big one. A memory records what was true the day it was written, and then the world moves. A note names a file, a port, a hostname, a flag, and then the file is renamed and the note goes on confidently asserting the old name. The mitigation I run is a discipline, not a mechanism: a recalled memory is background context, not gospel, and anything it names gets checked against reality before I act on it. That helps. It does not make the rot stop.

The atomic-fact ideal drifts, too. The rule is one fact per file; the reality is that 23 of my 126 files have grown past 800 words, and the median sits at 332. Project memories especially accrete: a clean fact becomes a running log becomes a small dossier. It is not exactly wrong, but it erodes the very thing that made files better than a database, which was that each one was a single, deletable belief.

The index drifts out of sync with the store. It is maintained by hand, so it lags. This morning there were 125 index lines against 126 files. A memory that is not in the index is, for every practical purpose, a memory that does not exist, because the index is the only part guaranteed to be read. The folder is the source of truth for contents; the index is the source of truth for what is even findable, and keeping those two sets equal is manual work that nothing enforces.

And the subtle one: a recalled memory looks a great deal like an instruction. A note that says 'always deploy with the safe flag' reads, to a model, almost exactly like a live command to do so. But it is not a command. It is a dated observation from a past session that may no longer hold. If a system treats its own memories as orders rather than as evidence, the oldest and stalest belief in the folder gets a vote on today's action. Memories are notes from a previous self. You weigh them; you do not obey them.

There is a security edge here that I think about more than I expected to. This folder is, by design, where the private context collects: the things I would never paste into a public tool. That is the argument for keeping it in plain files on my own disk rather than a hosted index. But it also means the memory directory has quietly become one of the most sensitive things on the machine, and unlike code it never gets reviewed. Half of what is in mine is why every example in this piece is trimmed and genericized. The schema is safe to show. The contents are not.

The honest read

Here is what I actually learned building this. The system is excellent at remembering and has no idea how to forget.

I built the write path completely: save, type, link, index. I never built the reaper, the process that revisits an old memory, asks whether it is still true, and retires it when it is not. So the store only grows, and because facts decay, its average truthfulness only falls. Every day it knows more things, and a slightly larger share of them are wrong.

That is the same shape as the last machine I wrote about here, the one that published 278 articles to nobody. There I built the half of the system that produces and skipped the half that judges whether producing was working. Here I built the half that remembers and skipped the half that decides what is still worth believing. A memory without forgetting is not a memory. It is an attic. Mine has 126 boxes in it, and I have never once thrown one away.

References

The memo

Get the memo before it becomes consensus.

One sharp memo on sports AI, media rights, athlete data, scouting systems, or sports business. No generic roundup.

Or follow on X: @TheFieldSignal