{"slug": "consolidation-the-half-of-agent-memory-nobody-builds", "title": "Consolidation: the half of agent memory nobody builds", "summary": "A developer argues that agent memory systems need a consolidation stage beyond the standard record-and-recall pattern, addressing duplicates, silent contradictions, and unbounded growth that degrade retrieval quality over time. The proposed approach includes merging high-confidence duplicate entries, marking superseded decisions rather than deleting them, applying age-based decay weights, and running consolidation out of band with reviewable diffs.", "body_md": "Every agent memory project I've seen (including the first two versions of mine) builds two things: `record` and `recall`. You write something down, you read it back. Ship it.\n\nThen, three weeks in, recall quality drops — and nobody can explain why, because nothing in the system got worse. Nothing in the system got *cleaned*, either.\n\nThat's the missing stage. Consolidation.\n\nThree mechanisms, all of them boring and all of them certain:\n\n**Duplicates.** The same fact gets recorded five times across five sessions, each with slightly different wording, because nothing at write time knew it already existed. Retrieval now returns five near-identical entries and burns its budget on one fact.\n\n**Silent contradiction.** The store says `using poetry for dependency management` and `switched to uv because CI install time` — both true, one superseded. Nothing marks which one is current. The agent picks whichever one scores higher on embedding similarity that day. You get non-deterministic behaviour that looks like a model problem and is actually a data problem.\n\n**Unbounded growth.** If nothing is ever pruned or compacted, a fixed retrieval budget has to cover an ever-larger candidate set. Recall doesn't fail loudly; it just gradually returns more generic, less useful context.\n\nNone of these are fixed by a better embedding model. They're fixed by a process that runs on the store itself.\n\nConsolidation is not one thing. It's four, and they have different failure modes.\n\nTwo entries that assert the same thing should become one, with both sources attached. The hard part is not detecting similarity — it's deciding when similarity means *same assertion* versus *related but distinct*. \"We use Postgres\" and \"we use Postgres in the billing service only\" are 0.9 similar and must not be merged.\n\nPractical rule I use: merge automatically on high-confidence matches, and queue anything in the ambiguous band for review. Do not let the ambiguous band be auto-merged. That band is exactly where the information lives.\n\nWhen a decision is reversed, the old entry should remain, marked as superseded, linked to the entry that replaced it. Deleting it is the tempting option and it's the wrong one, because the reason a decision was reversed is the thing you'll need again in three months.\n\nAn entry needs, at minimum:\n\n```\n{\n  \"id\": \"mem_7f3a\",\n  \"type\": \"decision\",\n  \"text\": \"use uv instead of poetry for dependency resolution\",\n  \"rationale\": \"poetry's lockfile resolution was too slow in monorepo CI\",\n  \"created_at\": \"2026-04-11T09:12:00Z\",\n  \"valid_from\": \"2026-04-11\",\n  \"valid_until\": null,\n  \"supersedes\": [\"mem_2c91\"],\n  \"superseded_by\": null,\n  \"sources\": [\"session/2026-04-11#turn-42\"]\n}\n```\n\n`supersedes` / `superseded_by` turn your memory store into a graph rather than a bag. It's what lets you answer \"why is it like this now\" instead of only \"what is it now\".\n\nOld entries shouldn't be deleted; they should lose rank. Store a decay weight derived from age and access, and let retrieval use it as one signal among several. An entry that hasn't been relevant in six months but is still true should be cheap to keep and cheap to ignore.\n\nDeletion is for garbage (duplicated, malformed, explicitly retracted). Everything else ages.\n\nTwo checks, at two different times:\n\n**Type your entries.** Free-text blobs retrieve badly. `fact` / `decision` / `pitfall` retrieve under different policies, and mixing them means you always get an average of everything. \"This project uses uv\" (fact), \"we chose uv because CI needed to be fast\" (decision), and \"poetry's lockfile has a path bug in monorepos\" (pitfall) need different ranking.\n\n**Make consolidation idempotent and reviewable.** It should produce a diff you can read, not an opaque rewrite. If a background process silently rewrites your project history and you can't audit it, you've built a system you can't trust — and you won't notice until it has already misled you a dozen times.\n\n**Run it out of band.** Not in the request path. Consolidation is a batch job that runs between sessions; doing it inline adds latency to the exact moment you're waiting on the agent.\n\n**Anchor memories to something stable.** Bind entries to a git remote or a project id, not an absolute path. Directory renames and moves are common and will otherwise silently detach the entire history.\n\n**Over-merging first.** My earliest merge threshold was too permissive and it collapsed distinct decisions into one averaged entry. Recovering the original two required going back to raw session logs. The information was gone from the store and only existed in the transcript. Aggressive merging feels like progress and quietly destroys the thing you built the system for.\n\n**Treating consolidation as a one-shot cleanup.** I ran it once, was happy with the result, and made it manual. It needs to be scheduled. The store doesn't stay tidy; it's a garden, not a build artifact.\n\nI deliberately won't quote numbers here, because my deployment is small and any percentage I gave you would be noise dressed as evidence. What I do track are proxies that are meaningful even at small scale:\n\n| Signal | What it tells you | \n|---|---|\n| Count of superseded entries | Whether reversals are being captured at all | \n| Longest supersession chain | Whether you can reconstruct decision history | \n| Share of recall results that are already superseded | Your staleness rate — should trend toward zero | \n| Duplicate clusters merged per pass | Whether write-time filtering is too loose | \n| Size of the ambiguous review queue | Whether you're guessing too much | \n\nIf the staleness share is climbing, your consolidation isn't running or isn't looking at the right thing. That ratio is the closest thing to a health check I've found.\n\nI run this as a local-first memory layer — everything on local disk, retrieval local, no cloud round-trip, and consolidation as a scheduled offline pass. The tradeoffs are real and I'll state them plainly: no cross-device sync (you move the files yourself), no team-shared memory, and it's Windows-only right now. macOS is planned, not shipped.\n\nAccess is over MCP, a desktop connection, or Python / Node SDKs depending on the client. And one honest caveat for anyone outside China: the trial signup uses a Chinese phone number or WeChat login, so it's realistically aimed at a China-based audience — I'd rather say that up front than have you hit a wall at the signup screen.\n\nIf you're building memory for an agent and you've reached the point where storing works but recall is degrading, consolidation is probably the missing piece. The two questions worth asking yourself: *can I reconstruct why a decision changed?* and *do I know what fraction of what I hand the model is stale?* If either answer is no, that's the next thing to build.\n\nI write about this as I go — part 1 covered the eight failure modes I hit getting memory to work at all:\n\n→ [I gave my AI coding agents a local long-term memory layer — 8 things that broke](https://dev.to/qianqiuwanzi/i-gave-my-ai-coding-agents-a-local-long-term-memory-layer-8-things-that-broke-a5i)\n\nAnd if you want to look at the implementation: [https://hm.qianshi.cool/api/v2/dl?from=devto](https://hm.qianshi.cool/api/v2/dl?from=devto)", "url": "https://wpnews.pro/news/consolidation-the-half-of-agent-memory-nobody-builds", "canonical_source": "https://dev.to/qianqiuwanzi/consolidation-the-half-of-agent-memory-nobody-builds-4lfg", "published_at": "2026-09-16 03:59:07+00:00", "updated_at": "2026-09-16 04:08:28.768123+00:00", "lang": "en", "topics": ["ai-agents", "ai-infrastructure", "large-language-models", "mlops"], "entities": [], "alternates": {"html": "https://wpnews.pro/news/consolidation-the-half-of-agent-memory-nobody-builds", "markdown": "https://wpnews.pro/news/consolidation-the-half-of-agent-memory-nobody-builds.md", "text": "https://wpnews.pro/news/consolidation-the-half-of-agent-memory-nobody-builds.txt", "jsonld": "https://wpnews.pro/news/consolidation-the-half-of-agent-memory-nobody-builds.jsonld"}}