# Nemori Memory System **๐Ÿ“„ [Paper](https://arxiv.org/abs/2508.03341)** > Important: This release is a complete rewrite aligned with the paper and is not compatible with the previous MVP. The legacy MVP is available here: [legacy-mvp branch](https://github.com/nemori-ai/nemori/tree/legacy-mvp) Nemori logo Nemori is a self-organising long-term memory substrate for agentic LLM workflows. It ingests multi-turn conversations, segments them into topic-consistent episodes, distils durable semantic knowledge, and exposes a unified search surface for downstream reasoning. The implementation combines insights from Event Segmentation Theory and Predictive Processing with production-ready concurrency, caching, and pluggable storage.
- **๐Ÿ Language:** Python 3.10+ - **๐Ÿ“œ License:** MIT - **๐Ÿ“ฆ Key dependencies:** asyncpg, Qdrant, OpenAI SDK, Pillow --- ## 1. โ“ Why Nemori Large language models rapidly forget long-horizon context. Nemori counters this with two coupled control loops: 1. **๐Ÿ”„ Two-Step Alignment** - *๐ŸŽฏ Boundary Alignment* โ€“ LLM-powered boundary detection with transitional masking heuristics keeps episodes semantically coherent. - *๐Ÿ“ Representation Alignment* โ€“ the episode generator converts each segment into rich narratives with precise temporal anchors and provenance. 2. **๐Ÿ”ฎ Predictโ€“Calibrate Learning** - *๐Ÿ’ญ Predict* โ€“ hypothesise new episodes from existing semantic knowledge to surface gaps early. - *๐ŸŽฏ Calibrate* โ€“ extract high-value facts from discrepancies and fold them into the semantic knowledge base. The result is a compact, queryable memory fabric that stays faithful to the source dialogue while remaining efficient to traverse. --- ## 2. ๐Ÿš€ Quick Start ### 2.1 ๐Ÿณ Infrastructure (Docker Compose) Nemori uses PostgreSQL for metadata and text search, and Qdrant for vector storage. Start both with a single command: ```bash docker compose up -d ``` This launches PostgreSQL 16 (port 5432) and Qdrant (ports 6333/6334) with persistent volumes. ### 2.2 ๐Ÿ“ฅ Install Nemori Using [uv](https://github.com/astral-sh/uv) is the easiest way to manage the environment: ```bash brew install uv # or curl -LsSf https://astral.sh/uv/install.sh | sh git clone https://github.com/nemori-ai/nemori.git cd nemori uv venv source .venv/bin/activate # Windows: .venv\Scripts\activate uv sync ``` Alternatively, install in editable mode: ```bash pip install -e . ``` ### 2.3 ๐Ÿ”‘ Credentials Create a `.env` file in the repo root: ```bash # OpenRouter (recommended โ€” single key for both LLM and embeddings) LLM_API_KEY=sk-or-... LLM_BASE_URL=https://openrouter.ai/api/v1 EMBEDDING_API_KEY=sk-or-... EMBEDDING_BASE_URL=https://openrouter.ai/api/v1 # Or use direct OpenAI # LLM_API_KEY=sk-... # EMBEDDING_API_KEY=sk-... ``` Nemori only reads these variables; it never writes secrets to disk. ๐Ÿ”’ ### 2.4 ๐Ÿ’ก Minimal usage ```python import asyncio from nemori import NemoriMemory, MemoryConfig async def main(): # DSN, API keys, and base URLs are resolved from environment variables. # Only model names need to be specified explicitly. config = MemoryConfig( llm_model="openai/gpt-4.1-mini", embedding_model="google/gemini-embedding-001", ) async with NemoriMemory(config) as memory: await memory.add_messages("user123", [ {"role": "user", "content": "I started training for a marathon in Seattle."}, {"role": "assistant", "content": "Great! When is the race?"}, {"role": "user", "content": "It is in October."}, ]) await memory.flush("user123") results = await memory.search("user123", "marathon training") print(results) asyncio.run(main()) ``` --- ## 3. ๐Ÿ—๏ธ System Architecture ![Nemori system architecture](assets/nemori_system.png) Nemori uses a **dual-backend** storage architecture: - **PostgreSQL** โ€“ metadata, text search (tsvector/GIN indexes), and message buffering. - **Qdrant** โ€“ all vector storage and similarity search with automatic embedding dimension adaptation. Both backends are fully async via `asyncpg` and the Qdrant gRPC client. --- ## 4. ๐Ÿ“‚ Repository Layout ``` nemori/ โ”œโ”€โ”€ api/ # Async facade (NemoriMemory) โ”œโ”€โ”€ core/ # MemorySystem orchestrator โ”œโ”€โ”€ db/ # PostgreSQL stores + Qdrant vector store โ”œโ”€โ”€ domain/ # Models, interfaces, exceptions โ”œโ”€โ”€ llm/ # LLM client, orchestrator, generators โ”œโ”€โ”€ search/ # Unified search (vector + text + hybrid) โ”œโ”€โ”€ services/ # Embedding client, event bus โ””โ”€โ”€ utils/ # Image compression utilities evaluation/ โ”œโ”€โ”€ locomo/ # LoCoMo benchmark scripts โ”œโ”€โ”€ longmemeval/ # Long-context evaluation suite โ””โ”€โ”€ readme.md # Dataset instructions docker/ โ””โ”€โ”€ init-extensions.sql # PostgreSQL extension setup ``` --- ## 5. ๐Ÿ“Š Running Evaluations ### 5.1 ๐Ÿ”ง LoCoMo pipeline ```bash PYTHONPATH=. python evaluation/locomo/add.py PYTHONPATH=. python evaluation/locomo/search.py PYTHONPATH=. python evaluation/locomo/evals.py PYTHONPATH=. python evaluation/locomo/generate_scores.py ``` ### 5.2 ๐Ÿ† Latest LoCoMo scores (V5) ![LoCoMo LLM score comparison](assets/locomo_scores.png) | Category | BLEU | F1 | LLM | Count | |----------|------|----|-----|-------| | Multi-Hop | 0.3432 | 0.4338 | 0.7943 | 282 | | Temporal | 0.5109 | 0.5913 | 0.7882 | 321 | | Open-Domain | 0.2224 | 0.2736 | 0.5938 | 96 | | Single-Hop | 0.5046 | 0.5664 | 0.8859 | 841 | โœจ Overall LLM alignment: **0.8305** ### 5.3 ๐Ÿ“š LongMemEval See `evaluation/longmemeval/readme.md` for running the 100k-token context benchmark. --- ## 6. ๐Ÿณ Docker Deployment Start the infrastructure services: ```bash docker compose up -d ``` This brings up: - **PostgreSQL 16** on port `5432` (user: `nemori`, password: `nemori`, db: `nemori`) - **Qdrant** on ports `6333` (HTTP) and `6334` (gRPC) Data is persisted in Docker volumes (`nemori_pg_data`, `nemori_qdrant_data`). To stop: ```bash docker compose down # keep data docker compose down -v # remove data volumes ``` --- ## 7. ๐Ÿข Multi-Tenant Support Nemori supports workspace isolation via `agent_id`. Each agent gets its own namespace for episodes, semantic memories, and vector collections, enabling safe multi-tenant deployments. --- ## 8. ๐Ÿ–ผ๏ธ Multimodal Support Nemori supports image inputs via `add_multimodal_message()`. Images are automatically compressed and stored alongside text content, enabling memory formation from visual conversations. --- ## 9. ๐Ÿ› ๏ธ Developing with Nemori - ๐Ÿงช Tests: `pytest tests/` - ๐Ÿ” Linting: `ruff check nemori` - ๐Ÿ“ Type checking: `mypy nemori` - ๐Ÿ“Š Benchmark helpers live in `scripts/` Use the `NemoriMemory` facade for experiments and inject custom storage or LLM clients when integrating into larger systems. --- ## 10. ๐Ÿ”ง Troubleshooting | ๐Ÿšจ Symptom | ๐Ÿ” Likely cause | ๐Ÿ’ก Mitigation | |---------|--------------|------------| | `asyncpg.ConnectionError` on startup | PostgreSQL not running | Run `docker compose up -d` and wait for healthcheck | | Qdrant connection refused | Qdrant container not ready | Check `docker compose ps`; wait for healthy status | | Embedding dimension mismatch | Model changed without recreating collection | Delete the Qdrant collection and re-ingest | --- ## 11. ๐Ÿค Contributing 1. ๐Ÿด Fork the repository and create a feature branch. 2. โœ… Add or update tests (`pytest`, `ruff`, `mypy`). 3. ๐Ÿš€ Open a PR explaining architectural impact (boundary logic, storage schema, etc.). Nemori is evolving toward multi-agent deployments. Feedback and collaboration are welcome! ๐Ÿ’ฌ --- ## 12. ๐Ÿ“ฐ News - **๐ŸŽ‰ 2026-03-24** โ€” Complete async refactoring: PostgreSQL + Qdrant dual backend, OpenRouter LLM support, multimodal messages, Docker Compose deployment. - **๐ŸŽ‰ 2025-10-28** โ€” Upgraded the segmenter component and added token counting functionality for evaluation. - **๐ŸŽ‰ 2025-09-26** โ€” Released Nemori as fully open source, covering episodic and semantic memory implementations end-to-end. - **๐Ÿ 2025-07-10** โ€” Delivered the MVP of episodic memory generation.