Skip to content
Harshdeep Singh

Case study

Knowledge Workbench

Research with hybrid retrieval and citation-grounded answers

A NotebookLM-style research assistant. Notebooks hold PDFs, articles, YouTube videos and VTT transcripts; answers stream with citations that jump back into the source viewer.

  1. 01Ingest
  2. 02Dense + full-text
  3. 03Fuse + rerank
  4. 04Cited answer

Query rewrite → Qdrant dense search + Postgres full-text search → reciprocal rank fusion → time diversify → LLM rerank → streamed answer with [n] citations.

Status
Public repository
Demo
None hosted
Runtime
Bun + TanStack Start
Stores
PostgreSQL + Qdrant
Source on GitHub(opens in a new tab)

01Problem

Why this is hard

Research means reading across mixed sources — papers, articles, videos — and an answer is only useful if you can check exactly where it came from.

Each retrieval method misses something on its own: vector search can miss exact terms, full-text search can miss paraphrase. And a citation has to land on the cited material, not just name a document.

02Approach

The shape of the solution

  1. 01

    Every source runs the same pipeline: create, background job, type-specific extract, chunk, embed, write chunks to Postgres and upsert vectors to Qdrant, then mark ready.

  2. 02

    Questions run hybrid retrieval: rewrite the query, search Qdrant (dense) and Postgres full-text (lexical), merge with reciprocal rank fusion, diversify, and rerank with an LLM.

  3. 03

    Answers stream with [n] citation badges that open the source viewer at the cited material.

  4. 04

    Studio artifacts — brief, study guide, comparison, learning roadmap — run as notebook-wide retrieval probes, not per-source features.

03System

How the pieces fit

Knowledge Workbench pipeline: sources are extracted, chunked and embedded into PostgreSQL (text, metadata, chat) and Qdrant (vectors). A question is rewritten, searched in both stores, fused with reciprocal rank fusion, reranked by an LLM, and answered with citations.
Source types
pdf, text, url, youtube, vtt. Status flows uploading → indexing → ready or failed.
Ingest
YouTube caption indexing behind residential proxy checks; playlist import up to 25 videos.
Progress
Server-sent events stream live indexing progress to the notebook.
Auth
Clerk; notebooks carry an ownerId and mutating server functions check ownership.

04Engineering decisions

What was chosen, and what it cost

  1. K1

    Two stores with explicit ownership

    PostgreSQL (with Drizzle) owns text, metadata and chat; Qdrant owns embeddings, with point IDs kept in sync with the Postgres chunks.

    Cost
    Every ingest writes to both stores, so the two must be kept consistent.
  2. K2

    Hybrid retrieval with rank fusion

    Dense and lexical results are merged with reciprocal rank fusion, time-diversified, then reranked by an LLM before the answer is generated.

    Cost
    Each question pays for a query rewrite and a rerank call on top of two searches.
  3. K3

    Citations as navigation

    Answers carry [n] citation badges that open the source viewer, so a claim can be checked against the material it came from.

  4. K4

    Bun and TanStack Start server functions

    Bun is the production runtime; TanStack Start file routes and server functions carry the API, with ownership checks on every mutation.

    Cost
    Background work runs in-process rather than on a durable queue.

05Tradeoffs

Known limits, written down

  • Background jobs run in-process (setTimeout) and are lost if the process crashes — not Redis, not a durable queue.

  • Rate limits are in-memory per process.

  • Analytics are a development-only console track(); there is no analytics vendor.

  • bun run eval:rag covers two hardcoded timestamp cases. It is not a CI evaluation harness.

  • Plan-limit and upgrade UI exist; there is no Stripe billing.

06Technology

What it runs on

Runtime
  • Bun
  • TypeScript
App
  • TanStack Start
  • TanStack Router
  • TanStack Query
  • React 19
  • Tailwind 4
Data
  • PostgreSQL
  • Drizzle
  • Qdrant
AI
  • OpenAI embeddings
  • OpenAI chat
Auth
  • Clerk
Deploy
  • Docker Compose
  • Caddy on a VPS
  • Qdrant Cloud