Memory & Context Eval Harness

August 15, 2026 · View on GitHub

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.

Architecture

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:

  1. Ingest — Load benchmark sessions into a memory provider
  2. Search — Retrieve relevant context for each question
  3. Answer — Generate answers using an LLM with retrieved context
  4. Evaluate — Score answers with an LLM judge + compute retrieval metrics
  5. Report — Aggregate accuracy, latency, and retrieval quality

Supported Providers

ProviderTypeSDK
SynapFull context managementpip install maximem-synap
Mem0Memory extractionpip install mem0ai
ZepTemporal knowledge graphpip install zep-cloud
SupermemoryAuto-chunking + searchpip install supermemory
CustomImplement Provider ABCSee Adapter Spec

Supported Benchmarks

BenchmarkQuestionsSessionsFocus
LongMemEval500940Long-term memory across sessions
LoCoMo1,5405,290Multi-conversation, multi-modal, very long context
CustomImplement Benchmark ABCSee Adding Benchmarks

Headline Results

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.

BenchmarkScopeProviderAccuracy
LoCoMoFull set, 1,540 Cat 1-4 questions (adversarial Cat 5 excluded)Synap93.2%
LongMemEvalFull set, 500 questions across 6 categoriesSynap92.0%

Full methodology, category-level breakdowns, and the cross-vendor comparison live in the results repo: maximem-ai/eval_benchmark_runs_output.

Quickstart

1. Install

git clone https://github.com/maximem-ai/memory_and_context_eval_harness.git
cd memory_and_context_eval_harness
pip install -e .

2. Configure

cp .env.example .env
# Edit .env with your API keys

3. Get the datasets

python 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.

4. Run

python -m runner.server

This 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

Evaluation Modes

ModeDescriptionUse Case
GlobalAll sessions in one shared containerFast, cross-session reasoning
IsolatedSeparate container per questionClean evaluation, no cross-contamination

Retrieval Metrics

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

Adding a Provider

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.

Adding a Benchmark

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"

Configuration

Provider credentials are stored in .env. Provider-specific settings are in configs/*.yaml. Orchestrator configs define multi-dataset pipelines in configs/orchestrator_*.yaml.

Project Structure

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

Documentation

License

MIT