Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FinQuery 🔍

AI-powered financial research assistant — chat with SEC filings, annual reports, and earnings transcripts using RAG, semantic search, and cited answers.

Python FastAPI License: MIT


Imagine you need to compare Microsoft's and Deloitte's annual reports — 200+ pages combined. Without FinQuery, you're manually scanning and losing context. With FinQuery, you type "What are the key revenue drivers?" and get a cited answer in under 4 seconds, pinpointed to the exact filename and page: 📄 microsoft_annual.pdf · p.4


🚀 Live Demo

Backend API (Live on AWS): http://3.25.163.61:8000/docs

The FastAPI backend is deployed on AWS EC2 using Docker, with persistent document storage and auto-restart configured. Explore the interactive Swagger UI to test document upload, Q&A, and multi-document comparison endpoints directly.

What's Built

  • PDF ingestion pipeline — Extract, chunk (1000 tokens, 200 overlap), embed, and store with a persistent document registry that prevents duplicate uploads across restarts
  • Semantic Q&A with citations — Top-5 cosine similarity retrieval from ChromaDB, answer grounded by Groq (Llama3), citation rendered as filename + page number
  • Multi-document comparison — Same query runs against each document independently with explicit doc_id filtering; LLM synthesises a structured comparison — no cross-document retrieval bleed
  • Conversation memory — Follow-up questions carry prior context; session cleared via DELETE /session
  • Document library — Upload, list, and delete filings; persistent JSON registry maps filenames to ChromaDB IDs across restarts
  • Dockerized + deployed — Backend containerised and running live on AWS EC2; full compose (backend + Next.js + PostgreSQL) defined for local multi-service dev
  • CI/CD pipeline — GitHub Actions runs tests on every push, then automatically deploys to AWS on merge to main

Key Numbers

Metric Value
End-to-end query latency 2–4 seconds
Groq inference time ~500ms
Factual Q&A accuracy (informal, 10-question test) ~80%
Chunk size / overlap 1000 tokens / 200 tokens
Chunks retrieved per query (k) 5
REST API endpoints 7

Architecture

User Query
    │
    ▼
Next.js Frontend  (React · Tailwind CSS)
    │  POST /ask  or  POST /compare
    ▼
FastAPI Backend  (Python 3.11)
    │
    ├─── PDF Upload Path
    │         └── PyMuPDF extract → chunk (1000t / 200o) → all-MiniLM-L6-v2 embed
    │                  └── ChromaDB (local, persistent to disk)
    │                           └── JSON Registry (filename → doc_id map)
    │
    └─── Query Path
              └── embed query → cosine sim top-5 → filter by doc_id
                       └── context + query → Groq (Llama3)
                                └── cited answer (filename + page) → UI

CI/CD

GitHub Actions pipeline runs on every push to main:

  1. CI — runs the pytest suite against the FastAPI backend
  2. CD — SSHs into the AWS EC2 instance, pulls the latest code, rebuilds the Docker image, and restarts the container with --restart unless-stopped

No manual deployment steps required after merging — the live demo link always reflects the latest code on main.


Screenshots

Q&A with Source Citations

Q&A with citations

Multi-Document Comparison

Multi-document comparison

API Documentation

FastAPI docs


Tech Stack — and Why

Layer Choice Reasoning
LLM Groq · Llama3 ~500ms inference, free tier, no credit card. 3–5× faster than OpenAI at this scale
Vector DB ChromaDB Local, persistent to disk, zero API cost. Pinecone makes sense at production scale; ChromaDB is the right call for a self-hosted RAG system
Embeddings all-MiniLM-L6-v2 Runs locally — no embedding API cost, no per-token billing, fast enough at our document scale
Backend FastAPI Async I/O fits the embedding + LLM call pattern; auto-generates OpenAPI docs at /docs
Frontend Next.js · Tailwind SSR where needed, fast iteration on UI components
Database PostgreSQL (planned) Defined in docker-compose.yml for document metadata, user sessions, and upload history — not yet wired into the application logic
Infra Docker + AWS EC2 Single-command local dev; backend runs as a Docker container on EC2 with swap space configured to handle memory-intensive embedding workloads on a t3.micro instance
CI/CD GitHub Actions Automated testing on every push; automated SSH deploy to EC2 on merge to main

API Reference

Method Endpoint Description
POST /upload Upload PDF, chunk, embed, register to persistent doc registry
GET /documents List all uploaded documents with metadata
DELETE /document Remove document from ChromaDB + registry
POST /ask Query a single document — returns answer + citation
POST /compare Run same query across multiple docs; LLM synthesises comparison
DELETE /session Clear conversation memory
GET /health Service health check

The Hardest Problem I Solved

Duplicate document identity across restarts.

Every PDF upload generated a new UUID, so after a server restart ChromaDB still held the vectors but the application had no way to map a filename back to its document ID. Subsequent queries would either fail silently or retrieve from the wrong document.

Fix: built a persistent JSON registry (filename → document ID) that loads on startup. Any re-upload of an existing file returns the existing ID rather than creating a duplicate. The compare endpoint also required an explicit where={"doc_id": id} filter per document — without it, ChromaDB's semantic search retrieves the global top-5 chunks and silently ignores whichever document matched less strongly, making the comparison feature meaningless.

A related issue surfaced during AWS deployment: the EC2 t3.micro instance's 1GB RAM was insufficient to run the embedding model, ChromaDB, and FastAPI simultaneously, causing the Docker container to be OOM-killed (exit code 137). Fixed by provisioning a 2GB swap file rather than upgrading the instance tier.


Quick Start

git clone https://github.com/JaiAgrawal1110/FinQuery.git
cd FinQuery/backend
python -m venv venv
source venv/bin/activate        # Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env            # Add your GROQ_API_KEY
uvicorn app.main:app --reload   # Docs at http://localhost:8000/docs

Frontend (runs locally, connects to live AWS backend)

cd FinQuery/frontend
npm install
npm run dev   # http://localhost:3000

Docker

docker build -t finquery-backend .
docker run -p 8000:8000 --env-file .env finquery-backend

What's Next

  • Hybrid search — BM25 + vector retrieval via LangChain EnsembleRetriever; improves recall on keyword-heavy financial queries
  • RAG evaluation — RAGAS pipeline scoring faithfulness, answer relevance, and context precision on a fixed question set
  • SEC EDGAR auto-fetch — type a company name and year, automatically pull and index the filing
  • Nginx reverse proxy — front the FastAPI container on EC2 for cleaner URLs and TLS termination
  • PostgreSQL integration — wire up document metadata and session persistence beyond the current JSON registry

MIT © 2026 Jai Agrawal

About

Production-grade RAG system for financial document analysis — chat with SEC filings & annual reports, get cited answers in under 4 seconds. Built with FastAPI · ChromaDB · Groq · Next.js

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages