oc_mlops_projet_3 / README.md
CedM's picture
Déploiement automatique depuis GitLab CI
0bedf8a verified
---
title: NBA Analyst AI
emoji: 🏀
colorFrom: blue
colorTo: indigo
sdk: docker
app_port: 7860
pinned: false
license: mit
short_description: Chatbot NBA RAG+SQL (Streamlit,Faiss,SQL,Mistral)
---
# Assistant RAG avec Mistral
Ce projet implémente un assistant virtuel basé sur le modèle Mistral, utilisant la technique de Retrieval-Augmented Generation (RAG) ou RAG + Agent SQL pour fournir des réponses précises et contextuelles à partir d'une base de connaissances personnalisée.
## Fonctionnalités
- 🔍 **Recherche sémantique** avec FAISS pour trouver les documents pertinents
- 🔍 **Recherche SQL** pour interroger une base de données PostgreSQL
- 🤖 **Génération de réponses** avec les modèles Mistral (Small ou Large)
- ⚙️ **Paramètres personnalisables** (modèle, taille des chunks, nombre de Retrieved Documents, température, etc.)
- 📊 **Évaluation des performances** du RAG ou du RAG+SQL avec Ragas (Context Precision, Context Recall, Answer Relevancy, Faithfulness)
- 🧑‍💻 **Interface utilisateur** avec Streamlit pour une interaction facile
## Installation en local - Prérequis
- Ubuntu 22.04+ ou n'importe quel système d'exploitation compatible
- Python 3.11+
- PostgreSQL (Agent SQL)
- Clé API Mistral (obtenue sur [console.mistral.ai](https://console.mistral.ai/))
- Clé API Logfire (obtenue sur [logfire.com](https://logfire.com/))
### Installation
1. **Cloner le dépôt**
```bash
git clone https://framagit.org/dapa/oc_mlops_projet_3.git
cd oc_mlops_projet_3
```
2. **Créer un environnement virtuel**
```bash
# Création de l'environnement virtuel
python -m venv mon_venv
# Activation de l'environnement virtuel
source mon_venv/bin/activate
```
3. **Installer les dépendances**
```bash
pip install -r requirements_local.txt
```
4. **Configurer les clés API et mots de passe**
Créez un fichier `.env` à la racine du projet avec le contenu suivant :
```
# Clés API
MISTRAL_API_KEY="votre_clé_api_mistral"
LOGFIRE_TOKEN="votre_clé_api_logfire"
# URL du stockage distant des données d'entrée (si applicable)
INPUT_DATA_URL=""
# Configuration PostgreSQL
PG_ADMIN_PASSWORD=mot de passe admin
PG_USER_1_PASSWORD=mot de passe user_1
```
5. **Installer et configurer PostgreSQL**
```bash
# Installation de PostgreSQL (exemple pour Ubuntu)
sudo apt update
sudo apt install postgresql -y
# Chargement des variables d'environnement
source .env
# Création de la base de données et des utilisateurs
sudo -u postgres psql \
-c "CREATE ROLE admin WITH LOGIN PASSWORD '$PG_ADMIN_PASSWORD' CREATEROLE;" \
-c "CREATE DATABASE oc_mlops_projet_3 OWNER admin;"
psql -h localhost -p 5432 -U admin -d oc_mlops_projet_3 \
-c "CREATE ROLE user_1 WITH LOGIN NOINHERIT PASSWORD '$PG_USER_1_PASSWORD';" \
-c "GRANT CONNECT ON DATABASE oc_mlops_projet_3 TO user_1;" \
-c "GRANT USAGE ON SCHEMA public TO user_1;" \
-c "GRANT SELECT ON ALL TABLES IN SCHEMA public TO user_1;"
```
6. **Créer le schéma relationnel de la base de données**
Exécutez le script SQL suivant en vous connectant avec l'utilisateur `admin` pour créer les tables et les clés étrangères :
```bash
psql -h localhost -p 5432 -U admin -d oc_mlops_projet_3 -f SQL_db/schema_relationnel_sql.sql
```
Ce script va :
1. Créer les 6 tables (`teams`, `players`, `analyse_joueurs_une_equipe`, `analyse_nbr_joueurs_et_points_par_equipe`, `analyse_top_15_joueurs_nombre_points`, `stats_joueurs_saison_reguliere`)
2. Ajouter les contraintes de clés étrangères entre les tables
3. Ajouter les commentaires sur les colonnes
> ⚠️ **Cette étape est indispensable avant de lancer `load_excel_to_db.py`**, sans quoi les tables cibles n'existent pas encore.
## Structure du projet
```
.
├── .gitignore # Fichier pour ignorer les fichiers et dossiers non pertinents dans le dépôt Git
├── .env # Fichier pour stocker les variables d'environnement (clés API, mots de passe, etc.)
├── Dockerfile # Image Docker combinée PostgreSQL + Streamlit (port 7860)
├── evaluate_ragas.py # Script pour évaluer les performances du RAG ou du RAG+SQL avec Ragas
├── indexer.py # Script pour indexer les documents
├── load_excel_to_db.py # Script pour charger les données Excel dans la base de données PostgreSQL
├── MistralChat.py # Application Streamlit principale
├── Notebook_Eval_Ragas.ipynb # Jupyter Notebook pour l'évaluation des performances du RAG ou du RAG+SQL avec Ragas
├── README.md # Documentation du projet
├── requirements_docker.txt # Dépendances Python pour le déploiement Docker (HF Spaces)
├── requirements_local.txt # Dépendances Python pour l'installation locale
├── start.sh # Script d'initialisation PostgreSQL et de démarrage des services
├── Docs/ # Diagrammes fonctionnels et schéma relationnel de la base de données
├── inputs/ # Dossier pour les documents sources (PDF, XLSX, etc.)
├── Ragas_results/ # Dossier pour les résultats d'évaluation du RAG ou du RAG+SQL avec Ragas
├── SQL_db/ # Scripts SQL de création du schéma relationnel
├── vector_db/ # Dossier pour l'index FAISS et les chunks vectorisés
└── utils/ # Modules utilitaires
├── config.py # Configuration de l'application
├── data_loader.py # Extraction et prétraitement des documents pour l'indexation
├── langgraph_app.py # Routeur d'aiguillage vers Rag ou agent SQL selon la requête utilisateur
├── sql_tool.py # Construction de l'outil de traduction de requêtes en SQL
└── vector_store.py # Gestion de l'index vectoriel
```
## Utilisation
### 1. Ajouter des documents
Placez vos documents dans le dossier `inputs/`. Les formats supportés sont :
- PDF
- TXT
- DOCX
- XLSX
- CSV
Vous pouvez organiser vos documents dans des sous-dossiers pour une meilleure organisation.
### 2. Indexer les documents
Exécutez le script d'indexation pour traiter les documents et créer l'index FAISS :
```bash
python indexer.py
```
Ce script va :
1. Charger les documents depuis le dossier `inputs/`
2. Découper les documents en chunks
3. Générer des embeddings avec Mistral
4. Créer un index FAISS pour la recherche sémantique
5. Sauvegarder l'index et les chunks dans le dossier `vector_db/`
### 3. Charger les documents dans la base de données PostgreSQL
Exécutez le script pour charger les données Excel dans la base de données PostgreSQL :
```bash
sudo systemctl start postgresql
python load_excel_to_db.py
```
Ce script va :
1. Charger les fichiers Excel depuis le dossier `inputs/`
2. Se connecter à la base de données PostgreSQL
3. Effacer les données existantes dans les tables concernées
4. Insérer les nouvelles données dans les tables correspondantes
### 4. Evaluation des performances du RAG ou du RAG+SQL avec Ragas
Si vous souhaitez faire l'évaluation du **Rag uniquement**, mettez dans le fichier `utils/config.py` la variable **'DATABASE_STATUS' à 0**
et **lancez le script 'utils/indexer.py' pour indexer tous les documents**. Puis lancez le script d'évaluation :
```bash
sudo systemctl start postgresql
python evaluate_ragas.py
```
Ce script va :
1. Tokenizer/vectoriser les questions d'évaluation avec Mistral Embedding
2. Interroger l'index FAISS pour récupérer les k=5 chunks les plus pertinents
3. Soumettre le prompt final au modèle llm de Mistral pour générer une réponse
4. A l'aide des réponses générées, des contextes récupérés et des questions d'évaluation, calculer les métriques
(Context Precision, Context Recall, Answer Relevancy et Faithfulness)
5. Sauvegarder les résultats d'évaluation dans un fichier CSV `Ragas_results/ragas_results_initial.csv`
**Note** :
- Une fois avoir lancé 3 évaluations sur le Rag ou Rag+SQL, vous pouvez visualiser les résultats d'évaluation dans le Jupyter Notebook `Notebook_Eval_Ragas.ipynb`.
- Si vous voulez optimiser les performances du Rag ou Rag+SQL, pensez à supprimer les fichiers dans le dossier `Ragas_results/` avant de relancer une nouvelle évaluation...
Si vous souhaitez faire **l'évaluation du Rag et Agent SQL**, mettez dans le fichier `utils/config.py` la variable **'DATABASE_STATUS' à 1**
et **lancez le script 'utils/indexer.py' pour indexer sans les documents Excel**. Par contre, vous devez **lancer le script
'utils/load_excel_to_db.py' pour charger les données Excel dans la base de données PostgreSQL.**
Puis lancez le script d'évaluation :
```bash
sudo systemctl start postgresql
python evaluate_ragas.py
```
Ce script va :
1. Tokenizer/vectoriser les questions d'évaluation avec Mistral Embedding
2. Pour chaque question d'évaluation, déterminer à l'aide du llm si une recherche RAG est nécessaire ou si une requête SQL doit être construite
3. Si une recherche RAG est nécessaire, interroger l'index FAISS pour récupérer les k=5 chunks les plus pertinents
3. Si une requête SQL doit être construite, utiliser l'outil de traduction de requêtes en SQL pour construire la requête SQL correspondante et l'exécuter sur la base de données PostgreSQL
4. Soumettre le prompt final au modèle llm de Mistral pour générer une réponse
5. A l'aide des réponses générées, des contextes récupérés (RAG) et des questions d'évaluation, calculer les métriques (Context Precision, Context Recall, Answer Relevancy et Faithfulness)
6. Sauvegarder les résultats d'évaluation dans un fichier CSV `Ragas_results/ragas_results_final.csv`
**Note** :
- Une fois avoir lancé 3 évaluations sur le Rag ou Rag+SQL, vous pouvez visualiser les résultats d'évaluation dans le Jupyter Notebook `Notebook_Eval_Ragas.ipynb`.
- Si vous voulez optimiser les performances du Rag ou Rag+SQL, pensez à supprimer les fichiers dans le dossier `Ragas_results/` avant de relancer une nouvelle évaluation...
### 5. Lancer l'application
```bash
sudo systemctl start postgresql
streamlit run MistralChat.py
```
L'application sera accessible à l'adresse http://localhost:8501 dans votre navigateur.
**Note** :
- Pour une utilisation en mode RAG uniquement, assurez-vous que la variable `DATABASE_STATUS` dans `utils/config.py` est définie à 0 et que l'indexation a été réalisée avec tous les documents (y compris les Excel).
- Pour une utilisation en mode RAG + Agent SQL, assurez-vous que la variable `DATABASE_STATUS` dans `utils/config.py` est définie à 1, que l'indexation a été réalisée sans les documents Excel et que les données Excel ont été chargées dans la base SQL.
## Modules principaux
### `utils/data_loader.py`
Extraction et prétraitement des documents pour l'indexation :
- Chargement de documents multi-formats (PDF, DOCX, XLSX, CSV, JSON, TXT)
- Nettoyage du texte (suppression des feuilles avec trop peu de caractères, normalisation des espaces)
- Découpage en chunks avec chevauchement configurable
- Préparation des données pour la vectorisation
### `utils/langgraph_app.py`
Routeur d'aiguillage entre le RAG et l'agent SQL :
- Analyse de la requête utilisateur pour déterminer la source à interroger
- Orchestration du pipeline RAG ou SQL via LangGraph
- Retour de la réponse finale du modèle Mistral
### `utils/sql_tool.py`
Construction et exécution de requêtes SQL :
- Traduction des questions en langage naturel vers du SQL
- Exécution des requêtes sur la base de données PostgreSQL
- Retour des résultats structurés
### `utils/vector_store.py`
Gère l'index vectoriel FAISS et la recherche sémantique :
- Chunking des documents
- Génération des embeddings avec Mistral
- Création et interrogation de l'index FAISS
## Personnalisation
Vous pouvez personnaliser l'application en modifiant les paramètres dans `utils/config.py` :
- Modèles Mistral utilisés
- Taille des chunks et chevauchement
- Nombre de documents renvoyés par le RAG
- Température et Top-p pour la génération de réponses
- les prompts utilisés pour le RAG et l'agent SQL
- etc.
## Déploiement sur HuggingFace Spaces
Cette application est déployable en un seul **Docker Space** qui embarque à la fois le serveur PostgreSQL et le dashboard Streamlit.
### Architecture du conteneur HF Spaces
```
┌─────────────────────────────────────────┐
│ HF Docker Space │
│ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ PostgreSQL │ │ Streamlit │ │
│ │ port 5432 │◄───│ port 7860 │ │
│ │ (interne) │ │ (HF exposé) │ │
│ └─────────────┘ └─────────────────┘ │
│ │
│ start.sh : init PG → démarre PG → exec │
│ streamlit │
└─────────────────────────────────────────┘
```
### Fichiers ajoutés pour HF Spaces
| Fichier | Rôle |
|---------|------|
| `Dockerfile` | Image combinée PostgreSQL + Streamlit (port 7860) |
| `start.sh` | Init cluster PG, création schéma/utilisateurs, démarrage des services |
### Procédure de déploiement
1. **Créer un nouveau Space** sur [huggingface.co/spaces](https://huggingface.co/spaces) :
- SDK : **Docker**
- Visibilité : Public ou Private
2. **Pousser le dépôt** vers le Space HF :
```bash
# Ajouter le remote HF
git remote add hf https://huggingface.co/spaces/<VOTRE_USERNAME>/<NOM_DU_SPACE>
git push hf main
```
3. **Configurer les Secrets** dans *Settings → Repository secrets* :
| Secret | Description |
|--------|-------------|
| `MISTRAL_API_KEY` | Clé API Mistral (obligatoire) |
| `POSTGRES_PASSWORD` | Mot de passe du superutilisateur PostgreSQL `admin` |
| `PG_USER_1_PASSWORD` | Mot de passe de l'utilisateur read-only `user_1` |
| `LOGFIRE_TOKEN` | Token Logfire (optionnel) |
4. **Attendre le build** (~3-5 min) : HF Spaces construit l'image et démarre les services automatiquement.
> ⚠️ **Persistance des données** : HF Spaces (tier gratuit) ne garantit pas la persistance des volumes. Les données PostgreSQL sont recréées à chaque redémarrage du Space via `start.sh`. Pour la persistance, utilisez le [stockage persistant HF](https://huggingface.co/docs/hub/spaces-storage) ou un service PostgreSQL externe (ex. [Supabase](https://supabase.com), [Neon](https://neon.tech)).
---