Medallion architecture for an agent's memory

Layered rock strata in the Grand Canyon, distinct horizontal bands stacked over an immutable base
Photo: “Grand Canyon National Park: The Abyss Overlook” by Grand Canyon NPS, licensed under CC BY 2.0.

I set out to build a memory layer for my agents — somewhere they could write what they learned and read it back later without me hand-feeding context into every prompt. A few weeks in, I looked at the schema I'd drawn and laughed, because I'd reinvented something I've been building in data lakes for years. Bronze, Silver, Gold. The medallion architecture, transplanted out of the warehouse and into an agent's recall. It turns out the pattern that keeps analytics honest is the same one that keeps memory honest.

If you've built medallion pipelines, you already know most of this — you just haven't pointed it at an LLM yet. Let me walk you through the transplant, layer by layer, and the one invariant that makes the whole thing work.

Medallion flow: Bronze (raw, immutable, append-only) feeds Silver (distill, embed, conflict-resolve, score), which feeds Gold (MCP tools plus overlays where human edits win); Silver is always rebuildable from Bronze
Bronze → Silver → Gold for an agent's memory — and the invariant that holds it up: Silver is always rebuildable from Bronze.

Bronze: raw, immutable, append-only

Every event an agent or a human emits lands first in a single table I think of as Bronze — an append-only archive. Raw content goes in verbatim and is never modified after insert. A session transcript, a note, a commit, an issue: it gets wrapped in a small contract and stored exactly as it arrived.

That contract carries a few fields that earn their place. A source and a source_event_id together form an idempotency key, so re-submitting the same event returns "duplicate" instead of creating a second copy — re-running an ingest is safe. A namespace scopes the record to an owner or a project and acts as a contamination firewall, so one client's memory can't bleed into another's. And a provenance_root points back to the upstream source of truth, so every memory can be traced to where it actually came from.

The discipline here is the same as in any lakehouse: Bronze is sacred and dumb. It doesn't interpret, it doesn't clean, it doesn't dedupe the content. It just remembers, faithfully, forever.

Silver: derived, cleaned, the part the system owns

Silver is where the raw event becomes usable knowledge, and it's owned entirely by the engine — no consumer reaches in and writes here. For each Bronze row, a derivation runs in four steps:

  1. Distill. An LLM pulls atomic facts out of the raw content — each fact self-contained, specific, and testable. One messy transcript becomes a handful of clean assertions.
  2. Embed. Each fact gets a vector, indexed for similarity search. This is what makes recall semantic instead of keyword-bound.
  3. Resolve conflicts. Before a new fact is stored, the system finds existing facts that are close in vector space and asks an LLM to judge: is this new, a refinement, or a contradiction? It resolves to add, update, supersede, or skip.
  4. Score. The fact gets an importance score, so later recall can prioritize what matters.

The supersede case is the one I want you to sit with. When a new fact contradicts an old one, the old fact isn't deleted — it gets an end-timestamp and steps aside. Yesterday's truth is still on disk, marked as no-longer-current. Memory doesn't overwrite; it keeps a history of what it used to believe and when that changed.

Gold: shaped for whoever's asking

Gold is what consumers actually touch, exposed through capability-gated tools — search, read, list — so an agent gets only the access it's been granted. Nothing queries the raw archive directly; everything comes through this projection.

Gold is also where humans get to disagree with the machine. A person can write an overlay — an edit, an annotation, a redaction — anchored to a span of a derived fact. On read, the system composes the Silver fact with the human's overlay laid on top, and the human's version wins. The machine's derivation is a draft; a person's correction is final. When Silver later re-derives from Bronze with a better model, those overlays re-anchor onto the new text rather than getting silently dropped. Human judgment survives a model upgrade.

The invariant that makes it all work

Here's the line that holds the whole structure up, and it's lifted straight from the lakehouse playbook: Silver is always rebuildable from Bronze.

Everything above the raw layer is disposable. If a better extraction model ships next quarter, I don't migrate Silver — I throw it away and re-derive it from Bronze. If I find a bug in the conflict-resolution logic, same move: fix the code, rebuild from the immutable source. The refined layers are a cache of my best current interpretation, not a second source of truth. There's exactly one source of truth, and it's the dumb append-only table at the bottom.

That invariant is also what makes the system safe to automate, which is the part that surprised me. Because re-deriving Silver is reversible, the engine can do it on its own. The only operations that need a human in the loop are the genuinely irreversible ones — destroying a Bronze record, or overwriting a person's overlay. Reversibility, not the model's confidence, draws the line between what the system does autonomously and what it asks permission for.

Where it costs you

I'm not going to sell you a free lunch. Medallion-for-memory has a real bill attached. Every Bronze row triggers an LLM distill and an embedding call, so ingest isn't cheap — you're paying model inference to turn raw events into facts, at the rate events arrive. The conflict-resolution threshold is a genuine knob, not a setting you get right once: too loose and contradictions slip through as duplicate "facts," too tight and real updates get filed as brand-new beliefs. And the rebuild-from-Bronze guarantee is only as good as your discipline about Bronze — the day something quietly prunes the raw layer to save space, the entire safety story collapses and you won't notice until you try to rebuild.

None of that has talked me out of it. The same separation that keeps a data lake trustworthy — immutable raw, disposable derivations, a consumer layer that never mutates the source — is exactly what an agent's memory needs, for exactly the same reasons. I've been doing medallion since before I called it that. It just took building a brain for my agents to realize the pattern was never really about analytics.

If you're storing what your agents learn, I'd love to know whether you landed somewhere similar or solved it a different way. As always, I'm here to help.