I got tired of hallucinated answers from LLMs when I asked about specific documents or topics they weren't trained on. RAG (Retrieval Augmented Generation) is the fix — instead of asking the model to remember things it doesn't know, you give it the relevant context at query time and it answers from that.
This project is a full RAG pipeline. Drop in your own .txt files, ask questions in plain English, and get answers with citations so you can verify them.
- Your files get split into chunks
- Each chunk gets embedded (converted to a vector that captures its meaning)
- Your question also gets embedded
- The most similar chunks are fetched
- Those chunks + your question go to the LLM, which answers strictly from the context
Simple idea, but genuinely useful. The source attribution part is what I care about most — if the answer isn't in your documents, it says so.
- Python + LangChain 1.2
- Hybrid Support (Cloud or 100% Local)
- Cloud Mode: OpenAI
text-embedding-3-small(embeddings) + Groqllama-3.3-70b-versatile(generation) - Local Mode: Ollama
nomic-embed-text(embeddings) + Ollamaqwen2.5:1.5b(generation)
- Cloud Mode: OpenAI
- FAISS for the local vector store (no external DB needed)
rag-document-qa/
├── ingestion/loader.py # loads and chunks your documents
├── embeddings/embedder.py # creates embeddings + builds the vector store
├── retrieval/retriever.py # semantic search + answer generation
├── data/ # drop your .txt files here
└── main.py
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .envBy default, the system runs 100% Locally using Ollama to save API costs and protect privacy.
- Download Ollama
- Pull the required models:
ollama pull nomic-embed-textandollama pull qwen2.5:1.5b - Ensure
USE_LOCAL_MODELS=Trueis in your.env.
If you prefer to use Cloud Models, set USE_LOCAL_MODELS=False and provide your keys:
GROQ_API_KEYOPENAI_API_KEY
Add your .txt or .md files to the data/ folder, then:
python main.pyThere's already a sample file in data/ so you can test it right away without adding anything.
- Groq handles answer generation (free)
- OpenAI handles embeddings — this is the only paid part, and it's tiny (fractions of a cent per document)
- FAISS stores everything in memory, no external services needed
- Chunking uses overlap so context doesn't get cut off at boundaries