A newer version of the Gradio SDK is available: 6.22.0
Case study: what chunking and hybrid retrieval actually buy you
Lumen ships an eval harness (lumen_rag/eval/) specifically so claims like
"chunking helps" or "hybrid retrieval helps" don't have to stay vibes. This
is the measurement behind the numbers in the README.
Setup
- Corpus:
data/docs/β 7 markdown documents (~2,250 words total), each covering multiple unrelated handbook topics per file (e.g.deploys-ops.mdbundles deployments, on-call, incident response, disaster recovery, plus three unrelated filler sections). This mirrors a real internal wiki page: long, multi-topic, with the answer to any given question living in one paragraph out of several. - Eval set:
data/eval.jsonlβ 19 labelled questions, each with the correct source document id(s). - Embedder: the offline deterministic
HashingEmbedder(bag-of-words feature hashing, L2-normalised) β no API key, fully reproducible, what CI and the hosted demo run by default. - Metric:
lumen_rag.eval.harness.evaluate, doc-level (chunk hits are collapsed to unique parent documents before scoring), k=5. - Reproduce:
python scripts/benchmark.py
Results
| Configuration | recall@5 | precision@5 | MRR | nDCG@5 | hit rate |
|---|---|---|---|---|---|
| naive β 1 chunk per doc, vector-only | 0.97 | 0.20 | 0.93 | 0.94 | 1.00 |
| + sentence-aware chunking, vector-only | 0.97 | 0.20 | 0.97 | 0.97 | 1.00 |
| + hybrid (BM25 + Reciprocal Rank Fusion) | 0.97 | 0.20 | 0.97 | 0.97 | 1.00 |
Reading the numbers honestly
Recall and hit-rate are already saturated at 0.97/1.00 in the naive config β with only 7 candidate documents and distinct enough vocabulary per topic, the correct document almost always lands somewhere in the top 5 regardless of technique. Publishing only recall would (falsely) suggest chunking doesn't matter here. It does β just not on that metric.
MRR and nDCG@5 are where the effect shows up. Both measure where the correct document ranks, not just whether it's present. Moving from naive to chunked lifts MRR from 0.93 to 0.97 β a small absolute jump that maps to a concrete failure mode disappearing: when a whole 300β450 word multi-topic document is embedded as a single vector, the sections irrelevant to the query dilute the average, and the correct document occasionally ranks 2nd or 3rd behind a partial-vocabulary-match decoy instead of 1st. Sentence-aware chunking (120-word windows, 20-word overlap) embeds each section on its own, so the answer-bearing chunk competes on its own signal instead of being outvoted by the rest of the document.
Hybrid ties chunked-vector, not because RRF doesn't work, but because the
offline HashingEmbedder is itself a bag-of-words signal β term-frequency
counts, L2-normalised. That's structurally close to what BM25 computes, so
fusing the two rankers mostly agrees with itself. Hybrid's actual value
proposition β catching exact rare-term or numeric matches that a semantic
embedding model under-weights in favor of topical similarity β needs a real
semantic embedder (OPENAI_API_KEY set, text-embedding-3-small) and a
larger, noisier corpus to demonstrate honestly. That's flagged as a follow-up
rather than asserted with numbers we didn't measure.
Takeaways for anyone building on Lumen
- Don't just report recall/hit-rate. They saturate fast on small corpora and hide ranking-quality regressions. MRR/nDCG catch what recall misses.
- Chunking's benefit scales with document length and topic density, not corpus size. A corpus of short, single-topic documents won't show this effect β you need documents where the answer is a minority of the content.
- Hybrid retrieval's payoff is embedder-dependent. With a lexical/hash
embedder it's close to redundant with vector search; with a real semantic
embedder it complements it. Re-run
scripts/benchmark.pywithOPENAI_API_KEYset to see the difference on your own corpus.