An open-source evaluation platform for benchmarking memory and context management systems. Compare providers like Synap, Mem0, Zep, and Supermemory across standardized benchmarks with a 5-phase pipeline and interactive dashboard.
Dataset ──> Ingest ──> Search ──> Answer ──> Evaluate ──> Report
| | | | |
Sessions Per-query LLM call LLM judge Accuracy,
stored in retrieval generates scores vs latency,
provider from hypothesis ground retrieval
memory provider truth metrics
Pipeline Phases:
- Ingest — Load benchmark sessions into a memory provider
- Search — Retrieve relevant context for each question
- Answer — Generate answers using an LLM with retrieved context
- Evaluate — Score answers with an LLM judge + compute retrieval metrics
- Report — Aggregate accuracy, latency, and retrieval quality
| Provider | Type | SDK |
|---|---|---|
| Synap | Full context management | pip install maximem-synap |
| Mem0 | Memory extraction | pip install mem0ai |
| Zep | Temporal knowledge graph | pip install zep-cloud |
| Supermemory | Auto-chunking + search | pip install supermemory |
| Custom | Implement Provider ABC |
See Adapter Spec |
| Benchmark | Questions | Sessions | Focus |
|---|---|---|---|
| LongMemEval | 500 | 940 | Long-term memory across sessions |
| LoCoMo | 1,540 | 5,290 | Multi-conversation, multi-modal, very long context |
| Custom | Implement Benchmark ABC |
See Adding Benchmarks |
Run with gpt-5-mini answer + gpt-5-mini judge, binary judging methodology (CORRECT / WRONG, 5-seed mean), excluding adversarial questions per industry convention (mem0, Zep, original LoCoMo paper). Both benchmarks are scored at full scale on the official public distributions, with no custom subsets and no relabeling.
| Benchmark | Scope | Provider | Accuracy |
|---|---|---|---|
| LoCoMo | Full set, 1,540 Cat 1-4 questions (adversarial Cat 5 excluded) | Synap | 93.2% |
| LongMemEval | Full set, 500 questions across 6 categories | Synap | 92.0% |
Full methodology, category-level breakdowns, and the cross-vendor comparison live in the results repo: maximem-ai/eval_benchmark_runs_output.
git clone https://github.com/maximem-ai/memory_and_context_eval_harness.git
cd memory_and_context_eval_harness
pip install -e .cp .env.example .env
# Edit .env with your API keyspython scripts/download_datasets.py --variant s--variant s is the 500-question LongMemEval set used for the published results. See docs/QUICKSTART.md for the other options.
python -m runner.serverThis starts the API server and dashboard at http://localhost:8766.
For frontend development with hot reloading, run it separately:
cd frontend && npm install && npm run dev| Mode | Description | Use Case |
|---|---|---|
| Global | All sessions in one shared container | Fast, cross-session reasoning |
| Isolated | Separate container per question | Clean evaluation, no cross-contamination |
Every evaluation run computes:
- Hit@K — Is relevant context in top-K results?
- Precision@K — Fraction of relevant results in top-K
- Recall@K — Fraction of relevant results found
- F1@K — Harmonic mean of precision and recall
- MRR — Mean Reciprocal Rank
- NDCG — Normalized Discounted Cumulative Gain
Implement the Provider abstract class from runner/types.py:
from runner.types import Provider, ProviderConfig, IngestOptions, IngestResult, SearchOptions
class MyProvider(Provider):
name = "my-provider"
async def initialize(self, config: ProviderConfig) -> None: ...
async def ingest(self, sessions, options: IngestOptions) -> IngestResult: ...
async def await_indexing(self, result, container_tag, on_progress=None) -> None: ...
async def search(self, query: str, options: SearchOptions) -> list: ...
async def clear(self, container_tag: str) -> None: ...Register it in adapters/__init__.py:
PROVIDER_REGISTRY["my-provider"] = "adapters.my_provider.MyProvider"Then check your class against the contract before running anything:
pytest tests/unit/test_provider_contract.py -v→ Build Your Own Adapter walks through the whole thing with a complete worked example, including the mistakes that quietly cost you accuracy. Provider Specification is the interface reference.
Implement the Benchmark abstract class from runner/types.py:
from runner.types import Benchmark, UnifiedQuestion, UnifiedSession
class MyBenchmark(Benchmark):
name = "my-benchmark"
async def load(self, config=None) -> None: ...
def get_questions(self, filter=None) -> list[UnifiedQuestion]: ...
def get_haystack_sessions(self, question_id: str) -> list[UnifiedSession]: ...
def get_ground_truth(self, question_id: str) -> str: ...
def get_question_types(self) -> dict: ...Register it in datasets/base.py:
BENCHMARK_REGISTRY["my-benchmark"] = "datasets.my_benchmark.MyBenchmark"Provider credentials are stored in .env. Provider-specific settings are in configs/*.yaml. Orchestrator configs define multi-dataset pipelines in configs/orchestrator_*.yaml.
runner/ # Core pipeline orchestrator + phases
phases/ # Ingest, search, answer, evaluate, report
adapters/ # Provider implementations
datasets/ # Benchmark loaders + data files
scorers/ # LLM judge + retrieval metrics
prompts/ # System prompts for answering + judging
configs/ # Provider + orchestrator YAML configs
frontend/ # Next.js dashboard
- Quickstart — Install, configure, download datasets, run
- Build Your Own Adapter — Benchmark your own memory system, with a worked example
- Provider Specification — Interface reference: methods, types, lifecycle
- Framework Architecture — Pipeline phases, checkpointing, evaluation modes, judge prompts, retrieval metrics
- Deviations — Where our setup differs from published methodology
- Contributing Guide — How to add providers, benchmarks, and submit PRs
MIT