{"slug": "does-my-ai-agent-memory-graph-change-when-it-reads-or-only-when-it-writes", "title": "Does my AI agent memory graph change when it reads, or only when it writes?", "summary": "A developer compared six agent memory systems — Mem0, Zep with Graphiti, Cognee, Letta, Supermemory and Mnemoverse — and found that in all six, graph edges are created on write, with only two walking further on read and one writing a reinforcement on read. The only place where a read demonstrably strengthens an edge is a research repository rather than a shipped product, and the author notes that Mnemoverse, which he works on, describes the co-activation mechanism publicly while keeping its engine closed.", "body_md": "You ask the agent about the payments retry table, and it comes back with the retry table plus the queue migration you argued about last month, because both mention the same service. Useful. Next week you ask about the queue and the retry table comes back with it again, and the week after that too. At some point you wonder whether that pairing is now something your memory layer knows, or whether you are watching the same shared entity match fire every time and nothing has been learned at all. The vendor page says knowledge graph, which is true, and answers nothing.\n\nThat is the buyer's question about graph memory once you strip the feature list off it. Every product in this category builds a graph, so the feature list separates nobody. What separates them is what a node is, when an edge is made, and whether anything in that graph changes because of what a search returned. Not because you wrote something new. Because you read. I put that question to six systems, Mem0, Zep with Graphiti, Cognee, Letta, Supermemory and Mnemoverse, and read each vendor's own pages and published code. I work on the last one, and on this exact question it holds the weakest row, so it goes first.\n\nOne line to carry: in all six the edges are made when you write, two of them walk further when you read, one of them writes a reinforcement when you read, and the only place where a read demonstrably strengthens an edge is a research repository, not a product.\n\nMnemoverse describes the mechanism this article goes looking for, in public, in code you can open. The memory server we publish prints it in a line the user sees: \"concept-to-concept links learned from concepts that occur together as memories are stored and used\". The comment above that line names the operation without a metaphor, `co_activate`, linking query concepts \"to result concepts on use\". Our library page says the same in prose: \"Its association layer links concepts through weighted edges strengthened by co-activation, with feedback tuning the weights over time\". On use. That is the loop, written down by us.\n\nAnd our engine is closed, so you can read those sentences and you cannot check one of them. Five of the six say nothing about this mechanism in public, and silence promises nothing. We have said more and shown less. If you are choosing on evidence rather than on ambition, that runs against us, and it should. Two smaller things, one each way. For us: the comment in that same file corrects an earlier description we published and names both defects in it, evidence that somebody is checking in public, not that the engine does anything. Against us: that wrong gloss, connections between memories that strengthen when they are retrieved together, was still live on 13 September on our own research page about building memory that scales, so a reader checking us finds both stories on our own site.\n\nZep: \"Zep's temporal Context Graph is the unit of agent memory. Nodes are entities, and edges are facts or relationships. The graph updates as new data arrives.\" Cognee extracts entities and relationships into a graph store, Mem0 ships a feature named Graph Memory, Supermemory sells a memory graph on its product page, Letta resolves links between memory files, and Mnemoverse ships a learned association graph. Six products, six graphs, and the word does different work in each sentence.\n\nEntities are what Zep and Cognee mean, and Cognee's retrieval guide is exact about the order: nodes are selected first and \"An edge is only carried over if both of the nodes it connects were selected\".\n\nMemories are what Mem0 means, and its graph is bipartite. Entities are stored once, and \"Over time this forms a graph: a web of entities, each connecting all the memories that mention it.\" Two memories are connected when they share an entity, with no learned weight on that connection, and the vendor rules out typed relations in the same breath: \"It does not assign typed, labeled relationships between entities\". Connected through a shared thing, not to each other.\n\nDocuments are what Letta means. The nodes are Markdown files the model itself wrote, the edges are file links a resolver parses, nothing weights them, and Letta's own published memory showcase says what a link is for: \"A double-bracket path is a discovery link, not an automatic include or semantic retrieval instruction.\"\n\nFacts on facts are what Supermemory means: \"When content is processed, new facts connect to existing ones through three relationship types.\" Its published package types those three as strings and carries no weight, strength or access count on the edge, though its generated SDK leaves the field an open enum.\n\nConcept labels are what we mean. Our nodes are neither entities nor memories, and our edges carry no relation types, no direction and no entity resolution, so the association layer never asserts that two records denote the same thing. Four kinds of object under one word.\n\nIn all six, the edges are created when something is written. Extraction, linking, and then the work is finished before you ask anything. Same in every row, ours included.\n\nTwo of the six do something extra at query time. Cognee ships a neighbourhood depth parameter that triggers real multi-hop expansion, which the shipped code declares None, so it is off unless you set it. Zep documents the same shape under a different name: \"You can enable breadth-first search to expand results around specified graph nodes.\" Its parameter table gives the seed no default and marks it not required.\n\nBoth walk the graph and find nodes. Walking is not changing, and for Cognee that is the vendor's own statement about its retrieval object: the memory fragment built for a query \"is never read directly from, or written back to, the full persisted graph\". For Zep the conclusion is narrower, because the served engine is closed: every documentation page I read uses the vocabulary of returning results, and none of them documents a write on the search path. That walk was not completed, so this is a statement about the pages read, not about the engine.\n\nMem0 is the real counter-example: a read does write. Its memory decay page says so twice, once as a principle, \"every time a memory is returned in a search it gets a small reinforcement\", and once as a numbered step in the search pipeline, \"Records a fire-and-forget reinforcement against each returned memory\".\n\nOn that entire page the words edge, graph, connection and link occur zero times, checked on 8 September 2026. The reinforcement lands on the memory's own access history. It is not a connection that got stronger because two things came back together. And the whole feature is \"opt-in per project\" and \"off by default\". A read writes, to the memory, not to the graph, and only if you asked for it.\n\nTo reach a surface documentation never touches, I searched each vendor's GitHub organisation for the vocabulary this mechanism has: hebbian, co-activation, spreading activation, co-retrieval. Four terms, five organisations, twenty code searches, all printed on the full write-up so you can run them. Re-run on 8 September 2026, all twenty return zero files.\n\nA zero from an instrument is a statement about the instrument first, so it needs controls, and it has two. The positive control is the same search with the term memory, which returns files in every one of the five organisations. The stronger control does not depend on the index: I downloaded the default branch of each vendor's main repositories, seven trees, and grepped them directly, hyphenated and unhyphenated spellings both. Zero for all four terms in every tree, and zero in the single-file documentation corpora of Cognee, Supermemory and Mem0. One trap: letta-ai/letta no longer holds the source, so a grep there gives a zero that looks like evidence and is not; the source is in letta-code.\n\nA search of what is published is not a search of what runs, and four of these six do not publish an engine you can read, ours among them. Two vendors also run chat communities unreadable from outside, and this sweep does not cover them.\n\nWhat makes this hard to see from outside is that the words are in use, for other mechanisms. Supermemory's preferences memory type \"Strengthens with repetition\", in a table whose neighbouring rows persist until updated and decay unless significant, and nothing in that vendor's documentation corpus says what does the strengthening. Letta's shipped system prompt tells the model that its references should strengthen with use, an instruction to a model, not a description of an engine.\n\nAn earlier cut of this argument, in my own drafts and video, said those values were computed once and frozen. That was wrong and catchable in one click: Zep regenerates observations when new evidence lands, and Supermemory's row sits in a table about things that move. What none of them says is where the change comes from. New evidence, a rating, a repetition, a score. Every one is a real mechanism. Not one is a connection that got stronger because two things came back together.\n\nThe one public implementation where that happens is the code attached to an ACL 2026 paper, ReinerBRO/HeLa-Mem. The last thing its retrieve method does before returning results is call a routine whose docstring reads \"Strengthen connections between simultaneously retrieved memories.\" It walks every pair of the retrieved identifiers and adds weight to the edge between them. That is the whole mechanism, and what none of the five products has published is those few statements between having the results and returning them. It is a research artifact with no releases, no tags and no licence, and the claim is exactly that narrow: one public implementation where retrieving changes the connection.\n\nEvery quotation above is a contiguous substring of a page its author published, re-checked on 2026-09-13, and each source is named on the [full write-up](https://mnemoverse.com/docs/library/agent-memory-knowledge-graphs-compared). The table is a reading of published pages and code, not a benchmark.\n\n| system | a node is | edges made | extra at read time | does a read write anything | \n|---|---|---|---|---|\n| Mnemoverse | concept labels | on write, and on use per our public source | cannot be checked, engine closed | our source says yes, to the edge; unverifiable from outside | \n| Mem0 | memories, linked through shared entities | on write | entity boost reorders an over-fetched pool | yes, a reinforcement on the memory's own access history; opt-in, off by default; nothing on an edge | \n| Zep with Graphiti | entities; edges are facts | on write | breadth-first search from named nodes, optional | none documented on the pages read; hosted engine closed | \n| Cognee | entities | on write | neighbourhood depth, off unless set | no; the query fragment is never written back; an optional last-accessed stamp moves no weight | \n| Letta | Markdown files the model wrote | on write | none | no | \n| Supermemory | facts on facts, three typed relations, enum left open | on write | none documented | no weight on the edge type; the engine is not in the published tree | \n\nThree questions separate these six, and none of them is on a comparison table. What are the nodes: entities, memories, documents or concepts. When does anything happen: only at write time, or at query time as well, and if so whether it is on by default, because for the two that have it, it is not. And when the graph changes, what moved it: new evidence, a rating, a repetition, a score, or a read. The last one decides whether a memory layer learns from being used or only from being written to, and the category is quietest about it.\n\nFrom published material, five of the six never name the last case. One names it in its own public source and cannot show you the engine that would settle it, and that one is us. Ask us that question harder than you ask anybody else.\n\nWhich of the six do you run, and have you ever seen a pairing come back that nothing in your writes explains?\n\n*Disclosure: I work on [Mnemoverse](https://mnemoverse.com), one of the systems above, so weigh the argument accordingly. The full comparison with every source page is on our library.*", "url": "https://wpnews.pro/news/does-my-ai-agent-memory-graph-change-when-it-reads-or-only-when-it-writes", "canonical_source": "https://dev.to/izgorodin/does-my-ai-agent-memory-graph-change-when-it-reads-or-only-when-it-writes-20mj", "published_at": "2026-09-19 06:15:00+00:00", "updated_at": "2026-09-19 06:54:23.954100+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "ai-products", "artificial-intelligence"], "entities": ["Mem0", "Zep", "Graphiti", "Cognee", "Letta", "Supermemory", "Mnemoverse"], "alternates": {"html": "https://wpnews.pro/news/does-my-ai-agent-memory-graph-change-when-it-reads-or-only-when-it-writes", "markdown": "https://wpnews.pro/news/does-my-ai-agent-memory-graph-change-when-it-reads-or-only-when-it-writes.md", "text": "https://wpnews.pro/news/does-my-ai-agent-memory-graph-change-when-it-reads-or-only-when-it-writes.txt", "jsonld": "https://wpnews.pro/news/does-my-ai-agent-memory-graph-change-when-it-reads-or-only-when-it-writes.jsonld"}}