Mandol: An In-Memory Agent Memory System
Important
The main branch is under active refactoring and may differ from the released artifact. For exact paper reproduction, use the paper-repro branch. The current public PyPI package mandol==0.1.0a1 and the GitHub release are built from, and aligned with, paper-repro.
Show/Hide
Mandol is a native in-memory hierarchical memory system for LLM agents such as long-term conversational agents. Its core components are:
- Hierarchical Memory Model β Organizes memory into a basic layer and a high-level abstract layer, both uniformly represented as a structured semantic graph with traceable relationships between all memory elements.
- In-Memory Semantic Data Structures β Combines SemanticMap and SemanticGraph to natively fuse key-value, vector, and graph stores into a unified hybrid retrieval interface, eliminating cross-database I/O overhead.
- Smart Quantitative Retrieval β A query-adaptive routing mechanism with two-stage denoising, conflict resolution, and token-constrained context generation β all operating without invoking LLMs during retrieval.
On the LoCoMo and LongMemEval long-term conversation benchmarks, Mandol achieves state-of-the-art accuracy of 92.21% and 88.40%, respectively. Compared to representative agent memory systems, Mandol delivers a 5.4Γ retrieval speedup and a 4.8Γ insertion speedup under 10 QPS concurrent load, while sustaining low latency on consumer-grade hardware. These results validate the system's effectiveness, efficiency, and stability in complex long-conversation scenarios.
System-level comparison of agent memory systems:
| System | Memory Organization | Storage | Retrieval | Search Latency |
|---|---|---|---|---|
| Mem0 | Text vectors + metadata | VectorDB + metadata store | Vector semantic retrieval + metadata filtering | Medium |
| Zep | Text vectors + temporal knowledge graph | GraphDB + vector/full-text indexes | Multi-step graph traversal + reranking | High |
| MemOS | Text vectors + graph/tree summaries | VectorDB + GraphDB | Vector retrieval + graph node matching | High |
| EverMemOS | Text vectors + memory summaries | Multi-DB stack | Multi-turn retrieval + query rewriting | Very high |
| Mandol | Basic + high-level memories represented as a structured semantic graph | SemanticMap/Graph; DuckDB fallback | Hybrid recall + smart quantitative retrieval | Low |
LoCoMo accuracy (%) comparison among different memory systems:
| Backbone | System | Avg. Tok. | Single | Multi | Temp. | Open | Overall |
|---|---|---|---|---|---|---|---|
| GPT-4o-mini | Mem0 | 1.0k | 66.71 | 58.16 | 55.45 | 40.62 | 61.00 |
| MemU | 4.0k | 72.77 | 62.41 | 33.96 | 46.88 | 61.15 | |
| MemOS | 2.5k | 81.45 | 69.15 | 72.27 | 60.42 | 75.87 | |
| Zep | 1.4k | 88.11 | 71.99 | 74.45 | 66.67 | 81.06 | |
| EverMemOSβ | 2.5k | 91.68 | 82.74 | 79.34 | 70.14 | 86.13 | |
| Mandol (Ours) | 2.0k | 93.82 | 85.11 | 89.10 | 65.63 | 89.48 | |
| GPT-4.1-mini | Mem0 | 1.0k | 68.97 | 61.70 | 58.26 | 50.00 | 64.20 |
| MemU | 4.0k | 74.91 | 72.34 | 43.61 | 54.17 | 66.67 | |
| MemOS | 2.5k | 85.37 | 79.43 | 75.08 | 64.58 | 80.76 | |
| Zep | 1.4k | 90.84 | 81.91 | 77.26 | 75.00 | 85.22 | |
| EverMemOSβ | 2.3k | 95.32 | 89.01 | 90.13 | 77.43 | 91.97 | |
| Mandol (Ours) | 1.9k | 95.36 | 92.20 | 87.85 | 79.17 | 92.21 |
β Reproduced using the official implementation from EverMemOS.
Mandol achieves the highest Overall accuracy on LoCoMo under both backbone settings.
LongMemEval accuracy (%) comparison among different memory systems:
| Backbone | System | Avg. Tok. | SS-Pref | SS-Asst | Temporal | Multi-S | Know. Upd. | SS-User | Overall |
|---|---|---|---|---|---|---|---|---|---|
| GPT-4o-mini | MemU | 0.5k | 76.70 | 19.60 | 17.30 | 42.10 | 41.00 | 67.10 | 38.40 |
| Mem0 | 1.1k | 90.00 | 26.78 | 72.18 | 63.15 | 66.67 | 82.86 | 66.40 | |
| Zep | 1.6k | 53.30 | 75.00 | 54.10 | 47.40 | 74.40 | 92.90 | 63.80 | |
| MemOS | 1.4k | 96.67 | 67.86 | 77.44 | 70.67 | 74.26 | 95.71 | 77.80 | |
| Mandol (Ours) | 2.1k | 96.67 | 98.21 | 78.95 | 74.44 | 88.46 | 97.14 | 85.00 | |
| GPT-4.1-mini | EverMemOS | 2.8k | 93.33 | 85.71 | 77.44 | 73.68 | 89.74 | 97.14 | 83.00 |
| Mandol (Ours) | 2.3k | 96.67 | 98.21 | 87.22 | 77.44 | 89.74 | 98.57 | 88.40 |
Mandol achieves the highest Overall accuracy on LongMemEval under both backbone settings.
Evaluation methodology. Retrieval quality is measured via QA accuracy on the two benchmarks, defined as the percentage of questions whose generated answers are judged correct or semantically consistent with the ground-truth answers. Following the evaluation protocol of prior memory-system studies, GPT-4o-mini and GPT-4.1-mini serve as the answer-generation backbones, and we adopt the released LLM-based answer correctness evaluation script from EverMemOS.
Notably, rather than using large-parameter models such as Qwen3-Embedding-4B and Qwen3-Reranker-4B, we employ lightweight alternatives β Qwen3-Embedding-0.6B for embedding and bge-reranker-v2-m3 for reranking.
Memory is organized into a basic memory layer and a high-level abstract memory layer, both uniformly represented as a structured semantic graph. The basic layer represents raw memory through memory units, spaces, and explicit/implicit relationships. The abstract layer automatically derives episodic memory (event chains), semantic memory (entity graphs), and emotional memory (user preferences) from basic memories, with traceable links that ensure evidence grounding while supporting abstract reasoning.
SemanticMap and SemanticGraph form a unified in-memory data structure that natively fuses key-value storage, vector indexes, and graph representations, eliminating multi-database fragmentation. Hybrid retrieval operators combine vector matching and graph traversal through a single API surface, removing the I/O latency inherent in heterogeneous storage architectures. The data structures also connect to an underlying persistent database for cold storage and long-term retention.
The RAG-style recall-then-rank paradigm is replaced with a proactive pipeline of Query-Adaptive Routing, two-stage denoising and conflict resolution, and token-constrained context generation. Query-Adaptive Routing dynamically selects and queries the most relevant memory sources based on query intent. Two-stage quantitative denoising and conflict resolution then remove noise and contradictory information across sources. Finally, a compact high-quality context is assembled under token constraints by jointly optimizing relevance and diversity β all without LLM involvement in retrieval.
Core APIs exposed by Mandol:
| Scope | API |
|---|---|
| Memory unit operation | add/delete/update(space, [unit]) |
| Explicit relationship | add/delete/update_relationship(unit_src, unit_target, [type]) |
| Unit retrieval | search_unit(query, memory_space, type) |
| Graph traversal | traverse_explicit_nodes(unit, [type]) |
| Semantic traversal | traverse_implicit_nodes(unit, [top_k]) |
| Quantitative retrieval | smart_search_with_quantification(query, [params]) |
| Persistence | save_graph([dir, build_index]) |
| Memory construction | build_memory_from_raw(sample_id,extraction_style, [session_date]) |
When new content is inserted, the system automatically chunks, embeds, and segments the raw data. It extracts events and causal relationships to form episodic memory, entities and their relations to form semantic memory, and user preferences and long-term states to form emotional memory. These high-level memories coexist with the underlying base memories as the system's complete memory state.
Queries are served through the smart quantitative search API. For each query, Query-Adaptive Routing first allocates a token budget across memory spaces (basic, episodic, semantic, emotional). The system then performs algorithmic fusion, resolves conflicts, and selects high-quality memory entries within the assigned token budget.
By default, Mandol keeps memory content in the in-memory SemanticMap/Graph to support low-latency retrieval. Mandol can also persist selected memory units and graphs for checkpointing, recovery, and later reloading into the in-memory runtime. Persistence can be triggered automatically by the runtime for database-backed checkpointing, while the save_graph API explicitly exports the current in-memory graph to local storage for inspection, backup, or later restoration.
For detailed reproduction steps, refer to the benchmarks README.
The currently released PyPI package corresponds to the paper-repro branch:
pip install mandol==0.1.0a1For the full paper reproduction environment, use the paper-repro source checkout and install the artifact stack with:
uv sync --extra dev --extra cuda --group spacy-modelIf CUDA or flash-attention is not available on your platform, omit --extra cuda:
uv sync --extra dev --group spacy-modelThe following optional dependency groups are intended for the main branch development version and may not match the released paper-repro package:
pip install mandol[faiss] # FAISS vector index acceleration
pip install mandol[sentence-transformers] # Local Embedding/Reranker models
pip install mandol[openai] # OpenAI API support
pip install mandol[milvus] # Milvus vector database
pip install mandol[neo4j] # Neo4j graph database
pip install mandol[all] # Install all optional dependenciesFor exact paper reproduction, please use the
paper-reprobranch. For complete installation guides, configuration details, and advanced usage, see the online documentation.
Copy the environment variable template and fill in your API key:
cp .env.example .envOr configure fully via a YAML configuration file:
llm:
model: "gpt-4o-mini"
base_url: "https://api.openai.com/v1"
api_key: "sk-..."
embedder:
model: "Qwen/Qwen3-Embedding-0.6B"
device: "cpu"
use_remote: false
reranker:
model: "BAAI/bge-reranker-v2-m3"
# model: "Qwen/Qwen3-Reranker-4B"
device: "cpu"
use_remote: false
system:
chunk_max_tokens: 512
bfs_expansion_hops: 1
max_context_units: 20In remote API mode, no local model download (~8 GB) is needed β just set use_remote to true and configure the API endpoint to get started quickly.
from mandol import MemorySystem, MemoryUnit, Uid
system = MemorySystem.from_yaml_config("config.yaml")
# 1. Write memories
system.add(MemoryUnit(
uid=Uid("msg_001"),
raw_data={"text_content": "Zhang San went to Beijing on a business trip today"},
metadata={"timestamp": "2024-01-15T10:00:00"},
))
# 2. Build high-level memory structures
system.build_high_level(mode="auto")
# 3. Hybrid retrieval
hits = system.holistic_retrieve("Where did Zhang San go?", top_k=5)
for hit in hits:
print(f"[{hit.final_score:.3f}] {hit.unit.raw_data['text_content']}")
system.save("./memory_snapshot") # Persist
system2 = MemorySystem.load("./memory_snapshot") # RestoreTip: The system automatically detects session boundaries during
add()and triggers high-level memory construction. After inserting a small batch of data, it is recommended to manually callbuild_high_level()to ensure high-level memories are populated. For further configuration options and advanced usage, see the online documentation.
Complete API reference, architecture design, and best practice guides are built with Sphinx and organized around three entry points β basic users, advanced users, and developers:
π Online documentation: https://agentcombo.github.io/Mandol/docs (coming soon)
Build the documentation locally:
cd docs && make htmlWe welcome community contributions! Please read CONTRIBUTING.md before submitting a PR to learn about development environment setup, code standards (Ruff, 100-char line length), testing requirements, and the PR process.
- Issues: GitHub Issues β Report bugs or request new features
- Discussions: GitHub Discussions β Usage questions, best practice discussions
- Community: Scan the QR code below to join our WeChat user group
If this work is helpful to your research, please cite our paper:
@misc{zhang2026mandol,
title={Mandol: An Agglomerative Agent Memory System for Long-Term Conversations},
author={Yuhan Zhang and Zhiyuan Guo and Ziheng Zeng and Wei Wang and Wentao Wu and Lijie Xu},
year={2026},
eprint={2606.29778},
archivePrefix={arXiv},
primaryClass={cs.DB},
url={https://arxiv.org/abs/2606.29778},
}Apache License 2.0 β See LICENSE

