Yerel-PDF-RAG: A PDF Question-Answering System That Cites Its Sources
A RAG application that answers questions in Turkish about the PDFs you upload, cites every answer with the document and page number, and runs entirely on your own computer.

Problem
Finding a piece of information in long regulations, academic calendars and reports takes time. General-purpose chat tools can make up facts that are not in the document, and they do not show where an answer came from.
This system answers only from the uploaded documents and shows the source of every claim as a document and page number. When the information is not in the documents, it says so plainly. In the local version the documents never leave the computer.
Approach
In RAG, most errors come not from the model but from reading the document wrongly or retrieving the wrong passage. That is why most of the work went into the extraction and retrieval layers.
PDFs are read with word positions; two-column pages, repeated headers and footers, and tables without ruling lines are handled separately. Table rows are rewritten as "Label | Column: value" so the model reads them correctly. Retrieval combines Turkish stemmed keyword search (BM25) with semantic search (e5), and follow-up questions keep the context of the previous one.
The answer comes from a single model call. The output is bound to a JSON schema (answered, no information, ask for clarification) and every cited source is verified. Throughout development I measured with separate question sets and only accepted changes that fixed a general class of errors, never patches for a single question or document.
I wrote both sides of the application. The FastAPI backend handles document upload, retrieval and the answer stream; the React and TypeScript interface brings together the conversations, the streaming answer and a PDF viewer that opens the cited page.
Highlights
- Numbered sources; clicking one opens the matching PDF page in a side panel
- The answer streams in as it is written (SSE)
- Says "no information" instead of making up an answer that is not in the documents
- In documents where the same row names repeat across tables (e.g. a faculty-by-faculty academic calendar), keeps track of which row belongs to which unit
- The local version runs offline with Ollama and Qwen3.5 4B on a laptop with a 4 GB GPU
- The model provider can be switched in the settings; the live version runs on the Groq API, Docker and Hugging Face Spaces
Next project
Back to all projects
Internship Management System
A web application that manages internships between students, the internship committee, the faculty internship office (KPTO) and companies on one platform, from application to final evaluation.
- C#
- ASP.NET Core MVC (.NET 10)
- Entity Framework Core
- ASP.NET Core Identity