← Back to Projects

Document Intelligence Platform

A retrieval-augmented generation platform that turns a large collection of PDFs into a queryable knowledge base — ask a question in plain language, get an answer grounded in the source documents with a page-level citation behind every claim.

Python FastAPI PostgreSQL pgvector LlamaIndex Haystack GPT-4 React Docker

The problem it solves

Plenty of organisations sit on hundreds or thousands of PDFs — reports, filings, contracts, research, technical documentation — that nobody can search properly. Keyword search misses anything phrased differently to the query, and full-text search returns whole documents when what you needed was one paragraph on page 84.

The usual fallback is a person reading through the pile. That does not scale, it is expensive, and the output is inconsistent between readers. This platform makes the collection genuinely searchable by meaning, and produces written summaries that stay traceable to their sources.

Key Features

Document Ingestion

Layout-aware PDF extraction with intelligent chunking, so tables and multi-column pages survive the pipeline intact

Semantic Retrieval

Vector similarity search over PostgreSQL with pgvector, plus optional reranking to push the most relevant passages to the top

Citation Preservation

Every generated statement carries a page-level reference back to its source document, so output can be verified rather than trusted

Structured Report Generation

LlamaIndex orchestration produces consistent, sectioned reports from a query rather than a wall of chat output

Workspace Isolation

Multi-tenant by design — each workspace has its own document set and index, with no cross-workspace retrieval

Multilingual Corpora

Handles document sets spanning multiple languages, including right-to-left scripts, without a separate pipeline per language

Professional Export

Reports export to Word (.docx) and PDF with formatting and citations preserved, ready to circulate

React Front End

Upload, query, and report generation in one interface, with retrieval results shown alongside the generated text

Technical Architecture

Two pipelines, deliberately kept separate. Ingestion runs once per document: extract, chunk, embed, store. Query runs per question: retrieve, rerank, generate, cite. Keeping them apart means re-indexing a corpus does not require touching the query path, and swapping the generation model does not require re-embedding anything.

Ingest:  PDFs → layout-aware parse → chunker → embeddings → PostgreSQL + pgvector

Query:   question → vector retrieval → rerank → LlamaIndex + GPT-4 → cited report → .docx / .pdf

Backend Stack

  • • Python with FastAPI for REST endpoints
  • • PostgreSQL with pgvector for vector storage
  • • Layout-aware PDF parsing and chunking
  • • Haystack 2.x retrieval pipeline

AI Integration

  • • LlamaIndex for RAG orchestration
  • • GPT-4 behind a LiteLLM proxy for model portability
  • • Vector similarity search with reranking
  • • Docker-based deployment

Workflow

1. Upload

PDF collections go in through the web interface and are parsed with layout awareness, so structure is not flattened away

2. Index

Extracted text is chunked, embedded, and written to PostgreSQL with pgvector alongside its page provenance

3. Query

A plain-language question is matched semantically against the corpus, with reranking applied before anything reaches the model

4. Generate and export

The model writes a structured report from the retrieved passages, each claim carrying its page citation, then exports to Word or PDF

Engineering notes

Citations are a retrieval concern, not a prompt concern

Page provenance is attached to each chunk at ingestion and carried through retrieval. Asking a model to cite its sources after the fact invites invention; carrying the reference through the pipeline does not.

Chunking decides retrieval quality

More tuning time went into chunk boundaries than into prompts. Splitting mid-table or mid-clause produces confidently wrong answers that are hard to spot downstream.

The proxy layer earns its keep

Routing generation through LiteLLM meant swapping models was a config change rather than a refactor — worth it in a space where the best available model changes every few months.

Structured output beats chat

Generating a fixed report shape rather than free-form answers made results comparable across queries and far easier to review at volume.

Related services

If you have a document pile that should be a searchable system, these are the relevant places to start.