← back

density-rag

Imagine handing someone a 200 page annual report and asking what the revenue was.

The usual way: they run a search for "revenue", flip to the eight pages that matched hardest, and read those. Often those are the contents page, a header, and the auditor's boilerplate. They never learn what they skipped.

This way: they first flip through the entire report and mark, on every page, how strongly it smells of each idea in the question. Then they look at that map and read where the marks bunch together, the way you would spot a dense table from across the room.

That map is the heatmap below. A model reads it as numbers. You read it as colour. It is the same object.

In the technical version: document retrieval using full-document density heatmaps over FAISS indexes. Instead of blind top-k search, it scores every page against several seed terms first, so the model picks pages by spotting clusters rather than guessing.

The question

query  What was the revenue for FY25, and how did segment mix change?

Seed terms the model generated from that question, before reading anything: revenue, segment, FY25, operating margin. Each is embedded and scored against every page in the index.

What the agent sees

cosine similarity 0.10 → 0.90 ·  hover a cell for its score  ·  outlined = pages the model chose to read

The cluster around pages 34 to 38 is the point. No single seed spikes there, but all four score moderately at once, which is what a segment-results table looks like from the outside. Page 12 scores highest on revenue alone and is the contents page. Top-k would have read page 12 and missed the table entirely.

Why it beats top-k

Standard RAG

Embeds the query, returns the 8 nearest chunks, reads them blind.

Every chunk that mentions "revenue" competes equally, so contents pages, headers and the auditor's boilerplate crowd out the actual table.

The model never learns what it did not see.

density-rag

Scores every page against several seeds, then hands the model the full matrix.

The model picks pages by spotting clusters, the way you would flip through a report looking for a dense table.

Next round's seeds come from words it actually read, so they get sharper.

The loop

  1. SEED. The model writes 3 to 5 literal terms from the query.
  2. MAP. Each seed is embedded and scored against every page via cosine similarity over a FAISS index, producing the matrix above.
  3. NAVIGATE. The model reads the matrix as a table and picks 4 to 8 pages, looking for clusters and spread across seeds.
  4. READ. Full page text is loaded for those pages only.
  5. DECIDE. Extract data points with [page N] citations, then either finish, read more from the existing map, or re-seed with terms taken from the real text.

Built for long structured documents, annual reports, filings, manuals, where the answer is scattered across dozens of pages and ordinary retrieval returns noise.