My AI Remembered Everything Important. It Forgot What I Did Last Night.
I built an AI memory system inspired by one thing brains seem to do well: reinforce associations through use. Most AI memory is a notes file with search. It stores documents and retrieves them based on text similarity. I wanted something that behaved more like actual memory. I wanted paths that strengthen when you use them and fade when you do not. So mycelium stores memories as nodes with connections. This is not just a graph database. It is an active system. When you recall a few things together enough times, the link between them gets stronger. This is a Hebbian approach to storage. If two concepts appear in the same context repeatedly, the system assumes they belong together. Ignore a memory long enough and it decays. This decay is deliberate. Forgetting is a feature, not a bug. It keeps the system from becoming a static archive of everything you have ever typed. The core mechanism relies on SQLite with FTS5 for keyword matching. The connection graph lives on top of that. You might hear people talk about vectors for everything. Vectors exist as a secondary signal in mycelium. They are not the primary recall mechanism. The primary driver is this connection graph and the frequency of access. Recall is pattern completion. A query does not just match text against a document body. It fires the matching memories and spreads activation through their connections. A partial cue pulls back the whole cluster that tends to light up with it. The memories that win are the ones that are strongly connected and frequently accessed. I call those the hubs. Loading context at the start of a session deliberately returns the hubs. On average, the hubs are the load bearing knowledge. They are the concepts you have referenced most often. If you are building an agent that needs to know who you are, what you have been working on for weeks, or what your general preferences are, the hubs are the right answer. This is a feature. It is also the bug. I hit the issue during normal development cycles. I would open a fresh session and effectively ask, what was I just working on. I would paste in a code snippet or describe a problem I had solved minutes ago. I expected the system to surface that immediate context. Instead, I got my greatest hits. The system returned the architecture of the whole project. It returned the three facts I look up constantly. It returned the stuff from months ago that everything connects to. What I would NOT reliably get was last night's actual work. It was the thing I literally needed to resume. This was frustrating because the system was not broken. It was working exactly as designed. The ranking was correct. It was just answering the wrong question. The cause is not a bug in the usual sense. Every piece worked as intended. Ranking is centrality: connections times access. A memory I wrote an hour ago has close to zero of both. It has no connections yet because nothing has been recalled alongside it, and no access count because I have not pulled it up. So it sits at the bottom, structurally underneath every hub that has been reinforced for months. Nothing was wrong with retrieval. The new memory was present. It was simply losing honestly. Which is exactly the wrong answer to the question, what just happened. This is the same trade your own memory makes. You can describe the house you grew up in in detail. You cannot find your keys. Salience and recency are not the same axis. When salience is dominated by reinforcement, new memories are disadvantaged by construction. I had rebuilt that trade off in software without noticing. I had created a system that was excellent at telling me who I was, but terrible at telling me what I was doing. The obvious fix is to treat this as a weighting problem. Add a recency boost, push recent items up the list, tune it until the balance feels right. That was the wrong abstraction. Tuning centrality + λ(recency) does not remove the conflict. It just slides the failure boundary around. Turn λ up enough to surface last night's work and you push the genuinely important hubs down on everyday queries, which breaks the thing that made recall good. Turn it back down to protect the hubs and recent work sinks again. One knob cannot serve two intents. It can only choose which one to disappoint today. The fix that actually worked was to stop pretending one score answers both questions. I had to accept that centrality and recency are two different routes. I kept centrality for what is important. That route remains unchanged. It still powers the general context loading. It still identifies the hubs. I added a separate recency route for what just happened. This route is ranked newest first. It does not care about connections. It does not care about access counts. It cares only about when the memory was created or last touched. I wired that recency route into session startup. When a new session begins, the system loads the recent memories first. This gives the agent the immediate context it needs to resume work. Once that context is loaded, it can pull in the hubs if it needs broader understanding. Two questions. Two routes. The moment I stopped forcing one relevance number to do both jobs, both got better. The recent memories surfaced correctly. The important memories stayed in their rightful place. But calling it two routes undersells what I actually learned. This is not two ranking algorithms. It is two retrieval intents, and I had spent months pretending there was one. I started with the naive shape, memory(query) returns ranked results, when what I actually needed was closer to three different questions: continuity what happened recently? context what matters generally? recall what relates to this cue? Once you name the intent, a single universal relevance score starts to look suspicious. Those are not one question with different weights. They are different questions that happen to run over the same store. This is a lesson for anyone building retrieval systems. You are likely answering two different questions with one ranking function. You do not realize it because you are focused on relevance as a single metric. "What matters" and "what just happened" pull in opposite directions. If your system only has one relevance score, it is quietly bad at one of them. Which one depends on whether you tuned for salience or recency. If you tuned for salience, you will lose recency. If you tuned for recency, you will lose salience. The honest surprise for me was that the failure was not a ranking bug. It was a category error. I had one query where I needed two. The code is open at github.com/constant-itis/mycelium-memory. The separation is only a few lines. Noticing it needed to exist took months.
This is a summary aggregated from Dev.to. Read the complete article on the original site:
Read full article at Dev.to