This file is the honest status of what Engraphis measures today, how to reproduce it, and what
it does not yet claim. It exists because the README linked a BENCHMARKS.md that had never
been written; when this and the code disagree, the code wins (CLAUDE.md).
Engraphis's eval harness scores retrieval, not end-to-end QA. That distinction is deliberate
and stated everywhere the numbers appear (eval/external.py).
- Correctness gate:
eval/harness.pyovereval/datasets/sample.jsonlandcodemem.jsonl(conflict resolution) andgraph_multihop.jsonl(multi-hop graph recall). Runs on the deterministic embedder, so it is a plumbing/regression floor, not a public performance claim. This is the gate CI enforces. - Ablation:
eval/ablation.py: vector-only vs. 1-hop graph vs. Personalized-PageRank arm, to show the graph arm actually earns its place. - External benchmarks:
eval/external.pyloads LoCoMo and LongMemEval and pushes them through the realMemoryEnginewrite path (conflict resolution + evolution) and hybrid recall with a real sentence-transformers embedder. It reportsrecall_at_k/hit_at_k/answer_token_recall: i.e. did the evidence come back, not did an LLM answer correctly. It retains source categories and abstention/no-evidence questions as explicit exclusions from retrieval-only aggregates rather than silently dropping them.eval.longmemeval_v2is a local, text-only adapter for the official LongMemEval-V2insert(trajectory)/query(query, query_image=None)memory interface; it does not download data or call a model. - Grounded:
eval/grounded.py: answerable → cite, off-topic → abstain. - Chunking (quality per token):
eval/chunking_eval.pyovereval/datasets/longdoc.jsonlingests a multi-topic corpus twice: once as one memory per document (whole) and once with sub-fileChunkingExtractor(chunked), then queries both through the real recall pipeline. This is the first cut of the context-reduction metric (item 3 below). On the deterministic embedder: recall@5 1.000 for both, at ~73% fewer context tokens (809 → 219) and ~4× smaller tokens-to-evidence (162 → 42). Pass--embed-model sentence-transformers/all-MiniLM-L6-v2for a real retrieval number (recall should then favour chunked on larger corpora, not just tie). - Full-pipeline latency + quality:
eval/performance.pytimes the shipped semantic + lexical + graph + fusion + scoring + rerank + packing path after warmup, with reinforcement disabled so repeated measurements do not mutate their corpus. It reports p50/p95/p99 latency, retrieval quality, and packed context tokens in one JSON-safe schema.--filler-memoriesprovides deterministic corpus scaling, and every report records the runtime, architecture, embedder, vector backend, corpus size, warmups, and iteration count.--candidate-kand--retrieval-profilemake adaptive-depth/routing experiments executable instead of changing production defaults from an unmeasured hunch. - Workload context economy:
eval/context_economy.pycompares three executable strategies across every question in a workload: uncapped full-history replay, a contiguous recency window at the same hard budget, and shipped Engraphis hybrid recall + packing. It reports evidence and answer-token quality, cumulative reader-context tokens, a conservative total that charges one complete source-token pass to indexing, and the query-count break-even point. The default is deterministic/offline;--embed-modelenables a real retrieval model, while--format locomo|longmemevalreuses the established external loaders.
The workload benchmark is also allowed to say “this workload is too small for a memory layer.” On the 44-memory / 26-question CodeMem regression fixture, every case already fits inside a 64-token recency window. Full-history and recency therefore use the same 1,180 cumulative reader tokens at perfect evidence/answer-token quality, while Engraphis uses 1,375–1,377 reader tokens plus a conservative 631-token indexing pass. That is an honest no-break-even boundary result: the benefit being measured begins when history is long or reused enough to outweigh retrieval framing and indexing.
The complementary real-model LoCoMo workload diagnostic covers 10 conversations and 1,986
questions with all-MiniLM-L6-v2, k=10, a 512-token reader budget, and conflict resolution
disabled. Engraphis used 891,857 cumulative reader-context tokens versus 49,915,394 for
uncapped full history, 98.2133% lower. Charging one complete 246,539-token corpus pass to
indexing produces a conservative Engraphis total of 1,138,396, still 97.7193% lower, with
a calculated break-even at query 10. The quality tradeoff is explicit:
| LoCoMo workload method | Retrieval recall | Hit rate | Answer-token recall | Mean reader context |
|---|---|---|---|---|
| Engraphis hybrid recall | 0.600457 | 0.657417 | 0.679614 | 449.07 tokens |
| Same-budget recency window | 0.011289 | 0.012614 | 0.339941 | 487.87 tokens |
| Uncapped full history | 0.996997 | 0.997477 | 0.917247 | 25,133.63 tokens |
This diagnostic supports a precise statement: Engraphis recovered much more useful evidence than a same-budget recency window while using a small fraction of full-history context. It does not support “same quality as full history,” provider-billing, or end-to-end answer-accuracy claims. The embedding model revision was not pinned in that run, so rerun it with an immutable revision before treating the numbers as canonical release evidence.
# Correctness gate (deterministic, no download)
python -m pytest tests/ -q
python -m eval.harness --dataset eval/datasets/sample.jsonl --k 5
python -m eval.harness --dataset eval/datasets/codemem.jsonl --k 5
python -m eval.harness --dataset eval/datasets/graph_multihop.jsonl --k 5
python -m eval.ablation
python -m eval.performance --dataset eval/datasets/codemem.jsonl --k 5 --iterations 10
python -m eval.performance --dataset eval/datasets/codemem.jsonl --k 5 \
--candidate-k 25 --candidate-depth adaptive --retrieval-profile auto --iterations 10
python -m eval.context_economy --dataset eval/datasets/codemem.jsonl \
--token-budget 512 --k 5
python -m eval.performance --dataset eval/datasets/codemem.jsonl --k 5 \
--iterations 5 --filler-memories 1000
# Canonical latency/resource protocol: requires >=1,000 queries and five processes.
python -m eval.performance --dataset fixed-1000-plus.jsonl --acceptance-matrix --processes 5
# Real retrieval numbers (downloads all-MiniLM-L6-v2)
python -m eval.external --dataset longmemeval_s.json --format longmemeval --k 10
python -m eval.external --dataset locomo10.json --format locomo --k 10
python -m eval.context_economy --dataset locomo10.json --format locomo \
--embed-model sentence-transformers/all-MiniLM-L6-v2 --token-budget 512 --k 10 --no-resolve- No end-to-end QA accuracy. Official LoCoMo / LongMemEval QA scores depend on an answering model and evaluator. Engraphis isolates retrieval and does not present that result as end-to-end answer accuracy.
- No hosted-service latency comparison. The in-repo p50/p95/p99 benchmark covers the local reference pipeline and records its environment; unlike environments are not compared.
- No neutral third-party ranking. We have not run an external eval platform.
- No provider bill estimate. Context-economy counts reader evidence under its named counter. It excludes system/tool prompts, questions, completions, prompt caching, provider pricing, compute, and storage. Its indexing-inclusive total is a conservative text-volume proxy.
Every publishable run should emit the engraphis-benchmark/v2 envelope: dataset/config hashes,
per-question records, explicit exclusions, fixed-budget context curves, and deterministic
stratified or paired bootstrap confidence intervals. Every run names its token counter.
Noncanonical offline fixtures may identify a deterministic estimate; canonical public evidence
requires the exact pinned reader tokenizer and immutable model revision. The lightweight CI
fixtures validate that machinery; they are not a claim about external benchmark performance.
The benchmark context metric reads strict recall usage fields rather than inferring prompt size:
budget_tokens, context_tokens, source_tokens, saved_tokens, savings_ratio,
packed_count, omitted_count, and token_counter. Use engraphis_recall_context for a
hard-budget prompt packet; legacy engraphis_recall remains available in full or compact response
mode for compatibility.
Use python -m eval.benchmark --input report.json --output artifacts/run.json to validate a
report and write sorted, immutable JSON plus run.json.sha256. The command permits an identical
retry but refuses to replace a different artifact at the same path. For an official
LongMemEval-V2 run, add --canonical: this requires a profile with an exact benchmark repository
revision, dataset revision, reader model revision, and embedding model revision. The checked-in
profile pins immutable upstream commits; replacing any revision with a mutable tag fails
validation. Canonical profiles label the baseline (no_retrieval, lexical_only, dense_only,
dense_lexical_rrf, full_hybrid, full_history, no_graph, no_reranker,
no_temporal_resolution, or whole_document) and declare the required fixed context-budget
matrix: 256, 512, 1024, 2048, and 4096 tokens. Canonical in-repo reports rerun every question at
all five budgets and validate each aggregate against its per-question evidence. The checked-in
LongMemEval-V2 memory-module configuration sets the official adapter's operating point to 1,024
tokens; that single official point must not be presented as a five-point curve.
eval.external --canonical refuses --limit and rejects a normalized output that omitted source
cases. Retrieval-only abstention/no-evidence records remain visible in the artifact's
exclusions; they are not counted as evidence-retrieval scores.
Official LongMemEval-V2 output can be converted into a public-safe QA artifact with
python -m eval.longmemeval_v2_evidence. The exporter keeps the official QA score, fixed-reader
context token count, latency, model revisions, source digests, repository state, and artifact
checksum. It removes raw questions, answers, prompts, reader output, and retrieved context before
the artifact can be written. See eval/EVIDENCE.md for the exact command.
eval.longmemeval_v2.EngraphisLongMemEvalV2Memory follows the official
memory_modules.memory.Memory interface at LongMemEval-V2 commit
6f020ac2fc3275e46c706d3406e02c3ed79b7be2. When imported in that environment, its
@register_memory decorator registers memory_type="engraphis"; use the checked-in
eval/configs/longmemeval_v2_engraphis.json
with the official harness. The config pins Qwen/Qwen3-Embedding-8B to revision
1d8ad4ca9b3dd8059ad90a75d4983776a23d44af; mutable embedding revisions are rejected, and a
canonical adapter run fails instead of relabeling the deterministic offline fallback as Qwen.
Run python -m eval.run_longmemeval_v2 with the official harness arguments and the pinned
checkout on PYTHONPATH. This wrapper performs the upstream registry import in the required order
before delegating to evaluation.harness; a direct upstream invocation must otherwise import
eval.longmemeval_v2 before calling build_memory.
The checked-in configuration is canonical only when the adapter resolves the pinned Qwen reader
processor at c202236235762e1c871ad0ccb60c8ee5ba337b9a. The wrapper also forces the audited
official harness's otherwise-unpinned AutoProcessor call to that same revision. It refuses to
start if the optional processor dependency or immutable revision is unavailable; the local regex
counter is never silently relabeled as a reader budget. The recorded budget counts each returned
context item's content with that reader tokenizer (without prompt framing or inter-item
separators), so it is a hard evidence-item content budget, not a claim about total chat-prompt
tokens. Packed sources are returned as separate context items, preserving the largest fitting
evidence prefix instead of dropping one oversized monolithic item. The adapter does not download
benchmark data or call the reader/evaluator; the official harness owns those steps.
- Run the official LongMemEval-V2 reader and evaluator. The adapter, pinned runner, and
redacted evidence exporter are implemented. The exact upstream commit boots in an isolated
Python 3.11 environment and the wrapper reaches the official harness CLI. Dataset revision
f152293e235517d504809563c833d7190b8c713bpublishes 7,120,369,667 bytes before the pinned Qwen reader and embedding model assets. A full official run therefore still requires those resources, sufficient compute, and evaluator configuration; no canonical QA score is claimed until that run completes. - Publish production-backend latency. Run
eval/performance.pywith the real embedder and sqlite-vec/backend configuration on a fixed machine class and corpus scale. - Run the fixed-budget curve on the complete official datasets. The v2 harness now measures every question at 256, 512, 1,024, 2,048, and 4,096 evidence tokens and validates the per-question records, aggregates, and pinned reader-tokenizer identity. Publish the curve only after complete official runs produce immutable artifacts for every point.
- Run an external evaluation platform once (1)–(3) exist.
Do not make all evidence lanes variants of explicit factual recall. Executable offline adapters now cover:
- MemoryAgentBench: incremental multi-turn learning, long-range understanding, and conflict/consolidation inputs.
- LoCoMo-Plus: an old implicit constraint must affect a later response even when the later cue does not restate the remembered fact.
- Mem2ActBench: memory must select a tool and ground its arguments, not merely return a passage. The current adapter measures retrieval and expected tool-argument context coverage, not generated tool-call success.
python -m eval.agent_benchmarks --dataset memoryagentbench.json \
--format memoryagentbench
python -m eval.agent_benchmarks --dataset locomo_plus.json \
--format locomo_plus
python -m eval.agent_benchmarks --dataset qa_dataset.jsonl \
--conversations toolmem_conversation.jsonl --format mem2actbench \
--artifact artifacts/mem2actbench.jsonUse --artifact on any of these commands to write a redacted, immutable evidence envelope plus
an adjacent SHA256 file. The ordinary console/--json report is private run material and may
contain source questions for debugging.
These runs use the dependency-free deterministic embedder on upstream data. They validate the adapters and expose product gaps; they are noncanonical diagnostics, not leaderboard or marketing claims. The artifact validator accepted every completed envelope.
| Upstream source | Executed scope | Result and boundary |
|---|---|---|
LoCoMo-Plus commit 059f4e3d38f7f1f96765e8e2cb7de3097551bffb |
All 401 Cognitive cases, 40,270 source memories | Recall@10 0.1259, hit@10 0.1272, MRR@10 0.0744, answer-token context coverage 0.5095. This is cue-evidence retrieval, not answer-judge accuracy. The low retrieval score is useful negative evidence: implicit-constraint recall remains a real product gap. |
MemoryAgentBench commit 455306dcabc3842526eb83cd4e225e5d486c5c5d, official Hugging Face Accurate_Retrieval first row |
100 questions | Recall@10 0.5100, hit@10 0.8600, answer-token context coverage 0.8500. Gold evidence was derived only where an accepted answer occurred in a source chunk. |
The same source, Conflict_Resolution first row |
100 questions | Recall@10 0.4600, hit@10 0.6400, answer-token context coverage 0.6800. This plain-context export measures retrieval, not structured temporal invalidation. |
The same source, Long_Range_Understanding first row |
1 question | Answer-token context coverage 0.2658. The export supplied no evidence IDs and no accepted answer occurred verbatim in a source chunk, so retrieval was deliberately left unscored rather than reported as a false perfect score. |
The same source, Test_Time_Learning first row |
One 5.88 MB context | The no-resolution ingest did not complete within a five-minute local smoke ceiling. This is a measured large-ingest throughput gap, not a failed quality score; batch embedding and transaction work should precede a complete split run. |
| Mem2ActBench upstream smoke | 2 public rows | Recall@10, hit@10, MRR@10, and NDCG@10 1.0000; expected tool-call JSON token coverage 0.5714. This is retrieval/context coverage, not generated action success. |
The MemoryAgentBench loader accepts both its aligned public JSON export and the Hugging Face
dataset-server rows[].row envelope. Rows without gold evidence remain useful for answer-token
coverage, but are excluded from retrieval aggregates and counted separately as
retrieval_scored_questions.
For paired code-agent runs, execute the same tasks with the same model, tools, machine, and
deterministic success oracle under full_history and engraphis. Then analyze the content-free
run records with:
python -m eval.code_agent_ab --full-history full-history.jsonl \
--engraphis engraphis.jsonl --output paired-report.jsonThe analyzer rejects unmatched task IDs and different success oracles, then reports paired bootstrap intervals for task success, input/output/tool tokens, retries, latency, and optional cost. Its aggregate output does not echo task IDs or oracle commands. It does not launch an agent or invent a task-success oracle.
- Budget-aware packing: compare full source, safe summary, sentence-aligned safe summary excerpt, and raw-source excerpt at fixed budgets. Gate on support/answer retention and qualifier preservation, not token count alone.
- Adaptive retrieval work:
--candidate-depth adaptiveis now an opt-in performance experiment. It keeps wider graph/code pools and reduces routine lexical/balanced pools while reporting the requested and actual depth. Sample and CodeMem kept every offline quality metric at 1.0 with balanced depth reduced from 50 to 15; CodeMem plus 1,000 fillers reduced local median recall latency from 20.666 ms to 18.991 ms in a 260-recall comparison, an 8.1% reduction. These are machine-specific regression results, not production latency claims. Keep the default fixed until complete external categories meet predeclared quality margins. - Packing-pressure consolidation: prioritize memory families that are frequently recalled, repeatedly omitted, or costly per useful token. Count write/index/storage cost as well as later reader-context savings.
- Tokenizer-aware ingestion: implemented behind the chunk extractor. The dependency-free
default remains
engraphis.chars4.v1; an explicitly configured Hugging Face reader tokenizer enforces prose chunk and overlap budgets and records its identity in chunk metadata. Continue measuring tokens-to-evidence, recall, and storage/index growth together before recommending a model-specific default. - Bulk ingestion: add batch embedding plus a transaction-aware vector upsert path, then rerun the 5.88 MB MemoryAgentBench Test-Time Learning row. Gate this on identical stored-memory, provenance, graph-link, and temporal-resolution outcomes, not throughput alone.
- Scoped caches: benchmark query embeddings and repeat-recall results keyed by workspace, repo, time anchors, profile, and corpus version. Test invalidation correctness before claiming latency gains.
- Privacy-safe real usage: use
engraphis_context_savingsto let each workspace inspect aggregate source/context/saved tokens already present in content-free receipts. Keep unlike token counters separate and require a valid receipt chain before treating totals as auditable.
The predeclared question is whether the full vector + lexical/BM25 + sparse PPR graph + calibrated rerank pipeline, bi-temporal resolution, and grounded abstention produce higher evidence recall per injected token than the registered baselines. The answer must come from a complete, machine-readable artifact with paired confidence intervals; otherwise the release reports “no demonstrated improvement.”