Skip to main content
The Op-EdAI
2025-05-202 min

How I Built a RAG Helpdesk for My College

A deep dive into building Internal GPT — a Retrieval-Augmented Generation system that answers questions strictly from institutional documents with source citations.

Pass it on LinkedIn Post RSS

Internal GPT is a full-stack Retrieval-Augmented Generation helpdesk that I built specifically for college environments. The core idea is elegant in its simplicity: administrators upload institutional documents, and students and staff can ask natural language questions that are answered strictly from that data, complete with source citations. Every answer is grounded in the uploaded material, so there is no risk of the AI hallucinating policies that do not exist.

The system works in two distinct phases. First, when a document is uploaded, the backend extracts the text content and splits it into semantically meaningful chunks. Each chunk is then converted into a vector embedding using an embedding model, and these embeddings are stored alongside the original text. When a user asks a question, that question is also embedded, and we perform a vector similarity search to find the most relevant document chunks. This retrieval step is crucial because it constrains the AI to only consider information that actually exists in the knowledge base.

The second phase is generation. The retrieved chunks are injected into a carefully crafted prompt that instructs the AI model to answer based solely on the provided context. If the context does not contain sufficient information to answer the question, the model is instructed to say so explicitly rather than making something up. This is one of the most important prompt engineering lessons I learned: you must give the AI a graceful way to say "I don't know." Without that explicit instruction, models tend to produce plausible-sounding but completely fabricated answers, which is unacceptable in an institutional setting.

On the frontend, I used React with Vite for fast development and hot module reloading. The backend is a Node.js and Express API that handles document upload, text extraction, chunking, embedding, and search. For the initial version, I used Supabase for authentication and storage, with the embeddings stored in a simple table. However, I designed the retrieval layer with a clean abstraction so it can be upgraded to pgvector for production-scale deployments without changing any other part of the system.

One of the trickiest aspects was handling document formats. PDFs, Word documents, and plain text files all require different extraction pipelines, and some documents have complex layouts that confuse naive extraction algorithms. I implemented a fallback strategy where if the primary extraction method fails, the system tries alternative approaches before reporting an error to the user.

Building this system taught me that production RAG is as much about retrieval quality as it is about generation quality. A perfect language model is useless if it is searching through bad data. I spent significant effort on chunking strategies, overlap sizes, and embedding model selection. The difference between a good retrieval system and a great one is the difference between answers that are merely relevant and answers that are precisely correct.

Filed under
ReactNode.jsRAGGroqOpenAISupabaseAI