How a question gets answered without anything leaving your machine

SecureRAG is a retrieval-augmented generation (RAG) pipeline that runs inside a single browser tab. Your document is parsed in memory, split into passages, converted into vectors, indexed locally and searched when you ask something. This page walks through each stage and the one network request the whole application ever makes.

Last updated:

What happens the moment you drop a file

Four stages run in sequence, all of them on your device. Each stage is ordinary JavaScript, and each one reports progress so you can see where the time goes.

01

Ingestion

The file is read through the browser File API into an ArrayBuffer. Format detection uses magic bytes rather than the file extension, so a mislabelled file does not silently produce empty text. PDF text layers, Word heading levels and Markdown structure are preserved.

02

Normalisation and chunking

Repeated headers and footers are stripped, hard line breaks inside paragraphs are rejoined, and the text is cut along heading, then paragraph, then sentence boundaries — about 700 characters per chunk with 15% overlap, so a sentence is not severed from its context.

03

Embedding

Each chunk is converted into a 384- or 512-dimension vector by a small quantised transformer model running in a Web Worker. Vectors are mean-pooled and L2-normalised so similarity becomes a dot product.

04

Indexing

Chunks and vectors are written to IndexedDB in your browser profile. That means a refresh does not lose your work, and clearing site data deletes everything without leaving a copy anywhere else.

How retrieval picks the passages that matter

When you ask a question, the question itself is embedded with the same model, and the index is searched two ways at once. The dense vector search finds passages that mean the same thing in different words. A keyword pass using BM25 finds passages that contain the exact tokens — contract numbers, model codes, defined terms — which vector search alone often misses. The two ranked lists are merged with reciprocal rank fusion, near-duplicate passages are removed with maximal marginal relevance, and the top six passages are handed to the answering step.

Table 1 — why two retrieval methods instead of one
MethodFinds wellMisses
Vector search (embeddings)Paraphrases: “notice period” matches “termination requires prior written notification”Rare exact tokens such as “§8.2” or an internal reference code
Keyword search (BM25)Exact identifiers, numbers, defined terms, product namesSynonyms and phrasing you did not happen to use
Combined (RRF fusion)Both of the above, ranked separately then mergedNothing is free — fusion can promote a weak passage from each list
Why fusion matters in practice: a contract question usually contains one exact identifier (“clause 8.2”, “party B”) and one paraphrased concept (“walk away early”, “notice period”). Dense-only retrieval often ranks a semantically similar but wrong clause first; keyword-only retrieval misses the paraphrase entirely.

How the answer is produced

Two tiers exist, and you choose which is active. In the default retrieval tier, no language model writes anything: the most relevant sentences are selected from the retrieved passages by coverage and similarity scoring, stitched together in their original order, and every sentence keeps a numbered link back to its source. In the optional generation tier, a small instruction-tuned model (0.5B–1.5B parameters) is downloaded and runs locally to write a fluent answer from the same retrieved passages. Either way the citations are attached before the text reaches you — the model is never asked to produce references, because models invent them.

Strictness is your call. In “documents only” mode, if nothing in the corpus clears the similarity threshold, the answer is “not found in your documents” rather than a plausible guess. In “allow inference” mode the assistant may summarise across several passages, but every sentence that is not directly supported by a source is labelled as an inference.

What actually leaves your device

One request, on first use, and nothing else. The table below is also what the in-app network shield displays in real time while you work.

Table 2 — every outbound request the application makes
RequestDestinationPayloadAfter first use
Model weights (GET)A public model host (HuggingFace or a mirror)The model file name only — no document, no question, no identifierNone; served from the browser cache, works offline
Document parsingNowheren/aNo request of any kind
Embedding and searchNowheren/aNo request of any kind
Answer generationNowheren/aNo request of any kind
Verify it: open DevTools → Network, clear the log, add a document and ask three questions. You will see the model request once. Then switch DevTools to Offline and keep asking — it still works.

Where this approach can be wrong

We would rather list the failure modes than pretend they do not exist. Every one of them is visible in the interface rather than hidden behind a confident sentence.

  • Scanned PDFs without a text layer produce no text at all. SecureRAG detects this and tells you, instead of returning an empty answer.
  • Long documents can be split across a chunk boundary in a way that separates a definition from its exception. Raising the overlap and switching to the generation tier both help; the retrieval-quality guide covers this in detail.
  • A small local model writes less fluent prose than a frontier cloud model. That is the trade you are making, and the comparison page states it explicitly.
  • Mobile browsers impose stricter memory limits. Collections are capped lower on phones, and the tool says so rather than failing mid-index.

Check it yourself in five minutes

  1. Open the tool and DevTools → Network in two windows side by side.
  2. Add two files you already have — one PDF, one Word document. Watch the indexing progress and the absence of requests.
  3. Ask a question whose answer you know. Click a citation marker and confirm it lands on the right paragraph.
  4. Ask something the documents cannot answer, with strictness set to “documents only”. Confirm you get “not found” rather than an invented answer.
  5. Switch DevTools to Offline and repeat step 3. Then clear site data and confirm the library is empty.