Learn RAG by running it.
Retrieval-augmented generation, explained by letting you do it — on your own text, right in this tab. No prior knowledge assumed; if you've never heard of an embedding, you're in the right place, and if you build retrieval for a living, the controls are real. Nothing you type leaves your browser.
- ✓Runs in your browser
- ✓Nothing uploaded
- ✓Embeds locally
- ✓Open source
First — what is RAG, really?
A model like ChatGPT is brilliant but forgetful. It only knows what it absorbed while being trained, and it has never seen your documents — your notes, your team's wiki, the PDF on your desktop. Ask about them and it guesses, sometimes confidently and wrongly.
RAG — retrieval-augmented generation — is the fix, and it's simpler than the name. Before the model answers, you go find the handful of passages that actually bear on the question and hand them over. The model reads those and answers from them. It's an open-book exam instead of a closed-book one.
That splits RAG into two jobs: retrieval (find the right text) and generation (the model writes the answer from it). Almost everything that makes RAG good or bad happens in retrieval: feed the model the wrong pages and no amount of cleverness saves the answer. So retrieval is the half you'll run yourself below, one step at a time.
Cut the documents into chunks
You can't hand the model an entire library, and you wouldn't want to — it can read only so much at once, and burying the one relevant paragraph among a thousand others just makes the search harder. So the first move is to break your documents into smaller pieces, called chunks. Think index cards instead of whole books.
How you cut matters more than it looks. Too big, and a chunk blends several topics, so a match is noisy. Too small, and you slice a thought in half and lose the context that made it mean something. Edit the text or change the chunking below and watch the count move — there's no universally right setting, which is itself one of RAG's real headaches.
Ask a question, and search the chunks
Now the actual retrieval. You ask something, and the system scores every chunk for how well it answers, then keeps the best few. The interesting part is that "how well it answers" can be measured in completely different ways — and they often disagree. Ask your question, then turn on semantic search to see that disagreement play out.
Three ways to find the right chunk
Keyword search (BM25) matches the actual words. Ask about "login" and a chunk that says "login" scores high. Fast and exact — but literal: ask about "signing in" and it shrugs at a chunk on "authentication," because no words overlap.
Semantic search (embeddings) matches meaning instead. Each chunk and the question get turned into a list of numbers — a position in a "meaning space" — and chunks sitting near the question win. "Signing in" and "authentication" land close together with no shared words. The trade-off: it can drift toward chunks that are merely on-topic rather than ones that actually answer you.
Neither wins on its own, so fusion (RRF) blends the two ranked lists — a chunk both methods like floats to the top. Most RAG tools skip this entirely and lean on embeddings alone. grove goes the other way: it fuses keyword and semantic with a third retriever that walks your documents' own structure — folders, headings, links — like a table of contents. Combining retrievers instead of betting on one is where it parts ways with the typical vector-RAG stack. You'll see keyword, semantic, and their fusion below; grove's extra moves come further down.
Keyword
BM25Exact term overlap. Fast and literal — misses synonyms.
- #11.202
## Getting in People reach the dashboard through single sign-on. We issue a short-lived session token at the start of each visit and refresh it silently in the background, so nobody has to type a password twice in a day. If a teammate loses access, an admin can revoke every active session for them from the members page.
Semantic
EmbeddingsMeaning-based. Catches paraphrase the keywords miss.
Enable semantic search above to rank by meaning.
Fused
RRFReciprocal rank fusion — how grove combines its retrievers.
Appears once semantic search is on.
When one question is really several
Look back at what you asked. If it's really two questions wearing a trench coat — "how do people log in and what are the rate limits?" — a single search serves it badly: the words and meaning of one half dilute the other, and the top results skew to whichever part is louder, starving the rest.
The fix is to decompose the question into focused sub-queries, retrieve for each one separately, then fuse the results with the same RRF you saw above. Each part gets a fair search; the union covers the whole question. A real pipeline (and grove, on its deep mode) asks an LLM to do the splitting; here it's a plain rule-based splitter so it runs instantly — but you can edit the parts, which is the point. The fan-out-and-fuse mechanic is the same whoever writes them.
- 1
Single query
BM25Your whole question, searched as one string — the baseline from above.
- #11.202
## Getting in People reach the dashboard through single sign-on. We issue a short-lived session token at the start of each visit and refresh it silently in the background, so nobody has to type a password twice in a day. If a teammate loses access, an admin can revoke every active session for them from the members page.
Decomposed → fused
RRFEach sub-query retrieved on its own, then the lists fused together.
- #10.016
## Getting in People reach the dashboard through single sign-on. We issue a short-lived session token at the start of each visit and refresh it silently in the background, so nobody has to type a password twice in a day. If a teammate loses access, an admin can revoke every active session for them from the members page.
- #20.016
# Harbor — internal handbook
- #30.016
## Money and plans Each workspace is on a monthly or annual plan. Invoices are generated on the first of the month and emailed to the billing contact. Upgrading takes effect immediately and is prorated; downgrading takes effect at the next renewal so nobody loses paid-for time.
- #40.016
## Shipping changes Every merge to the main branch builds a container and deploys it to staging automatically. A human promotes staging to production with a single approval. Rollbacks are one click and redeploy the previous known-good image.
- #50.015
## Limits The public API allows 600 requests per minute per key. Bursts above that get a 429 with a Retry-After header. Internal services bypass the limit with a signed service token.
With the two-part question, watch chunks from both sections climb the right-hand column, where the single query tends to crowd the top with just one half. When a question really is single-minded, the two columns match — decomposition doesn't help, and doesn't hurt.
Then the model answers
Everything so far has been retrieval. The last step — generation — is the part this playground deliberately stops before. In a real system you take the top chunks, put them in front of an LLM together with the question, and it writes the answer out of them (citing them, if you ask it to).
That's what the "Copy top-3 as context" button up there is: it hands you exactly what a RAG pipeline would feed the model. Paste it in front of your question in any chatbot and you've just done end-to-end RAG by hand — retrieval here, generation there.
Under the hood — the actual math▸
BM25 (keyword). Scores a chunk by how often your query's words appear in it, with two dampers: repeating a word ten times isn't ten times better, and a match on a rare word ("authentication") counts for more than a common one ("the"). Longer chunks are normalized so they don't win just by being big.
Embeddings + cosine (semantic). A small sentence-transformer turns each chunk into a 384-dimension unit vector. Similarity is the cosine of the angle between two vectors: 1 means same direction (same meaning), 0 means unrelated. Ranking is just sorting chunks by cosine to the question's vector.
Reciprocal rank fusion (RRF). Each retriever contributes 1 / (k + rank) to a chunk's score (k = 60 here), summed across retrievers. It rewards chunks that rank well in more than one list, and it needs no score calibration — only the rankings — which is why it travels so well in practice.
The map. PCA and UMAP are only for the picture; they squash 384-D down to 2-D so it fits on screen. The ranking always happens in the full 384 dimensions, so trust the columns over the visual distances.
What you just did is the fast path.
This tool is the retrieval core on its own — deliberately the part that needs no LLM. It's the same keyword + semantic + RRF fusion that grove, a local knowledge engine I'm building, runs on its --fast path. Here's the rest of grove's pipeline, mapped to what you saw above.
A third retriever: structure descent
You fused two signals here. grove runs a third alongside them — an LLM descends your documents' own shape (folders, headings, Obsidian backlinks) like flipping through a table of contents. All three get RRF-fused, exactly like the Fused column above.
Then a relevance prune
Before it answers, grove runs a quick yes/no LLM pass over the fused shortlist — “could this actually answer the question?” — and drops the rest. This playground stops at the fused ranking; that's the cutoff grove tightens.
It embeds whole documents, not chunks
Up top you picked a chunk size. grove skips chunking and embeds at the document level, so structure stays intact. Slide the chunking knobs here and watch retrieval shift — that sensitivity is part of why grove avoids it.
No vector database to run
Here the vectors live in memory for one tab. In grove the keyword index, embeddings, and tree all sit in one local SQLite file — content-addressed so rebuilds are nearly free — and it serves them to AI tools over MCP. Bring your own model.
Want the concepts, not the pitch? Read what RAG actually is, embeddings without the linear-algebra lecture, and building a RAG engine without a vector database. And the honest footnote on this tool: BM25 and fusion are plain arithmetic, and the embeddings come from a small sentence-transformer (all-MiniLM-L6-v2) that runs in your browser via WebAssembly. The model weights download once from the HuggingFace CDN; your text never does.