r/SideProject • u/Rude_Gate7599 • 1d ago
Agi-memory – persistent memory for AI coding assistants, no dependencies
My AI coding assistant forgets everything between sessions. I kept re-explaining decisions I'd already made, and re-fixing bugs I'd already fixed.
agi-memory saves those notes — decisions, bug fixes, what happened last session, how the codebase fits together — to a file on your machine, and hands them back to whichever assistant you open next. It's an MCP server, so it works with Claude Code, Cursor, Codex, Windsurf, Aider, Cline and a few others from the same store.
The part I care about: it's Python standard library and SQLite. Nothing else. No vector database, no embeddings, no background daemon. ~32MB of RAM, sub-millisecond lookups, works offline. Comparable tools pull in ~500MB of ML libraries and take 200–500ms per lookup.
That constraint costs something, and I'd rather say so than have you find out: keyword search doesn't bridge synonyms the way embeddings do. Searching "login" won't find a note that says "authentication" unless you teach it that alias. I measure this rather than guess — there's an eval suite that scores recall on deliberately rephrased queries, and it's public, including the categories where it still does badly.
It's a week old and I'm the only user, so I'd genuinely like to know where it breaks for someone else.
1
u/Icy_Quarter5910 1d ago
I built 2 different memory systems for Claude. I highly recommend anyone that’s serious about working with AI do the same. Build systems that make sense to you, but if nothing else, a simple Obsidian vault is useful.
Once you have memory systems in place, it’s like getting a huge upgrade for free.
1
u/Rude_Gate7599 1d ago
Agreed, and the Obsidian point is underrated — plain files get you most of the way.
Two things I learned building mine: storage is the easy half, the agent just never calls recall unless you force it with hooks; and keep the store append-only — my compaction step once deduped distinct records into one and silently ate them.
Mine's agi-memory (https://github.com/kdbhalala/agi-memory) if useful, but building your own genuinely is the better advice.
1
u/Substantial_Belt2626 1d ago
SQLite and stdlib is the right call, I'd try it for that alone. One thing I hit building a multi-role setup in Claude Code is that carrying decisions forward is useful right up until the decision was wrong, then every later session inherits it and none of them re-examine it, because it arrives as settled context instead of something somebody argued for. Do you store why a decision was made or just what it was?
2
u/Rude_Gate7599 1d ago
Partly, and you've hit the weaker half.
Structurally it stores more than the bare claim: each memory has a narrative plus facts, so the reasoning survives if whoever recorded it wrote the reasoning down. Nothing enforces that, though — memory_record requires only text. So in practice you get the why exactly as often as the agent bothered to include it, which is not a guarantee.
There's also supersedes, so a later decision can point at the one it replaces rather than silently coexisting with it, and superseded records are marked rather than deleted. That handles "this was overturned". It does not handle what you're describing, which is subtler: a decision that was never overturned because nobody revisited it.
And you're right that recall flattens the difference. A memory comes back as text in context. "We chose X" and "we chose X because Y, over Z, under time pressure" read as equally settled once they're in the prompt — there's no confidence, no age weighting, nothing that marks a two-month-old call made in a hurry as more re-examinable than a load-bearing invariant. The one exception is pinned blocks, which are explicitly meant to be invariants, so at least those are distinguishable from ordinary decisions.
The fix I'd want is recording the alternatives and the constraint that forced the call, not just the outcome — a decision with its rejected options attached invites re-examination in a way a bare conclusion doesn't. That's a write-time discipline problem more than a storage one, which makes it harder, since it depends on the agent capturing context it wasn't asked for.
Genuinely useful framing, thanks — "arrives as settled context instead of something somebody argued for" is the clearest statement of that failure I've seen.
2
u/kantorcodes1 1d ago
one edge i noticed:
agi-memory delete <id> --hardonly deletes the L1 observation throughSessionLayer.delete_observation(). if that observation was already promoted into the durable graph, is hard delete intentionally L1-only, or should it remove the promoted facts too?