NEWpromptev for Android and Chrome: your agents on your phone and in your browser. Get the apps→

Context Engine benchmarks

What was measured, under which conditions, and what was not. Results only, in plain words: permissions under narrow access, retrieval quality on public datasets, and what the Context Graph adds.

Overview

Three sets of measurements. Each one states its data, its questions and its limits. Each one compares the Context Engine with itself or with a plain baseline: no other product appears in any of them.

BenchmarkWhat it answersMeasured on
Permissions under narrow accessDoes a person who may see 10% or 1% of a corpus get what a corpus holding only their documents would return?100,000 documents, 200 questions, synthetic permissions
Retrieval qualityHybrid search against plain vector search with the same embedding model.Five public datasets, 300 questions each
Context GraphWhat searching the Context Graph adds to hybrid search.Four multi-hop datasets, capped in size, 300 questions each

Read the conditions with the numbers. The permissions are synthetic. Recall in the permission benchmark is agreement with a corpus that holds only the person’s documents, not relevance. With the small embedding model used here, hybrid search does not beat plain vector search on most of the public datasets measured. The section What these benchmarks do not show lists the rest.

Permissions under narrow access

The Context Engine applies permissions during the search. The common alternative is to search first and filter afterwards. That loses results: the search spends its limit on passages the person may not see, and what is left after the filter is short or empty, with no error. This benchmark measures how much.

On a 100,000-document corpus with synthetic team-shaped permissions, a person who may see 10% or 1% of the documents gets exactly the top ten that a corpus holding only their documents returns. The same search filtered afterwards returns nothing for 64% and 99% of searches. Fetching ten times more before the filter recovers 0.42 and 0.02 of the results, and fifty times more recovers 0.64 and 0.08.

What was compared

  • Permissions during search. The Context Engine’s search, run as the person.
  • Filter after, same limit. The same search with no permissions, then the top 10 filtered to what the person may see.
  • Filter after, 10x and 50x fetch. The top 100 or the top 500 with no permissions, filtered, cut to 10. Fifty times is the deepest fetch measured.
  • The reference. The same search, with the same settings, on a copy that holds only the documents the person may see, searched exactly. Recall@10 is the share of that copy’s top ten a method returned. “Empty” is the share of searches where a method returned nothing although the copy had results.

Results

100,646 passages, clustered (team-shaped) permissions, the first 200 questions of the dataset. The 95% interval, a percentile bootstrap over questions, is under each recall figure.

SeesMethodRecall@10Empty
10%Permissions during search1.000[1.000, 1.000]0.0%
10%Filter after, same limit0.084[0.065, 0.103]63.5%
10%Filter after, 10x fetch0.419[0.375, 0.470]13.0%
10%Filter after, 50x fetch0.638[0.598, 0.679]1.0%
1%Permissions during search1.000[1.000, 1.000]0.0%
1%Filter after, same limit0.001[0.000, 0.003]99.0%
1%Filter after, 10x fetch0.021[0.012, 0.033]77.0%
1%Filter after, 50x fetch0.083[0.063, 0.106]38.0%

Where every search agreed with the reference the bootstrap interval has no width. The bound that does is the rule of three: with 200 searches and no disagreement, up to 1.5% of searches could still differ. “The same top ten” on this page means the same set of ten results, not the same order.

Recall@10 of hybrid search for a caller who may see 10% or 1% of the corpusAt 10% visibility: permissions during search 1.000 with 0.0% of searches empty, filter after, same limit 0.084 with 63.5% of searches empty, filter after, 10x fetch 0.419 with 13.0% of searches empty, filter after, 50x fetch 0.638 with 1.0% of searches empty. At 1% visibility: permissions during search 1.000 with 0.0% of searches empty, filter after, same limit 0.001 with 99.0% of searches empty, filter after, 10x fetch 0.021 with 77.0% of searches empty, filter after, 50x fetch 0.083 with 38.0% of searches empty.Caller sees 10% of the corpusPermissions during search1.000 · 0.0% emptyPermissions during search, 10% visible: recall@10 1.000, 0.0% of searches emptyFilter after, same limit0.084 · 63.5% emptyFilter after, same limit, 10% visible: recall@10 0.084, 63.5% of searches emptyFilter after, 10x fetch0.419 · 13.0% emptyFilter after, 10x fetch, 10% visible: recall@10 0.419, 13.0% of searches emptyFilter after, 50x fetch0.638 · 1.0% emptyFilter after, 50x fetch, 10% visible: recall@10 0.638, 1.0% of searches emptyCaller sees 1% of the corpusPermissions during search1.000 · 0.0% emptyPermissions during search, 1% visible: recall@10 1.000, 0.0% of searches emptyFilter after, same limit0.001 · 99.0% emptyFilter after, same limit, 1% visible: recall@10 0.001, 99.0% of searches emptyFilter after, 10x fetch0.021 · 77.0% emptyFilter after, 10x fetch, 1% visible: recall@10 0.021, 77.0% of searches emptyFilter after, 50x fetch0.083 · 38.0% emptyFilter after, 50x fetch, 1% visible: recall@10 0.083, 38.0% of searches empty
Recall@10 of hybrid search, and the share of searches returned empty. 100,000 documents (100,646 passages), 200 questions, synthetic team-shaped permissions. Recall is agreement with a corpus holding only the person’s documents, not relevance. Bars are drawn to scale, except that the 0.001 bar is drawn at a minimum visible width. Its label carries the value.

Random against clustered permissions

The same number of visible documents, drawn at random instead of as topic clusters. With permissions applied during the search the layout makes no difference: recall against the visible-only corpus is 1.000 either way. Filtering after the search depends on it. Each cell is recall@10 with the share of searches returned empty under it.

Hybrid search, filtered after the search

SeesFetchClusteredRandom
10%same limit0.08463.5%0.08644.0%
10%10x0.41913.0%0.7300.0%
10%50x0.6381.0%0.8120.0%
1%same limit0.00199.0%0.01189.0%
1%10x0.02177.0%0.08639.5%
1%50x0.08338.0%0.4180.0%

At the same limit the two layouts lose about the same recall. What clustering changes there is how the losses are spread: more searches come back with nothing at all. Fetching more is where the layout decides the outcome. A benchmark that assigns permissions at random and over-fetches will report that filtering after the search is nearly safe. The longer argument is in Your ACL benchmark is measuring the easy case.

Conditions

  • Synthetic permissions. No real permission data was used. For the clustered layout, 40 seed documents are drawn at random, every document joins its most similar seed, and whole clusters are taken until the person sees 10% or 1% of the corpus. Real permissions follow topic less cleanly.
  • Agreement, not relevance. A recall of 1.000 here means the person got what a deployment holding only their documents would return. It does not say those results answer the question.
  • Single-group people, no public documents. Each person holds one group and every document carries a permission.
  • Data. BEIR HotpotQA, 100,000 documents (the judged documents of 500 questions, the rest sampled with seed 0), embedded with BAAI/bge-small-en-v1.5 at 384 dimensions, default settings. The questions are the dataset’s questions in dataset order and were not chosen to match the visible topics.

Retrieval quality

Hybrid search at the default settings against plain vector search with the same embeddings, on five public datasets, the first 300 questions of each, with BAAI/bge-small-en-v1.5 embeddings. Every comparison is paired question by question on the same data, and the interval is a 95% bootstrap of the per-question differences.

With this embedding model, hybrid search beats plain vector search on 1 of 5 datasets, ties on 1 and trails on 3. A stronger embedding model, and a corpus full of names, codes and part numbers, both change the balance. Measure it on your own questions.

DatasetVector onlyHybridHybrid minus vector
MuSiQue0.5330.508-0.025[-0.039, -0.011] trails
2WikiMultihopQA0.7820.725-0.057[-0.071, -0.044] trails
MultiHop-RAG0.6580.686+0.029[+0.015, +0.042] ahead
ArguAna0.5730.513-0.060[-0.085, -0.032] trails
CQADupStack English0.5430.523-0.020[-0.042, +0.005] tie

nDCG@10, with the 95% interval of the paired difference under each delta. “Tie” means the interval spans zero. Recall@10, vector only then hybrid: MuSiQue 0.558 / 0.556; 2WikiMultihopQA 0.752 / 0.745; MultiHop-RAG 0.766 / 0.790; ArguAna 0.833 / 0.817; CQADupStack English 0.581 / 0.584.

Corpus sizes, documents and passages: MuSiQue 11,656 / 12,211; 2WikiMultihopQA 6,119 / 6,817; MultiHop-RAG 609 / 6,976; ArguAna 8,674 / 12,142; CQADupStack English 10,000 of 40,221 / 10,924.

nDCG@10 of plain vector search and of hybrid search at the default settings, on five public datasetsMuSiQue: vector only 0.533, hybrid 0.508. 2WikiMultihopQA: vector only 0.782, hybrid 0.725. MultiHop-RAG: vector only 0.658, hybrid 0.686. ArguAna: vector only 0.573, hybrid 0.513. CQADupStack English: vector only 0.543, hybrid 0.523.Vector onlyHybrid, defaultsMuSiQuevectorMuSiQue, vector only: nDCG@10 0.5330.533hybridMuSiQue, hybrid at the default settings: nDCG@10 0.5080.5082WikiMultihopQAvector2WikiMultihopQA, vector only: nDCG@10 0.7820.782hybrid2WikiMultihopQA, hybrid at the default settings: nDCG@10 0.7250.725MultiHop-RAGvectorMultiHop-RAG, vector only: nDCG@10 0.6580.658hybridMultiHop-RAG, hybrid at the default settings: nDCG@10 0.6860.686ArguAnavectorArguAna, vector only: nDCG@10 0.5730.573hybridArguAna, hybrid at the default settings: nDCG@10 0.5130.513CQADupStack EnglishvectorCQADupStack English, vector only: nDCG@10 0.5430.543hybridCQADupStack English, hybrid at the default settings: nDCG@10 0.5230.523
nDCG@10 on the first 300 questions of each dataset, plain vector search and hybrid search at the default settings. One small embedding model, bge-small-en-v1.5. Retrieval only, document-level judgments, a person who may see everything. CQADupStack English is capped at 10,000 of its 40,221 documents. The scale runs from 0 to 1.

Context Graph

Each dataset was uploaded once in graph mode and searched over that one upload, with and without the Context Graph. Every configuration answered the same 300 questions. Graph mode is a choice per upload, and nothing here changes a default.

Searching the graph raised nDCG@10 over hybrid search on two of the four datasets (2WikiMultihopQA by +0.044 and GraphRAG-Bench novel by +0.046, each with a 95% interval above zero), made no measurable difference on MuSiQue, and lowered it slightly on MultiHop-RAG (-0.016).

DatasetChange in nDCG@10Change in Recall@10
MuSiQue-0.000[-0.022, +0.024]+0.008[-0.016, +0.032]
2WikiMultihopQA+0.044[+0.029, +0.061]+0.065[+0.045, +0.086]
GraphRAG-Bench novel+0.046[+0.019, +0.074]+0.076[+0.039, +0.116]
MultiHop-RAG-0.016[-0.033, -0.001]+0.010[-0.006, +0.027]

Hybrid search with the graph, minus hybrid search alone, on the same 300 questions, with the 95% interval under each figure.

DatasetDocumentsPassagesHybridHybrid + graph
MuSiQue1,000 of 11,6561,0440.7360.736
2WikiMultihopQA1,000 of 6,1191,1820.8010.845
GraphRAG-Bench novel600 of 4,401 passages1,0770.5870.633
MultiHop-RAG300 of 6093,6180.7320.716

nDCG@10 on the capped corpus of each dataset. “Documents” is the cap out of the dataset’s full size.

Change in nDCG@10 from searching the Context Graph as well, with 95% intervals, on four capped multi-hop datasetsMuSiQue: -0.000 [-0.022, +0.024], interval spans zero. 2WikiMultihopQA: +0.044 [+0.029, +0.061], interval above zero. GraphRAG-Bench novel: +0.046 [+0.019, +0.074], interval above zero. MultiHop-RAG: -0.016 [-0.033, -0.001], interval below zero.MuSiQue-0.000 [-0.022, +0.024]2WikiMultihopQA+0.044 [+0.029, +0.061]2WikiMultihopQA: change in nDCG@10 from searching the graph +0.044 [+0.029, +0.061], interval above zeroGraphRAG-Bench novel+0.046 [+0.019, +0.074]GraphRAG-Bench novel: change in nDCG@10 from searching the graph +0.046 [+0.019, +0.074], interval above zeroMultiHop-RAG-0.016 [-0.033, -0.001]MultiHop-RAG: change in nDCG@10 from searching the graph -0.016 [-0.033, -0.001], interval below zero-0.040+0.04+0.08
Change in nDCG@10 from searching the Context Graph as well, with the 95% interval as a whisker. Blue: interval above zero. Orange: interval below zero. An interval that spans zero is no measurable difference: MuSiQue’s change rounds to zero, so it has no bar, only its interval. Corpora capped at 300 to 1,000 documents to fit a model budget, 300 multi-hop questions each, default settings.
  • The graph widens what is found more than it sharpens the top of the list. Recall@10 went up on all four datasets, beyond its interval on the same two. The rank of the first relevant document did not improve in the same way.
  • Model cost of a graph upload. Building the graph cost between $2.48 and $3.26 of model spend per 1,000 passages with the extraction model used here, and a graph search makes no model call. The model was Gemini 2.5 Flash with thinking switched off, at its list price at the time of the run ($0.30 per million input tokens, $2.50 per million output tokens): $3.23 on MuSiQue, $3.26 on 2WikiMultihopQA, $2.49 on GraphRAG-Bench novel, $2.48 on MultiHop-RAG.
  • The corpora are capped, and the cap was set by cost. A cap keeps every judged document of the 300 questions and fills the rest with distractors drawn with seed 0. With fewer distractors every configuration scores higher than it would on the full corpus, so these absolute numbers are not comparable with the retrieval-quality section above.

What these benchmarks do not show

  • Hybrid search does not beat vector search here. On five public datasets with a small embedding model, hybrid search is ahead of plain vector search on one, level on one and behind on three. A stronger embedding model changes the balance. A corpus of part numbers, error codes, names or misspellings may need keyword matching more than these datasets do.
  • The Context Graph does not always help. Two of four datasets, all built from multi-hop questions, where a graph is expected to matter most. Single-hop questions and full-size corpora were not measured.
  • Not answer quality. Every figure is retrieval only. No answer was generated or graded.
  • Not real permissions. The permission layouts are generated, each person holds a single group, and every document carries a permission. People in several groups, documents visible to everyone, and narrowing by source or document were not measured.
  • Nothing beyond the measured scale. The permission run is 100,000 documents. Fetching more than fifty times before filtering is not measured.
  • One dataset, one embedding model for the permission benchmark. Longer documents, another model or another dimension move the numbers for filtering after the search.
  • Questions are not aimed at the visible topics. A person who searches only for what their own team wrote will find filtering after the search less harmful than these numbers. A person who searches for anything else will not.
  • Not latency. No figure on this page is a claim about search time.
  • Not a comparison with any other product. Both sides of every comparison are the Context Engine’s own search or a plain baseline.
1,000 free credits for a 30-day trial · No card required · No subscription1,000 free credits · 30-day trial · No card