Ahmed Doghri Logo Image
Ahmed Doghri

agentmem

Your agent does not need to remember that you said "ok sounds good" on a Tuesday. Most agent memory is a junk drawer with embeddings. This one is Marie Kondo with exponential decay: it keeps what matters, drops the filler, stays under a hard budget.

agentmem, bounded self-consolidating memory for LLM agents

Your Agent Does Not Need to Remember "ok sounds good"

Here is what passes for agent memory right now. Shove every message into a vector store and pray retrieval untangles the gold from the small talk later. That is not memory. That is a junk drawer with embeddings, and it grows forever whether or not a single thing inside it was worth keeping.

Real agents run on a budget. Context windows are not infinite and neither is your patience for retrieval that returns three "sounds good"s before the one fact that mattered.

agentmem has opinions about what to keep. Filler gets bounced at the door. Retrieval weighs relevance, recency, and importance together. And when the drawer fills up, it merges related memories into a summary before dropping the weakest, instead of blindly forgetting the oldest thing.

Memory With a Doorman

Zero dependencies, zero API keys, one method to swap in the real thing.

The gate: it scores every write and drops the filler on the way in, instead of letting retrieval clean up the mess later.

Dedup: say the same fact twice and it reinforces the existing memory instead of cloning it.

Decay-aware recall: it ranks on similarity, recency, and importance, and the act of remembering something makes it harder to forget, like an actual brain.

Consolidate, then evict: at capacity it fuses related memories into a summary before cutting the weakest, so you lose noise, not signal.

The Benchmark You Can't Argue With

The gate was easy. The honest benchmark was the hard part. It would have been trivial to cherry-pick a memory size where the numbers glow. Instead it streams 200 real facts past the agent with junk chatter mixed in, caps memory at a fixed number of slots, then quizzes at random. Turn the capacity dial and watch recall move. No hiding behind one flattering config.

I also left the default embedder deliberately dumb. A hashing embedder is less accurate than a real model, but it means the whole thing runs with zero keys and zero network calls, which matters more for something people are supposed to learn from than a slightly prettier recall score.

The Number

Stream 200 facts past a 32-slot memory and it consolidates down to exactly 32, holding 52% recall@5 on a random quiz. Raise the cap and recall climbs toward 100%. The tradeoff is right there in the open, not buried under one hand-picked setting.

7 tests green across Python 3.9 through 3.13, and it ships a py.typed marker so you get real type hints, not just crossed fingers.

Tools Used

Python
Hashing Embeddings
Decay-Aware Retrieval
pytest
Ruff
GitHub Actions CI
PyPI Packaging