An offline, low-cost AI coding mentor built for the ADTC Laptop LLM Challenge 2026. Runs a quantized LLM locally via RAG over a curated CS syllabus, with bilingual (English/Shona) explanations — no internet, no API costs, no cloud dependency.
# Offline Shona AI Coding Tutor
An offline AI coding tutor built for the **Africa Deep Tech Challenge 2026 — Laptop LLM Challenge**. Teaches Python and Computer science fundamentals in English and Shona, running fully on-device with no internet required.
## Features
- Fully offline inference (Gemma-2-2b-it, quantized GGUF Q4_K_M, via llama.cpp)
- Bilingual: English and Shona, for both explanations and practice questions
- RAG-grounded answers from a curated **58-topic** CS syllabus (Python basics through OOP, recursion, lambdas, and debugging strategy)
- Two modes: ask a question, or generate practice questions on a topic
- Runs within a 7GB RAM budget, CPU-only (official profiler measured peak: **2.75GB**)
- Attempts a real answer even for questions outside the syllabus, instead of a flat refusal — see How It Works
## Setup
```bash
# 1. Clone and enter the repo
git clone
github.com
cd adtc-tutor
# 2. Create virtual environment
python3 -m venv adtc-tutor-env
source adtc-tutor-env/bin/activate
# 3. Install build tools
sudo apt update && sudo apt install build-essential cmake -y
# 4. Install dependencies
pip install -r requirements.txt
# 5. Download the GGUF model + MiniLM embedder into model/ (public, no credentials)
bash download_model.sh
# 6. Build the RAG index
python3 build_index.py
# 7. Run the tutor
python3 rag_tutor.py
```
## Usage
You'll be asked to choose a mode and a language once, up front, and that choice applies consistently across both modes.
```
Choose mode - (1) Ask a question, (2) Get practice questions: 1
Language (english/shona) [1=english, 0=shona]: shona
Ask a coding question: Chii chinonzi for loop
--- Tutor's Answer ---
Musoro: For Loops
Tsanangudzo: For loop inodzokorora chikamu chekodhi kamwe nekamwe...
```
## How It Works
Your question is embedded (locally, via a shared `embedder.py` module wrapping `all-MiniLM-L6-v2`, loaded from `model/` with no network calls) and matched …