Skip to main content

🧠 Mneme

A cue-indexed tag memory for conversational agents — no embeddings, no LLM in the memory path.

PyPI Python License: MIT

Most agent memories embed every turn and distill it with a write-time LLM, then search by vector similarity — expensive and opaque. Mneme instead does what human recall does: index by cues, reinstate by cue-match, and spread activation along both shared meaning and the thread of conversation — with a plain inverted index over deterministic tags. No vector database, no language model, no embeddings.

At zero memory cost, under an identical controlled comparison, Mneme matches a strong dense retriever on LoCoMo (F1 52.6 vs 52.9) and beats it on high-distractor LongMemEval (acc 64.2 vs 62.2) — while outrunning both mem0 and BM25 on both benchmarks. Same answerer, judge, prompt, and budget; only the memory differs.


✨ Why Mneme

  • Zero cost. No write-time LLM calls, no embeddings, sub-millisecond recall, storage is plain JSON files.
  • Competitive quality. Matches or beats embedding + LLM memory on standard benchmarks (see below).
  • Interpretable. Retrieval is explicit cue overlap ranked by IDF — no opaque similarity threshold to tune.
  • Human-like forgetting. What has no distinctive cue, or whose cues never recur, is simply never surfaced — forgetting as retrieval failure, for free.
  • Local & sovereign. Your memory is a folder of files you can read, edit, or delete. English by default; Chinese optional.

📊 Benchmarks (controlled: same answerer/judge/prompt/budget, only the memory differs)

LoCoMo — low-distractor dialogue (F1 / accuracy):

method cost F1 acc
mem0 (LLM extract + vectors) LLM+emb 40.4 57.3
BM25 (raw turns) zero 45.8 57.0
Mneme (hybrid edges) zero 52.6 67.6
dense retriever (bge-large) embeddings 52.9 67.7

LongMemEval — high-distractor, ~50 sessions per question (accuracy):

method cost acc
BM25 (raw turns) zero 61.2
dense retriever (bge-large) embeddings 62.2
Mneme (associative) zero 64.2

Zero-cost Mneme reaches dense retrieval on LoCoMo and overtakes it where distractors dominate — the regime that matters for real long-term memory — and it is reader-agnostic (near-identical with two different answerer LLMs) and interpretable. The best edge mix is regime-dependent: discourse edges help clean dialogue, associative edges win high-distractor histories.

🚀 Install

pip install mnemekit
python -m spacy download en_core_web_sm     # English model (required)

pip install "mnemekit[zh]"                   # optional: Chinese (jieba)

⚡ Quick start

from mneme import Memory

m = Memory(root="~/.mneme")

m.remember("My dog Lucky is a golden retriever", "Cute! How old is Lucky?",
           session_id="chat-42", round_id=1)

m.recall("what breed is my dog")     # -> [Turn(...), ...]

Turns are stored one file per round at {root}/{session_id}/{YYYY-MM-DD}/{round_id}.json, so any session is trivial to inspect, export, or delete.

🔍 How it works

INGEST (no LLM, no embedding)
  turn ──▶ tag extraction (spaCy NER + lemmas / jieba) ──▶ inverted index  (tag → turns)
                                                           + event tag inheritance

RECALL (per query) — spread over an ephemeral heterogeneous graph, then discard it
  query ─▶ ① lexical: IDF cue reinstatement ─seeds─┬─▶ ② associative edge (shared tag, 1 hop)
                                                   └─▶ ③ discourse edge (adjacent turn in event)
                                                                        │
                                                          recalled context ─▶ your reader
  1. Cue index. Each turn is tagged deterministically; tags form an inverted index (a sparse cue index, à la hippocampal indexing). Keyword-free follow-ups inherit their event's tags, so they stay recallable.
  2. Reinstatement, then two kinds of edge. A query reinstates directly-cued turns lexically, then spreads activation over an ephemeral graph with two edge types: associative edges (shared discriminative cue → one hop) reach the associative tail a direct cue can't; discourse edges (adjacent turns in the same event) pull in the local conversational context around a hit. Neither is materialized — both are read straight off the index and event structure, used for the one query, and discarded.

🀄 Chinese & custom dictionaries

m = Memory(root="~/.mneme", userdict="my_terms.txt")   # jieba user dictionary
m.remember("我养了只金毛狗,叫 Lucky", "可爱!", session_id="u1", round_id=1)

Chinese is segmented by jieba; a custom dictionary keeps vertical-domain terms intact.

📄 Paper & reproduction

The write-up (method, cognitive grounding, controlled comparison, ablations) is in paper/; the evaluation harness (LoCoMo / LongMemEval / mem0) is in eval/. The frozen reproduction version is on the paper-repro branch.

📌 Citation

@misc{mneme2026,
  title  = {Do Conversational Agents Need Vectors? A Zero-LLM, Zero-Embedding Tag Memory},
  author = {Hao, Shaochun},
  year   = {2026},
  note   = {https://github.com/FTP2026/Mneme}
}

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mnemekit-0.2.0.tar.gz (12.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mnemekit-0.2.0-py3-none-any.whl (10.6 kB view details)

Uploaded Python 3

File details

Details for the file mnemekit-0.2.0.tar.gz.

File metadata

  • Download URL: mnemekit-0.2.0.tar.gz
  • Upload date:
  • Size: 12.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for mnemekit-0.2.0.tar.gz
Algorithm Hash digest
SHA256 42ece36656970b5d31ac66057558f9e4a555559bda9f0a6fe27c266a40080eb6
MD5 3a57c66c8162497214c62bfe1054b43e
BLAKE2b-256 a82e9a46e8ae403f4f7cbdc1a6fdcfd8b10666504c203e1eaaeb6d7156944125

See more details on using hashes here.

File details

Details for the file mnemekit-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: mnemekit-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 10.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for mnemekit-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3649c6561d8f39b9241bdc705f30437ee47737a2b9857f24cda6fa8257c991ff
MD5 37e02424acc0104f3cb1d35a6bac8231
BLAKE2b-256 7a5dd54274d6157a914d8ebad09941399c81889f47ca222af226d8c3fc3c761f

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page