Skip to content

Repository files navigation

title IPBot
emoji 🎓
colorFrom blue
colorTo green
sdk docker
app_port 7860
pinned false

IPBot

Ask your university anything, in any language

Python Docker Documents Live

Live: https://rawfilejson-ipbot.hf.space/

Quick start

python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt

Put a Groq key in .env:

GROQ_API_KEY=gsk_your_key_here

Build the index, then run it:

python run_pipeline.py
uvicorn api:app --reload --port 7860

Open http://localhost:7860

Refreshing the documents

pip install -r requirements-tools.txt
python tools/refresh_schedules.py
python tools/scrape_programmes.py
python run_pipeline.py

scrape_programmes.py covers licenciaturas, mestrados and CTeSP Only the 47 licenciaturas are in the repo today, so running it is how masters and CTeSP get added

refresh_schedules.py exits non-zero if a timetable comes out missing subjects that have exams scheduled That means the PDF grid changed shape and the parser needs a look - not that the data is gone

To see what the retriever returns for a question, without the model in the way:

python -m tools.search_cli

Architecture

Knowledge_Base/            147 files, 10 categories
       |
       v   loader -> chunker (1200 / 120, timetables keep their header)
       |
       v   intfloat/multilingual-e5-small     "passage: " at index time
       |
   vector_db/              932 chunks in ChromaDB
       |
       v   "query: " at search time
       |
   question
       |
       +-- router --- greeting or off-topic ------> direct reply
       |      |
       |      +-- rewritten query
       |             |
       |             +-- 10 + 4 candidates
       |                    |
       |                    +-- dedupe, re-rank, keep 6
       |                           |
       v                           v
   Llama 3.3 70B via Groq  ->  answer + source links

Configuration

Everything worth tuning is in src/config.py:

CHUNK_SIZE = 1200          # characters, with 120 of overlap
SEARCH_K_ROUTED = 10       # candidates from the rewritten query
SEARCH_K_RAW = 4           # candidates from the raw question
MAX_CONTEXT_DOCS = 6       # what actually reaches the prompt
ANSWER_HISTORY_TURNS = 16  # conversation the model sees
MAX_UPLOAD_BYTES = 5_000_000

Prompts are plain text in src/prompts/ - changing how IPBot talks does not mean touching Python

Deployment notes

The Space runs from the Dockerfile Full walkthrough in DEPLOYMENT.md The short version is git push origin main for GitHub and ./deploy.sh for the Space

The two differ because the Hub rejects binary files unless they are in LFS, while GitHub's free LFS budget is small main stays plain git, and deploy.sh builds an LFS-tracked branch only when publishing

  1. run_pipeline.py runs at build time, so the index always matches the installed chromadb and the model is baked into the image
  2. vector_db/ is not committed - it is derived from Knowledge_Base/ and rebuilt on every build
  3. GROQ_API_KEY is a Space secret
  4. Free Spaces sleep. The first request after a nap waits for the container to wake
  5. deploy.sh refuses to push anything that looks like a secret

Author

Demetre Metreveli

About

IPBot - an academic assistant for Instituto Politécnico de Bragança. Answers from official IPB documents, in any language, and links the source.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages