lumen-rag / docs /case-study.md
WickTech's picture
Space README + Gradio entrypoint
fd3cc1a verified
|
Raw
History Blame Contribute Delete
4.02 kB

A newer version of the Gradio SDK is available: 6.22.0

Upgrade

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.md bundles 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

  1. Don't just report recall/hit-rate. They saturate fast on small corpora and hide ranking-quality regressions. MRR/nDCG catch what recall misses.
  2. 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.
  3. 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.py with OPENAI_API_KEY set to see the difference on your own corpus.