This project is a professional-grade prototype of a Retrieval-Augmented Generation (RAG) pipeline in Python. It ingests local documents (PDF, TXT, MD, CSV), chunks them, generates embeddings, indexes them in a local vector store (numpy-based), and uses a Hugging Face model to answer questions grounded in those documents. It includes a CLI and a simple FastAPI for querying.
High-level flow:
Ingestion → Chunking → Embeddings → Vector Store (numpy) → Retrieval → Context Prompt → HF LLM → Answer
- Ingestion:
pypdffor PDFs; direct reads for text files. Basic cleanup of newlines and spaces. - Chunking: Configurable blocks (
CHUNK_SIZE,CHUNK_OVERLAP) to preserve context. - Embeddings:
sentence-transformers(defaultsentence-transformers/all-MiniLM-L6-v2) with normalization for cosine similarity. - Vector store: Embeddings matrix on disk (
embeddings.npy) + cosine search via numpy. - Retrieval: Fetch top_k most relevant chunks.
- Prompt: Concatenate context + instruction to restrict the answer to retrieved text.
- HF LLM: Model defined in
HF_MODEL_NAME, accessed via the Hugging Face Inference API (default) or loaded locally viatransformers.
- Python 3.10+
- Hugging Face Transformers / Inference Client
- Sentence Transformers (embedding model)
- Numpy (lightweight vector store)
- FastAPI + Uvicorn (optional HTTP API)
- pypdf, python-dotenv, tqdm
src/main.py: CLI and FastAPI server.src/rag_pipeline.py: Full pipeline (ingestion, embeddings, vector store, HF generation).src/ingestion.py: Reading, cleaning, and chunking documents.src/config.py: Environment/config loading.src/utils.py: Utilities (prompt, JSONL, directories).data/raw/: Put input files here.data/processed/: Reserved for intermediate outputs (not required in this prototype).models/: Storesembeddings.npyandmetadata.pkl.requirements.txt: Project dependencies..env.example: Example configuration (copy to.env).
- Python 3.10+ and
pip - Hugging Face token (for Inference API or to download private models)
pip install -r requirements.txtCopy the example and fill it out:
cp .env.example .envKey variables:
HF_TOKEN: your Hugging Face token (https://huggingface.co/settings/tokens).HF_MODEL_NAME: language model (e.g.,mistralai/Mistral-7B-Instruct-v0.2).EMBEDDING_MODEL: embedding model (e.g.,sentence-transformers/all-MiniLM-L6-v2).USE_INFERENCE_API:trueto use the Inference API (default, via router.huggingface.co);falseto load locally withtransformers.HF_API_URL: leave empty to use the default router; set only if you need a custom endpoint or alternative model id.DEVICE:cpu,cuda, ormps(Apple Silicon).CHUNK_SIZE,CHUNK_OVERLAP,TOP_K: chunking and retrieval params. Note: some providers expose certain models only as chat (chat_completion). If you see “task not supported”, switch to a model supportingtext-generation(e.g.,HuggingFaceH4/zephyr-7b-beta,meta-llama/Meta-Llama-3-8B-Instruct) or rely on the fallback tochat_completion.
Place documents in data/raw/ and run:
python src/main.py ingestOptional: point to another input directory:
python src/main.py ingest --input /path/to/docspython src/main.py query --question "What is the main topic of the documents?"The output shows the answer and the retrieved chunks.
python src/main.py api --host 0.0.0.0 --port 8000Example curl call:
curl -X POST http://localhost:8000/query \
-H "Content-Type: application/json" \
-d '{"question": "What is the main content?", "top_k": 3}'Returns JSON with answer and context.
- Drop files in
data/raw/(or another directory). - Run
python src/main.py ingestto rebuild embeddings and index. - Query via CLI/API. For large corpora, consider smaller chunks, smaller
top_k, and watch memory use.
- Update env vars:
HF_MODEL_NAME: change to another instruction model (smaller = faster; larger = better quality, higher RAM/VRAM).EMBEDDING_MODEL: set anothersentence-transformersmodel (larger models → richer embeddings, slower/heavier).
- Considerations:
- Latency/cost: Inference API is convenient but depends on network and may incur costs for paid models.
- Hardware: Local loading requires sufficient GPU/VRAM; CPU works but can be slow.
- The model can hallucinate if context is weak; the prompt mitigates but doesn’t eliminate this.
- Quality depends on cleaning, chunking, and document coverage.
- Useful tuning:
CHUNK_SIZE/CHUNK_OVERLAP: smaller chunks improve recall but may over-fragment.TOP_K: higher can bring more relevant context but also noise.- Generation params:
temperature,max_new_tokens.
- Monitor logs; consider storing queries/responses for debugging.
- Authentication/authorization on the API.
- More robust vector store persistence (versions, multi-tenant).
- Namespace datasets for multiple collections.
- Quality evaluation (user feedback, simple metrics).
- Prompt/response caching and latency/cost monitoring.
MIT License. Feel free to use and adapt with proper attribution.