A minimal RAG (Retrieval-Augmented Generation) demo for PDF question-answering. Upload any PDF, ask questions, and get cited answers grounded in the document text.
No vector database. No embeddings. Just BM25 keyword retrieval + an LLM via OpenRouter.
PDF → page chunks → BM25 search → top-k chunks → LLM → cited answer
- Extract —
pypdfreads the PDF page by page - Chunk — text split into ~180-word overlapping windows
- Retrieve — BM25 scores chunks against the user's question
- Generate — top chunks sent as context to an LLM via OpenRouter
- Cite — the LLM is prompted to cite every claim with
[Source N]
| Component | Choice |
|---|---|
| Retrieval | BM25 (no embeddings needed) |
| LLM | deepseek/deepseek-v4-flash via OpenRouter |
| UI | Streamlit |
| PDF parsing | pypdf |
git clone https://github.com/mondalsou/regdociq.git
cd regdociq
pip install -r requirements.txtcp .env.example .env
# edit .env and paste your OpenRouter API keyGet a free key at openrouter.ai/keys.
streamlit run streamlit_app.pyOpen http://localhost:8501, upload a PDF, and start asking questions.
Open rag_demo.ipynb in Jupyter, set PDF_PATH to your PDF, and run all cells step by step.
jupyter notebook rag_demo.ipynbregdociq/
├── streamlit_app.py # Streamlit web app
├── rag_demo.ipynb # Step-by-step notebook walkthrough
├── requirements.txt # Python dependencies
└── .env.example # API key template
Edit MODEL_NAME at the top of streamlit_app.py or rag_demo.ipynb:
MODEL_NAME = "deepseek/deepseek-v4-flash" # fast and cheap
# MODEL_NAME = "openai/gpt-4o-mini" # alternative
# MODEL_NAME = "anthropic/claude-haiku-4-5" # alternativeAny model on OpenRouter works as a drop-in replacement.
MIT