Hackathon-IA-Team / README.md
Quincy Hsieh
Add detailed Hackathon instructions
4d63566
|
Raw
History Blame
15.1 kB
ο»Ώ---
title: Example App Hackathon Gustave Eiffel 2026
emoji: πŸ€–
colorFrom: blue
colorTo: purple
sdk: gradio
sdk_version: 4.44.1
python_version: '3.11'
app_file: app.py
pinned: false
license: apache-2.0
---
# RAG Chat API Sample Code for Gustave Eiffel Hackathon 2026
This is a sample code of **Retrieval-Augmented Generation (RAG)** API deployed to Hugging Face Spaces for the Gustave Eiffel Hackathon 2026. The goal of this hackathon is to build an AI assistant for actuarial questions using a document corpus. The core challenge
is to build an assistant that is:
- βœ… Accurate (Juste) – correct answers, no hallucinations
- πŸ’² Low cost (Pas cher) – minimize token usage
- 🌱 Sustainable (Sobre) – reduce CO2 impact
πŸ‘‰ Success = balance all three, not just performance!
This sample code demonstrates how to build a RAG system with FastAPI and Gradio, and deploy it to Hugging Face Spaces. It also includes the necessary configuration and structure to meet the hackathon requirements. It includes:
- `/query` API endpoint to interact with the user or the RAG evaluation system. Note that the output of this endpoint is designed for the RAG evaluation system, which will assess the correctness of the answer from your RAG. The response MUST have all the fields as follow (DO NOT change the response format, otherwise the evaluation framework will not be able to parse the response and evaluate the answer -- you will get 0 for the evaluation if the response is unparseable):
- answer (str): The generated answer from your RAG system
- sources (list): Source documents used for context in the answer generation, each source should have:
- source (str): File name of the source document
- score (float): Relevance score of the source document
- ref_text (str): The exact text span from the source document that is used in the answer generation (can be truncated if too long)
- explanation (str): Explanation of the retrieval and answer logic
- total_token (int): Total token count from the LLM call
- prompt_tokens (int): Prompt token count
- completion_tokens (int): Completion token count
- cached_tokens (int): Cached prompt tokens (when reported by model provider)
- co2_grams (float | None): Estimated CO2 emission in grams (via ecologits)
- energy_kwh (float | None): Estimated energy use in kWh (via ecologits)
- run_time_in_ms (float): Pipeline execution time in milliseconds
- `/health` API endpoint to check if the API is running or not. The return format should be `{"status": "healthy"}` when the API is healthy.
- Gradio UI and configuration to be deployed to Hugging Face Spaces. The UI allows users to chat with the RAG system and ingest new documents.
---
## Overview
This application demonstrates how to build a production-ready RAG system within the Hugging Face Spaces. It covers:
| Requirement | Provided Solution |
|---|---|
| LLM API calls | Azure OpenAI (`gpt-5.1` via REST API) |
| Text β†’ Embeddings | Azure OpenAI (`text-embedding-3-small` via REST API) |
| Prompt engineering | Custom prompts for RAG system in /prompts/rag_prompts.txt |
| Vector Store | ChromaDB (persistent in /data folder, runs in-process) |
Hackathon participants can use this code as a starting point and customize any solutions (the LLM calls, embeddings, prompts, and vector store) as they see fit to optimize for accuracy, cost, and sustainability. The provided code is modular and well-documented to facilitate easy modifications.
---
## Architecture
```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Hugging Face Space β”‚
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Gradio β”‚ β”‚ FastAPI β”‚ β”‚ ChromaDB β”‚ β”‚
β”‚ β”‚ UI │────▢│ /query │────▢│ Vector Store β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ /ingest β”‚ β”‚ (persistent in β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ /health β”‚ β”‚ /data folder) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β–² β”‚
β”‚ β–Ό β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Azure OpenAI β”‚ β”‚ Azure OpenAI β”‚ β”‚
β”‚ β”‚ GPT-5.1 (LLM) β”‚ β”‚ text-embedding β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ -3-small β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```
---
## Setup & Deployment
### 1. Register for Hugging Face and Create a Space
If you have not created a Hugging Face Space, follow the instructions in the [Hugging Face Quickstart](README_HF.md) to create an account and set up a new Space and clone the sample code to your local machine.
### 2. Set Up a Python Virtual Environment
Download and set up a Python virtual environment to manage package dependencies.
To download Python, visit the [official Python website](https://www.python.org/downloads/) and follow the installation instructions for your operating system. Make sure to install Python 3.10 or 3.11. There is no need to install the latest Python version if it is above 3.11, as some dependencies may not be compatible with versions higher than 3.11.
To create a virtual environment, run the following command in your terminal (you can replace `hackathon-eiffel` with any name you prefer for your virtual environment):
```bash
python -m venv ~/.venv/hackathon-eiffel
# Activate the virtual environment
# macOS / Linux
source ~/.venv/hackathon-eiffel/bin/activate
# Windows (PowerShell)
~\.venv\hackathon-eiffel\Scripts\Activate.ps1
# Windows (Command Prompt)
~\.venv\hackathon-eiffel\Scripts\activate.bat
```
Once your virtual environment is activated, go to your project directory to install package dependencies and run the application:
```bash
# Install dependencies
pip install -r requirements.txt
# Set your Azure API key. Azure API key is a key to call the LLM APIs. The organizers will provide you one at the date of the hackathon.
# macOS / Linux
export AZURE_API_KEY="your_azure_api_key_here"
# Windows (PowerShell)
$env:AZURE_API_KEY = "your_azure_api_key_here"
# Run the application
python app.py
# Server starts at http://localhost:7860 . If you can open http://localhost:7860/health on browser, it means the API is running successfully.
# To make the RAG work, you first need to create embeddings , you can learn about it from README_RAG.md
```
> **Tip:** To deactivate the virtual environment when you are done, run `deactivate` (venv) or `conda deactivate` (conda).
---
### 3. Install the Hugging Face CLI
To manage binary files in the Hugging Face bucket (for storing large files like ChromaDB vector store, ingested documents, etc.), you need to install the Hugging Face CLI tool:
```bash
# Install the hf CLI (requires uv)
uv tool install "huggingface_hub[cli]"
# Try to login to Hugging Face with Hugging Face CLI (it needs Write access to the bucket)
export HF_TOKEN="hf_your_token_here"
# or interactively:
hf auth login
```
### 4. Adding Binary Files to the HF Space
Large or binary files (PDFs, pre-built ChromaDB databases, datasets, model weights) have to be stored in a **Hugging Face bucket** and mounted into the Space container. The `hf sync` command keeps your local folder in sync with the bucket.
> **Note:** Git LFS is not supported for Hugging Face Spaces persistent storage. Use the bucket + `hf sync` workflow described here instead.
### 5. Persist files in the Shared Folder
Each Hugging Face Space has a **persistent storage bucket** that is automatically mounted at `/data` to your project root inside the running container server. This folder is the single shared location where the application reads and writes all persistent files β€” the ChromaDB vector store, display images, even secrets and any binary assets.
| Path in server | Purpose |
|---|---|
| `/data/chroma_db/` | ChromaDB vector store (survives Space restarts) |
**Default bucket naming convention:**
A Hugging Face Space at
`https://huggingface.co/spaces/<org>/<space-name>`
gets a default /data storage bucket at
`https://huggingface.co/buckets/<org>/<space-name>-storage`
Using this project as an example, the Space URL is:
- Space: `https://huggingface.co/spaces/millimanfrance/Example-App-Hackathon-Gustave-Eiffel-2026`
- Bucket: `https://huggingface.co/buckets/millimanfrance/Example-App-Hackathon-Gustave-Eiffel-2026-storage`
The `hf://` URI for use with the CLI is:
`hf://buckets/millimanfrance/Example-App-Hackathon-Gustave-Eiffel-2026-storage`
Note that by default, the bucket is empty and private when you create the Space. You need to upload files to it (via `hf sync`) before they appear in the Space server at `/data`.
To attach the Hugging Face Storage Bucket to Your Space:
1. Open your Space on huggingface.co
2. Go to **"Organization" β†’ Your organization name β†’ "+New" β†’ "Bucket"**
3. Once the bucket is created. Go to your Hugging Face Space, click **"Settings"**. Scroll down to **"Storage Buckets" β†’ "Mount a bucket"**, select the existing bucket **`<org>/<space-name>-storage`** to mount it to your Space of Month path `/data`.
4. "Mount bucket" β€” Hugging Face will mount the bucket at `/data` inside the Space container
To Sync Your Local `./data` with the Space Bucket
Place all persistent files under the `./data` folder of your project. The expected structure may look like this:
```
./data/
β”œβ”€β”€ chroma_db/ # Binary files and ChromaDB vector store
β”‚ └── chroma.sqlite3
./train_data/ # Hackathon train datasets (will be mounted at /train_data in the project with a bucket from the Hackathon organizer)
β”œβ”€β”€ Automobile - Train/
β”œβ”€β”€ Climatique - Train/
└── ...
```
**Push local file in ./data to Hugging Face bucket:**
```bash
# Mirror ./data to the bucket β€” removes remote files deleted locally
hf sync ./data hf://buckets/<org>/<space-name>-storage --delete
# Sync only a specific sub-folder (e.g., the vector store)
hf sync ./data/chroma_db hf://buckets/<org>/<space-name>-storage/chroma_db
# Sync only specific file types
hf sync ./data hf://buckets/<org>/<space-name>-storage \
--include "*.pdf" --include "*.sqlite3"
```
> **`--delete` flag:** Without it, `hf sync` only uploads new/changed files and never removes anything from the remote. Add `--delete` to make the bucket an exact mirror of your local `./data`.
`hf sync` is **incremental** β€” it computes checksums and only transfers files that have changed.
**Download the Bucket to another Machine's `./data` folder:**
To pull the latest bucket contents back to a local `./data` folder (e.g., on another team member's machine):
```bash
hf sync hf://buckets/<org>/<space-name>-storage ./data
```
### 6. Get Hackathon Train Datasets from the Organizer's Bucket
The train datasets for this hackathon are stored in a separate read-only bucket. Sync them to a local `./train_data` folder to save your Hugging Face bucket storage (the train datasets is about 1GB).
```bash
# Download all training data to local folder train_data/ from the organizer's bucket hf://buckets/millimanfrance/Hackathon2026TrainData
hf sync hf://buckets/millimanfrance/Hackathon2026TrainData ./train_data
```
> **Note:** `Hackathon2026TrainData` is a shared read-only bucket. Do not attempt to push to it.
### 7. Accessing Files in the Space Application
Once the bucket is mounted, files appear under `/data` inside the Space container. The application resolves the data root automatically via a single `DATA_DIR` constant in `app.py`. Here is an example of how to access the ChromaDB vector store and the environment file in your code:
```python
from pathlib import Path
# /data when running in HF Spaces (bucket mount), ./data for local dev
DATA_DIR = Path("/data") if Path("/data").is_dir() else Path("./data")
CHROMA_PERSIST_DIR = str(DATA_DIR / "chroma_db")
ENV_FILE = str(DATA_DIR / ".env")
```
All persistent data β€” the vector store, sample documents, datasets β€” lives under `DATA_DIR` so a single `hf sync ./data ...` covers everything.
## Application Configuration
The application loads model configuration from **`./config.json`** (project root)
**NEVER put real credentials in the config file.** Use environment variables instead. The config file is meant for non-sensitive configuration parameters like model names, API endpoints, and other settings.
### Step 1 β€” Configure `./config.json`
Edit `./config.json` to different LLM and embedding models, or to add additional configuration parameters. The provided sample config is designed for Azure OpenAI REST API calls, but you can modify the structure and fields as needed for your implementation. Just make sure to update the code in `app.py` accordingly to read the new config format. The organizers will provide you with the Azure API key at the date of the hackathon, and two LLM models (**gpt-5-mini** & **gpt-5.1**) and embedding models (**text-embedding-3-large** & **text-embedding-3-small**) are available.
```json
{
"embedding": {
"endpoint_url": "https://hackathon-eiffel-2026-apim.azure-api.net/ai/openai/deployments/text-embedding-3-small/embeddings?api-version=2024-12-01-preview",
"model": "text-embedding-3-small"
},
"llm": {
"endpoint_url": "https://hackathon-eiffel-2026-apim.azure-api.net/ai/openai/deployments/gpt-5.1/chat/completions?api-version=2024-12-01-preview",
"model": "gpt-5.1",
"max_completion_tokens": 512,
"temperature": 0.7,
"top_p": 0.95
}
}
```
> **Note:** The `endpoint_url` for embeddings ends in `/embeddings` and the one for the LLM ends in `/chat/completions`. Keep those suffixes intact.
### Step 2 β€” Set the API Key
The API key **MUST NOT** be stored in `config.json`. Set it as an environment variable:
```bash
# macOS / Linux
export AZURE_API_KEY="your_azure_api_key_here"
# Windows (PowerShell)
$env:AZURE_API_KEY = "your_azure_api_key_here"
```
When deploying to Hugging Face Spaces, add it as a **Space Secret** (Go to your Hugging Face Space, click **Settings β†’ Variables and secrets β†’ New secret β†’ name it `AZURE_API_KEY`**).