RAG starter: document Q&A with hybrid search and verified citations

We start our document Q&A and knowledge assistant builds from this starter. It covers ingestion, hybrid retrieval, an agent that answers only from your documents and a citation check that fails closed.

What's inside.

How it fits together.

  1. 01

    Upload

    The Next.js front end sends a file to the FastAPI back end, which stores it in R2 and queues an ingestion job.

  2. 02

    Ingest

    A Celery worker extracts the text, splits it into chunks with their position in the document, embeds them and writes them to Postgres with a full-text index.

  3. 03

    Retrieve and answer

    For each question the agent calls hybrid search, which runs vector and keyword search in parallel, fuses the rankings and adds neighbouring chunks for context.

  4. 04

    Validate

    The validator checks every citation against the chunks retrieved in that turn before the answer is returned. Failures are logged and replaced with a safe response.

A look at the code.

A simplified citation check: any citation that cannot be traced to retrieved text rejects the whole answer.

Python
import re
from dataclasses import dataclass

MARKER = re.compile(r"\[(\d+)\]")

@dataclass
class Citation:
    index: int
    chunk_id: str
    excerpt: str

def normalise(text: str) -> str:
    return " ".join(text.split()).lower()

def validate(answer: str, citations: list[Citation], retrieved: dict[str, str]) -> bool:
    """Fail closed: no citations, or one we cannot verify, rejects the answer."""
    used = {int(n) for n in MARKER.findall(answer)}
    by_index = {c.index: c for c in citations}
    for n in used:
        c = by_index.get(n)
        if c is None or c.chunk_id not in retrieved:
            return False
        if normalise(c.excerpt) not in normalise(retrieved[c.chunk_id]):
            return False
    return bool(used)

Built with.

All technologies

Hear when it is public.

We are preparing the rag starter for release. One email when it is out, and our occasional notes.

Occasional emails, unsubscribe any time. See our privacy policy.

Start working with Vantion.