Replies: 5 comments 1 reply
|
From the current OSS code, this is not a simple "embedding similarity above threshold = merge" flow. In the newer additive path, Mem0 retrieves nearby existing memories and passes them into the extraction prompt as So for your examples: "I prefer Python" and "I mostly use TypeScript now" should normally both remain available unless you explicitly update/delete one, but the newer memory can be linked to the older one as the same preference topic. At 10k+ memories, retrieval quality depends more on your vector store filters/scoping and over-fetch/rerank strategy than on a built-in global dedupe pass. |
|
Answers based on the v3 ADD-only path (+ maintainer notes on #4896 / #4904):
Happy to point at the prompt / |
|
Worth noting how we approached this in Smriti: dedup/contradiction resolution is handled via explicit supersession — each event tracks what it replaces (superseded_by), so the query layer can filter to only the current belief instead of merging or scoring similarity between old and new. Avoids the 'which version wins' ambiguity that pure similarity-threshold dedup runs into at scale. Happy to compare notes if useful: smriti-kaal.vercel.app |
|
The answers above describe the design accurately — both memories are kept, I built an external read-only auditor for exactly this and ran it against a synthetic store with known ground truth — 24 facts, 7 deliberately planted pairs (3 duplicates, 2 contradictions, 2 supersessions), one topically-related-but-distinct trap pair, and 8 unrelated facts as noise. Embedding pass for nearest neighbours, then an LLM judge on only those candidates. What held up across four runs on two completely different embedding stacks:
The practical read for anyone auditing their own store: finding the pairs is the reliable part; deciding what kind of conflict each one is still needs a human. Which is why the tool reports and stops rather than merging anything. One thing worth flagging separately, because it bit me: the first measurement I published didn't reproduce months later, and I couldn't determine why — the reports hadn't recorded which models produced them, and by the time I re-ran, the embedding provider I'd used had been shut down entirely. If you're benchmarking memory behaviour, record the whole stack in the output. Write-up: https://github.com/simon9679/mem-audit/blob/main/docs/accuracy-postmortem.md Tool is https://github.com/simon9679/mem-audit — read-only, talks to Mem0 through the standard SDK, works with whatever backend you already run. Embeddings can run fully local through Ollama, so an audit needs no cloud keys at all. Caveats on the numbers: one 24-fact set, short English personal-memory-style facts, one measurement per configuration. Treat it as "the approach works as designed," not as a generalisation to a 10k store — which, to be clear, I have not measured. |

Uh oh!
There was an error while loading. Please reload this page.
Been thinking about memory deduplication as a real challenge for long-running agents. A few questions after reading through the codebase:
When the same fact gets stored multiple times across sessions (slightly different wording, same semantic meaning), how does Mem0 detect and merge these? Is it embedding similarity above a threshold, or something more structured?
What happens when two stored memories directly contradict each other? For example the user says "I prefer Python" in session 1 and "I mostly use TypeScript now" in session 3. Does the newer one overwrite, both get kept, or is there a merge strategy?
At scale (say 10k+ memories per user), does retrieval quality degrade noticeably or does the deduplication layer keep things manageable?
Interested in the design decisions here, not just the API surface. Happy to dig into specifics if useful.
All reactions