AI-powered financial research assistant — chat with SEC filings, annual reports, and earnings transcripts using RAG, semantic search, and cited answers.
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
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.
- 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_idfiltering; 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
| 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 |
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
GitHub Actions pipeline runs on every push to main:
- CI — runs the pytest suite against the FastAPI backend
- 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.
| 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 |
| 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 |
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.
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/docscd FinQuery/frontend
npm install
npm run dev # http://localhost:3000docker build -t finquery-backend .
docker run -p 8000:8000 --env-file .env finquery-backend- 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


