Back to .md Directory

Partie 2 : Pipeline RAG

Guides a student through forking, cloning, Dockerizing, and running a RAG chatbot with Streamlit, ChromaDB, and Google Gemini.

May 2, 2026
0 downloads
4 views
ai llm rag eval gemini
View source

What this file does

Guides a student through forking, cloning, Dockerizing, and running a RAG chatbot with Streamlit, ChromaDB, and Google Gemini.

When to use it

  • Learning to containerize a RAG application with Docker Compose
  • Setting up a local MLOps pipeline with hot reload for document updates
  • Practicing DevOps workflows on a pre-built AI project
  • Understanding the end-to-end RAG pipeline from ingestion to query

Assumes this stack

Python 3.9DockerDocker ComposeStreamlitChromaDBGoogle Gemini

Partie 2 : Pipeline RAG

Objectif

Mettre en pratique la conteneurisation et l'orchestration d'une application de Génération Augmentée par Récupération (RAG) à l'aide de Docker. Ce TP vous permettra de comprendre comment déployer une application d'intelligence artificielle moderne en utilisant les meilleures pratiques DevOps.

Structure des dossiers et fichiers

AIops-RAG/
├── app/
│   ├── main.py                      # Point d'entrée principal de l'application
│   ├── data/                        # Dossier des documents sources
│   │   ├── DevOps_cours.txt         # Informations sur le cours DevOps
│   │   ├── ensa_about.txt           # Description de l'ENSA
│   │   ├── ensa_programs.md         # Programmes d'études (format Markdown)
│   │   └── student_life.txt         # Vie étudiante et activités
│   ├── chroma_db/                   # Base de données vectorielle (générée)
│   │   ├── chroma.sqlite3           # Stockage SQLite des métadonnées
│   │   └── index/                   # Index de recherche vectorielle
│   └── utils/                       # Modules utilitaires
│       ├── chat_interface.py        # Interface utilisateur Streamlit
│       ├── embeddings.py            # Gestion des embeddings (vecteurs)
│       └── rag_pipeline.py          # Logique du pipeline RAG
├── docker-compose.yml               # Configuration d'orchestration Docker
├── Dockerfile                       # Instructions de construction de l'image
├── requirements.txt                 # Dépendances Python
├── .env.example                     # Modèle de fichier d'environnement
├── .env                             # Variables d'environnement (clé API)
└── TP.md                            # Documentation du TP

Qu'est-ce que le RAG ?

RAG (Retrieval-Augmented Generation) est une technique d'IA qui combine :

  • Récupération : Recherche d'informations pertinentes dans une base de données
  • Génération : Utilisation d'un modèle de langage (LLM) pour créer des réponses contextuelles

Avantages du RAG :

  • Réduit les hallucinations du modèle
  • Permet de travailler avec des données privées/spécifiques
  • Plus économique que le fine-tuning complet
  • Facilite la mise à jour des connaissances

Pré-requis

  • Docker Desktop installé (Télécharger)
    • Pourquoi ? Permet de créer des environnements isolés et reproductibles
  • Clé API Google Gemini (À obtenir ici)
    • Pourquoi ? Accéder au modèle de langage Gemini pour la génération de texte

Étape 1 : Acquérir le Projet

1.1 Fork du dépôt GitHub

Action : Dupliquer le dépôt sur votre profil GitHub

  1. Rendez-vous sur le dépôt original
  2. Cliquez sur le bouton "Fork" en haut à droite
  3. Sélectionnez votre compte GitHub comme destination

Pourquoi forker ?

  • Vous obtenez votre propre copie du projet
  • Vous pouvez modifier sans affecter l'original
  • Facilite la contribution et le suivi de vos modifications

1.2 Cloner le dépôt localement

Outil utilisé : Git (système de contrôle de version)

git clone https://github.com/youssef-elkahlaoui/AIops_tp.git
cd AIops_tp

Explication des commandes :

  • git clone : Télécharge l'intégralité du dépôt sur votre machine
  • cd AIops_tp : Se déplace dans le répertoire du projet

Qu'est-ce qui est téléchargé ?

  • Le code source de l'application
  • Les fichiers de configuration Docker
  • Les données d'exemple
  • L'historique Git complet

1.3 Configuration de la clé API

Étape 1 : Créer le fichier d'environnement

cp .env.example .env

Pourquoi utiliser un fichier .env ?

  • Sépare les secrets du code source
  • Évite d'exposer les clés API dans Git
  • Facilite la configuration pour différents environnements (dev, prod)

Étape 2 : Insérer votre clé API

Ouvrez le fichier .env et modifiez-le :

GOOGLE_API_KEY=AIzaSy... (votre clé obtenue depuis Google AI Studio)

Sécurité :

  • ⚠️ Ne commitez JAMAIS le fichier .env dans Git
  • Le fichier .gitignore doit contenir .env pour éviter cela
  • Utilisez des variables d'environnement en production

Étape 2 : Conditionnement Docker

2.1 Qu'est-ce que Docker ?

Docker est une plateforme de conteneurisation qui permet de :

  • Empaqueter une application avec toutes ses dépendances
  • Garantir un fonctionnement identique sur tous les environnements
  • Isoler l'application du système hôte

Concepts clés :

  • Image Docker : Modèle immuable contenant l'application et ses dépendances
  • Conteneur : Instance en cours d'exécution d'une image
  • Dockerfile : Fichier de recette pour construire une image

2.2 Analyse du Dockerfile

Le fichier Dockerfile est déjà présent dans le projet. Examinez son contenu ligne par ligne :

DirectiveFonctionExplication détaillée
FROM python:3.9-slimImage de baseUtilise Python 3.9 dans une version légère (sans paquets inutiles), réduit la taille de l'image finale
WORKDIR /appRépertoire de travailDéfinit /app comme dossier principal où toutes les commandes seront exécutées
RUN apt-get update && apt-get install -y build-essentialDépendances systèmeInstalle les outils de compilation nécessaires pour ChromaDB (gcc, g++, make)
COPY requirements.txt .Transfert des dépendancesCopie uniquement le fichier de dépendances en premier (optimise le cache Docker)
RUN pip install --no-cache-dir -r requirements.txtInstallation PythonInstalle tous les packages Python nécessaires sans garder le cache (réduit la taille)
COPY . .Transfert du code sourceCopie tout le code de l'application dans le conteneur
EXPOSE 8501Exposition du portIndique que Streamlit écoute sur le port 8501 (documentation, pas de sécurité réelle)
CMD ["streamlit", "run", "app/main.py", "--server.address=0.0.0.0"]Commande de démarrageLance l'application Streamlit au démarrage du conteneur

2.3 Pourquoi cet ordre spécifique ?

Optimisation du cache Docker :

  1. Les couches qui changent rarement (image de base, dépendances système) sont en premier
  2. requirements.txt est copié avant le code source
  3. Le code source (qui change fréquemment) est copié en dernier

Avantage : Si vous modifiez seulement le code, Docker réutilise les couches précédentes (gain de temps considérable)

2.4 Construction manuelle (optionnelle)

Pour comprendre le processus, vous pouvez construire l'image manuellement :

docker build -t rag-app:latest .

Explication :

  • docker build : Commande de construction d'image
  • -t rag-app:latest : Nomme l'image "rag-app" avec le tag "latest"
  • . : Utilise le Dockerfile du répertoire courant

Processus de construction :

  1. Docker lit le Dockerfile
  2. Exécute chaque instruction dans l'ordre
  3. Crée une couche intermédiaire pour chaque instruction
  4. Produit l'image finale

Étape 3 : Gestion avec Docker Compose

3.1 Qu'est-ce que Docker Compose ?

Docker Compose est un outil d'orchestration qui permet de :

  • Définir des applications multi-conteneurs
  • Gérer les configurations via un fichier YAML
  • Démarrer tous les services avec une seule commande
  • Gérer les réseaux et volumes automatiquement

Pourquoi utiliser Docker Compose ?

  • Simplifie la gestion des conteneurs
  • Configuration reproductible
  • Idéal pour les environnements de développement
  • Facilite la collaboration en équipe

3.2 Analyse du docker-compose.yml

Le fichier docker-compose.yml contient la configuration complète de l'application. Éléments typiques :

version: "3.8" # Version du format Compose
services:
  rag-app: # Nom du service
    build: . # Construit depuis le Dockerfile local
    ports:
      - "8501:8501" # Mappe le port hôte:conteneur
    volumes:
      - ./app:/app/app # Monte le code pour hot-reload
    env_file:
      - .env # Charge les variables d'environnement
    restart: unless-stopped # Redémarre automatiquement en cas d'erreur

Explication des paramètres :

  • build : Indique où trouver le Dockerfile
  • ports : Permet d'accéder à l'application depuis l'hôte
  • volumes : Synchronise les fichiers entre hôte et conteneur (permet les modifications à chaud)
  • env_file : Charge les variables d'environnement depuis .env
  • restart : Politique de redémarrage automatique

3.3 Démarrage de l'application

Commande principale :

docker-compose up --build

Décomposition de la commande :

  • docker-compose up : Lance tous les services définis
  • --build : Force la reconstruction des images (utile après modification du code)

Processus détaillé :

  1. Lecture du docker-compose.yml : Docker Compose analyse la configuration
  2. Construction de l'image : Exécute le Dockerfile
    • Téléchargement de l'image Python de base (~50 MB)
    • Installation des dépendances système (~100 MB)
    • Installation des packages Python (~200 MB)
    • Durée totale : 3-5 minutes la première fois
  3. Création du réseau : Réseau Docker isolé pour le projet
  4. Montage des volumes : Synchronisation des dossiers
  5. Démarrage du conteneur : Lance Streamlit
  6. Affichage des logs : Montre la sortie en temps réel

Indicateurs de réussite :

✓ Network aiops-rag_default  Created
✓ Container aiops-rag-app    Started
You can now view your Streamlit app in your browser.
Local URL: http://localhost:8501

3.4 Accès à l'interface

URL : http://localhost:8501

Que se passe-t-il ?

  1. Votre navigateur envoie une requête au port 8501
  2. Docker redirige vers le conteneur
  3. Streamlit traite la requête et renvoie l'interface web

Vérifications :

  • ✓ La page se charge correctement
  • ✓ L'interface Streamlit s'affiche
  • ✓ Le panneau latéral est visible

3.5 Commandes Docker Compose utiles

CommandeActionQuand l'utiliser
docker-compose up -dLance en arrière-planPour continuer à utiliser le terminal
docker-compose downArrête et supprime les conteneursPour nettoyer l'environnement
docker-compose logs -fAffiche les logs en temps réelPour déboguer
docker-compose restartRedémarre les servicesAprès modification de .env
docker-compose exec rag-app bashOuvre un terminal dans le conteneurPour explorer l'intérieur

Arrêt de l'application :

  • Méthode 1 : Ctrl + C dans le terminal
  • Méthode 2 : docker-compose down dans un autre terminal

Étape 4 : Vérification de la Chaîne MLOps

4.1 Qu'est-ce qu'un pipeline MLOps ?

MLOps (Machine Learning Operations) applique les principes DevOps au machine learning :

  • Automatisation du flux de données
  • Reproductibilité des résultats
  • Déploiement continu des modèles
  • Monitoring et maintenance

Notre pipeline RAG comporte 4 phases essentielles qui transforment des documents bruts en un système de question-réponse intelligent.

4.2 Paramétrage Initial

Actions à effectuer :

  1. Ouvrir l'interface : http://localhost:8501

  2. Localiser le panneau latéral (sidebar à gauche)

    • Si masqué, cliquez sur la flèche en haut à gauche
  3. Entrer la clé API Google

    • Collez votre clé dans le champ prévu
    • Format : AIzaSy... (environ 39 caractères)
  4. Lancer la construction : Cliquez sur "Rebuild Vector Store"

Pourquoi ce bouton ?

  • Initialise la base de données vectorielle
  • Traite tous les documents du dossier app/data/
  • Crée les embeddings nécessaires pour la recherche sémantique

4.3 Phase 1 : Ingestion de Données

Objectif : Charger les documents sources dans le système

Outil utilisé : LangChain Document Loaders

  • TextLoader pour les fichiers .txt
  • UnstructuredMarkdownLoader pour les fichiers .md

Processus détaillé :

  1. Scan du dossier : Le système parcourt app/data/
  2. Détection des fichiers : Identifie les formats supportés
  3. Lecture du contenu : Charge chaque fichier en mémoire
  4. Création de documents : Chaque fichier devient un objet Document avec :
    • page_content : Le texte du fichier
    • metadata : Nom du fichier, chemin, type

Fichiers traités :

  • DevOps_cours.txt : Informations sur le cours DevOps
  • ensa_about.txt : Description de l'ENSA
  • ensa_programs.md : Liste des programmes d'études
  • student_life.txt : Vie étudiante et activités

Résultat attendu :

Loaded 4 documents from app/data/
Total characters: ~5000

Points de vigilance :

  • Les fichiers doivent être en UTF-8
  • Les noms de fichiers sans caractères spéciaux
  • Taille maximale recommandée : 5 MB par fichier

4.4 Phase 2 : Segmentation de Texte (Chunking)

Objectif : Diviser les documents en fragments gérables

Outil utilisé : RecursiveCharacterTextSplitter de LangChain

Pourquoi segmenter ?

  • Les modèles ont des limites de tokens
  • Améliore la précision de la recherche
  • Réduit le coût des API (moins de tokens traités)
  • Permet de retrouver des passages spécifiques

Paramètres de segmentation :

chunk_size=1000        # Taille maximale d'un fragment (en caractères)
chunk_overlap=200      # Chevauchement entre fragments

Pourquoi le chevauchement ?

  • Évite de couper des informations importantes
  • Maintient le contexte entre les chunks
  • Améliore la qualité des réponses

Processus :

  1. Découpage intelligent :

    • Tente de couper aux sauts de paragraphe
    • Sinon aux points
    • Sinon aux virgules
    • En dernier recours : coupe au caractère
  2. Préservation du contexte :

    • Les 200 derniers caractères d'un chunk apparaissent dans le suivant
    • Les métadonnées sont conservées

Résultat attendu :

Split into 45 chunks
Average chunk size: 850 characters

Exemple de chunk :

Chunk 1: "L'ENSA Al Hoceima a été établie en 2008..."
Chunk 2: "...établie en 2008. Elle offre plusieurs programmes..."

4.5 Phase 3 : Création d'Embeddings

Objectif : Transformer le texte en vecteurs numériques

Qu'est-ce qu'un embedding ?

  • Représentation mathématique du sens d'un texte
  • Vecteur de nombres (ex: [0.23, -0.45, 0.67, ...])
  • Les textes similaires ont des vecteurs proches

Outil utilisé : SentenceTransformers avec le modèle all-MiniLM-L6-v2

Caractéristiques du modèle :

  • Dimensions : 384 (taille du vecteur)
  • Langue : Multilingue (français, anglais, arabe)
  • Taille : ~80 MB
  • Performance : Excellent rapport qualité/vitesse

Processus :

  1. Chargement du modèle : Téléchargé depuis Hugging Face (première fois uniquement)
  2. Encodage des chunks :
    • Chaque chunk est transformé en vecteur de 384 dimensions
    • Traitement par batch pour optimiser la vitesse
  3. Normalisation : Les vecteurs sont normalisés pour la recherche par similarité cosinus

Exemple simplifié :

Texte: "L'ENSA offre des formations en génie informatique"
→ Embedding: [0.234, -0.456, 0.678, ..., 0.123]  (384 valeurs)

Pourquoi ce modèle ?

  • ✓ Rapide (environ 1000 chunks/seconde)
  • ✓ Fonctionne sans connexion internet après téléchargement
  • ✓ Gratuit et open-source
  • ✓ Bonne qualité pour le français

Résultat attendu :

Generated 45 embeddings
Dimensions: 384
Model: all-MiniLM-L6-v2

4.6 Phase 4 : Sauvegarde Vectorielle

Objectif : Stocker les embeddings dans une base de données optimisée

Outil utilisé : ChromaDB

Qu'est-ce que ChromaDB ?

  • Base de données vectorielle open-source
  • Optimisée pour la recherche de similarité
  • Persistance sur disque
  • Interface Python simple

Processus de stockage :

  1. Initialisation de ChromaDB :

    • Création du dossier app/chroma_db/ si inexistant
    • Configuration de la collection "rag_collection"
  2. Insertion des données :

    • Chaque chunk est stocké avec :
      • Son embedding (vecteur)
      • Son contenu textuel
      • Ses métadonnées (source, page, etc.)
      • Un ID unique
  3. Création d'index :

    • ChromaDB construit des index HNSW (Hierarchical Navigable Small World)
    • Permet des recherches ultra-rapides (millisecondes)

Structure de stockage :

chroma_db/
├── chroma.sqlite3        # Base de données SQLite
├── index/                # Index de recherche
└── metadata/             # Métadonnées

Avantages de ChromaDB :

  • ✓ Recherche rapide même avec des millions de vecteurs
  • ✓ Persistance locale (pas besoin de serveur)
  • ✓ Mise à jour incrémentale (ajouter sans tout recréer)
  • ✓ Gratuit et sans limites

Résultat attendu :

💾 Vector store saved
Location: app/chroma_db/
Total documents: 45
Status: Ready for queries

4.7 Récapitulatif du pipeline complet

Flux de données :

📄 Documents (.txt, .md)
    ↓ Phase 1: Ingestion
📚 Documents chargés en mémoire
    ↓ Phase 2: Chunking
✂️ Fragments de texte (1000 chars)
    ↓ Phase 3: Embeddings
🔢 Vecteurs numériques (384 dimensions)
    ↓ Phase 4: Stockage
💾 ChromaDB (recherche vectorielle)
    ↓ Utilisation
💬 Chatbot RAG opérationnel

Temps d'exécution typique :

  • Phase 1 : < 1 seconde
  • Phase 2 : < 1 seconde
  • Phase 3 : 5-10 secondes (selon nombre de chunks)
  • Phase 4 : 2-3 secondes
  • Total : ~15 secondes pour le jeu de données fourni

4.8 Évaluer le Chatbot

Objectif : Tester la qualité du système RAG avec des questions variées

Comment fonctionne une requête ?

  1. Saisie de la question : L'utilisateur tape dans le chat
  2. Embedding de la question : Transformation en vecteur (384D)
  3. Recherche vectorielle : ChromaDB trouve les chunks les plus similaires
  4. Sélection du contexte : Les 3 meilleurs chunks sont récupérés
  5. Construction du prompt : Combinaison du contexte + question
  6. Appel à Gemini : Le LLM génère la réponse
  7. Affichage : La réponse apparaît dans l'interface

Tests à effectuer :

Test 1 : Question factuelle simple

Question : "Quand l'ENSA Al Hoceima a-t-elle été établie ?"

Réponse attendue : "L'ENSA Al Hoceima a été établie en 2008."

Ce test valide :

  • ✓ La recherche vectorielle fonctionne
  • ✓ Le chunk contenant la date est bien retrouvé
  • ✓ Gemini extrait correctement l'information

Test 2 : Question nécessitant agrégation

Question : "Quels sont les clubs étudiants répertoriés ?"

Réponse attendue : Une liste des clubs mentionnés dans student_life.txt

Ce test valide :

  • ✓ Capacité à retrouver plusieurs informations
  • ✓ Structuration de la réponse (liste)
  • ✓ Exhaustivité de la recherche

Test 3 : Question en anglais

Question : "What programming languages are taught?"

Réponse attendue : Liste des langages de programmation du cursus

Ce test valide :

  • ✓ Support multilingue du modèle d'embeddings
  • ✓ Capacité de Gemini à répondre en anglais
  • ✓ Recherche cross-lingue (question EN, docs FR)

Analyse de la qualité :

Bon indicateurs :

  • ✅ Réponse précise et concise
  • ✅ Information directement extraite des documents
  • ✅ Pas d'invention d'informations (hallucination)
  • ✅ Citation implicite de la source

Mauvais indicateurs :

  • ❌ Réponse générique ("Je ne sais pas")
  • ❌ Information inventée non présente dans les docs
  • ❌ Réponse hors sujet
  • ❌ Mélange de sources contradictoires

Comprendre les limites :

Si le chatbot répond "Je n'ai pas cette information" :

  1. Vérifiez que le document contient bien l'info
  2. Reformulez la question différemment
  3. Chunking : L'info est peut-être coupée entre 2 chunks

Panel de test avancé :

Type de questionExempleDifficulté
Factuelle"Quelle est la date de fondation ?"Facile
Agrégation"Liste tous les programmes"Moyenne
Comparaison"Quelle est la différence entre ..."Difficile
Temporelle"Quand se déroule le cours X ?"Facile
Négation"Quels clubs ne sont pas mentionnés ?"Très difficile

Étape 5 : Mise à Jour Instantanée (Hot Reload)

5.1 Qu'est-ce que le Hot Reload ?

Hot Reload (rechargement à chaud) est une fonctionnalité DevOps qui permet :

  • Mise à jour de l'application sans redémarrage complet
  • Synchronisation automatique des fichiers modifiés
  • Gain de temps considérable en développement

Comment ça fonctionne ici ?

  1. Docker monte le dossier app/ local dans le conteneur
  2. Streamlit détecte les changements de fichiers
  3. Le système recharge automatiquement les données

Pourquoi c'est important ?

  • Itération rapide sur les données
  • Pas besoin de docker-compose down/up
  • La base vectorielle se met à jour automatiquement
  • Environnement de développement agile

5.2 Objectif de ce test

Démontrer que la chaîne MLOps peut intégrer de nouvelles données sans nécessiter :

  • Reconstruction de l'image Docker
  • Redémarrage du conteneur
  • Intervention manuelle complexe

Scénario réel : Un professeur ajoute des informations de dernière minute

5.3 Ajout d'un Nouveau Document

Étape 1 : Créer le fichier app/data/DevOps_cours.txt

Emplacement : c:\Users\jozef\OneDrive\Desktop\AIops-RAG\app\data\DevOps_cours.txt

Méthode 1 - Via l'éditeur :

  1. Ouvrir VS Code
  2. Naviguer vers app/data/
  3. Créer un nouveau fichier : DevOps_cours.txt
  4. Coller le contenu ci-dessous
  5. Sauvegarder (Ctrl+S)

Méthode 2 - Via PowerShell :

cd app\data
New-Item -Path "DevOps_cours.txt" -ItemType File
notepad DevOps_cours.txt

Contenu à insérer :

Le cours de DevOps est dispensé le mercredi matin à 9 h.
Le professeur responsable est Dr. Bahri.
Les étudiants apprennent Docker, Kubernetes et CI/CD.
Le TP pratique couvre la conteneurisation d'applications.

Pourquoi ce contenu ?

  • Information factuelle simple (date, heure)
  • Nom propre spécifique (Dr. Bahri)
  • Termes techniques (Docker, Kubernetes)
  • Facilement vérifiable dans les réponses

5.4 Constater la Détection Automatique

Mécanisme de surveillance :

Le système utilise un watchdog (chien de garde) qui :

  1. Surveille le dossier app/data/ en permanence
  2. Calcule un hash (empreinte numérique) du contenu
  3. Compare avec le hash précédent
  4. Déclenche le rebuild si différence détectée

Processus automatique :

📁 Fichier ajouté/modifié
    ↓
🔍 Détection du changement (hash différent)
    ↓
⚠️ Alerte "Data folder changes detected!"
    ↓
🔄 Rebuild automatique du vector store
    ↓
✅ Système à jour

Indicateurs visuels :

  1. Actualisez la page dans le navigateur (F5)

  2. Message attendu dans le panneau latéral :

    ⚠️ Data folder changes detected!
    The vector store needs to be rebuilt.
    
  3. Bouton activé : "Rebuild Vector Store" devient cliquable

  4. Cliquez sur le bouton pour lancer le rebuild

  5. Progression : Les 4 phases se relancent

    • ✓ Phase 1 : Détection de 5 documents (au lieu de 4)
    • ✓ Phase 2 : Nouveau nombre de chunks
    • ✓ Phase 3 : Embeddings recalculés
    • ✓ Phase 4 : ChromaDB mis à jour

Temps de rebuild : 10-20 secondes

Optimisation possible :

  • Version avancée : Ne traiter que les nouveaux fichiers (delta update)
  • Version actuelle : Rebuild complet (plus simple, plus fiable)

5.5 Vérification technique (optionnelle)

Inspecter les logs Docker :

docker-compose logs -f rag-app

Messages attendus :

[INFO] File watcher detected changes
[INFO] Starting vector store rebuild...
[INFO] Loaded 5 documents (1 new)
[INFO] Generated 52 chunks
[INFO] Vector store updated successfully

5.6 Interroger la Nouvelle Donnée

Test 1 : Question temporelle

Question : "Quand est prévu le cours de DevOps ?"

Réponse attendue : "Le cours de DevOps est prévu le mercredi matin à 9h."

Validation :

  • ✅ Le système a bien indexé le nouveau fichier
  • ✅ La recherche vectorielle fonctionne sur les nouvelles données
  • ✅ L'information temporelle est correctement extraite

Analyse : Si la réponse est incorrecte ou absente :

  1. Vérifiez que le fichier est bien dans app/data/
  2. Confirmez que le rebuild a été effectué
  3. Regardez les logs pour d'éventuelles erreurs

Test 2 : Question sur personne

Question : "Qui est le professeur responsable du cours de DevOps ?"

Réponse attendue : "Le professeur responsable du cours de DevOps est Dr. Bahri."

Validation :

  • ✅ Extraction de nom propre fonctionnelle
  • ✅ Association correcte (cours ↔ professeur)
  • ✅ Formulation naturelle de la réponse

Test 3 : Question technique

Question : "Quelles technologies sont enseignées dans le cours de DevOps ?"

Réponse attendue : "Docker, Kubernetes et CI/CD"

Validation :

  • ✅ Énumération correcte
  • ✅ Pas d'ajout d'informations non présentes
  • ✅ Formatage lisible

5.7 Comprendre l'avantage du volume Docker

Sans volume Docker :

# Mauvaise pratique
services:
  rag-app:
    build: .
    # Pas de volume
  • ❌ Modifications de code non prises en compte
  • ❌ Nécessite docker-compose up --build à chaque fois
  • ❌ Perte de temps (3-5 minutes par rebuild)

Avec volume Docker (configuration actuelle) :

# Bonne pratique
services:
  rag-app:
    build: .
    volumes:
      - ./app:/app/app # Synchronisation bidirectionnelle
  • ✅ Modifications instantanées
  • ✅ Workflow de développement fluide
  • ✅ Rebuild uniquement si changement de dépendances

Cas d'usage réels :

  • Développement : Itération rapide sur les données/code
  • Démo : Ajout de données devant le client
  • Production : ⚠️ À désactiver (stabilité requise)

5.8 Expérimentations suggérées

Exercice 1 : Modifier un fichier existant

  1. Éditez app/data/ensa_about.txt
  2. Ajoutez une phrase
  3. Observez la détection automatique
  4. Posez une question sur la nouvelle info

Exercice 2 : Supprimer un document

  1. Supprimez app/data/student_life.txt
  2. Rebuild le vector store
  3. Tentez une question sur les clubs
  4. Résultat : "Information non disponible"

Exercice 3 : Format Markdown

  1. Créez app/data/horaires.md
  2. Utilisez la syntaxe Markdown (titres, listes)
  3. Vérifiez que le système traite correctement le formatage

Limites à connaître :

  • Formats supportés : .txt, .md uniquement
  • Encodage : UTF-8 obligatoire
  • Taille : Éviter les fichiers > 5 MB
  • Noms : Pas de caractères spéciaux (é, à, ç, espaces)

🎯 Récapitulatif et Concepts Clés

Technologies et leur rôle

TechnologieRôleAlternatives possibles
DockerConteneurisationPodman, LXC
Docker ComposeOrchestrationKubernetes (pour production)
Python 3.9Langage principalPython 3.10+, 3.11
StreamlitFramework webGradio, Flask, FastAPI
LangChainFramework RAGLlamaIndex, Haystack
ChromaDBBase vectoriellePinecone, Weaviate, Milvus, FAISS
SentenceTransformersModèle d'embeddingsOpenAI Ada-002, Cohere
Google GeminiLLM génératifGPT-4, Claude, Llama

Concepts DevOps appliqués

  1. Infrastructure as Code : Dockerfile + docker-compose.yml
  2. Immutabilité : Conteneurs identiques sur tous les environnements
  3. Isolation : Application séparée du système hôte
  4. Reproductibilité : Build identique partout
  5. Hot Reload : Développement itératif rapide
  6. Surveillance : Détection automatique des changements
  7. Logs centralisés : docker-compose logs

Flux d'une requête utilisateur

1. 💬 Utilisateur : "Quand l'ENSA a-t-elle été créée ?"
           ↓
2. 🔢 Embedding : [0.23, -0.45, 0.67, ...] (384D)
           ↓
3. 🔍 ChromaDB : Recherche par similarité cosinus
           ↓
4. 📄 Top 3 chunks :
   - "L'ENSA Al Hoceima établie en 2008..." (score: 0.92)
   - "Histoire de l'établissement..." (score: 0.87)
   - "Création et développement..." (score: 0.81)
           ↓
5. 📝 Construction du prompt :
   Contexte: [chunks récupérés]
   Question: "Quand l'ENSA a-t-elle été créée ?"
   Instruction: Réponds précisément basé sur le contexte.
           ↓
6. 🤖 Gemini API : Génération de la réponse
           ↓
7. ✅ Réponse : "L'ENSA Al Hoceima a été créée en 2008."

Métriques de performance

Temps de réponse typique :

  • Embedding de la question : ~50 ms
  • Recherche vectorielle : ~10 ms
  • Appel API Gemini : 1-3 secondes
  • Total : 1-3 secondes

Coûts :

  • Embeddings locaux : Gratuit (SentenceTransformers)
  • ChromaDB : Gratuit (open-source)
  • Gemini API : ~15 requêtes gratuites/minute
  • Coût total pour ce TP : 0 €

Scalabilité :

  • Documents : Jusqu'à 10 000 sans problème
  • Requêtes simultanées : 10-50 (selon config serveur)
  • Pour plus : Passer à une architecture distribuée

🏃 Plan B : Exécution Locale (Sans Docker)

Quand utiliser cette méthode ?

  • ❌ Docker Desktop ne fonctionne pas
  • ❌ Problèmes de virtualisation (Hyper-V)
  • ❌ Ressources système limitées
  • ✅ Développement rapide et léger
  • ✅ Débogage approfondi nécessaire

Prérequis système

  • Python : Version 3.9, 3.10 ou 3.11 installée
  • Pip : Gestionnaire de packages Python
  • Git : Pour cloner le dépôt
  • Espace disque : ~2 GB (modèles + dépendances)

Installation pas à pas

Étape 1 : Vérifier Python

python --version

Résultat attendu : Python 3.9.x ou supérieur

Si Python n'est pas installé :

  1. Télécharger depuis python.org
  2. Cocher "Add Python to PATH" pendant l'installation
  3. Redémarrer PowerShell

Étape 2 : Créer un environnement virtuel

# Se placer dans le dossier du projet
cd c:\Users\jozef\OneDrive\Desktop\AIops-RAG

# Créer l'environnement virtuel
python -m venv venv

# Activer l'environnement (Windows)
.\venv\Scripts\Activate.ps1

Pourquoi un environnement virtuel ?

  • Isole les dépendances du projet
  • Évite les conflits avec d'autres projets Python
  • Facilite la gestion des versions de packages

Étape 3 : Installer les dépendances

# Mettre à jour pip
python -m pip install --upgrade pip

# Installer tous les packages requis
pip install -r requirements.txt

Packages installés (principaux) :

  • streamlit : Framework web
  • langchain : Framework RAG
  • chromadb : Base vectorielle
  • sentence-transformers : Modèle d'embeddings
  • google-generativeai : SDK Gemini

Temps d'installation : 3-5 minutes

Étape 4 : Configurer la clé API

# Copier le fichier d'exemple
copy .env.example .env

# Éditer avec notepad
notepad .env

Insérer votre clé :

GOOGLE_API_KEY=AIzaSy...

Étape 5 : Démarrer l'application

# Lancer Streamlit
python -m streamlit run app/main.py

Alternative :

streamlit run app/main.py

Sortie attendue :

You can now view your Streamlit app in your browser.

  Local URL: http://localhost:8501
  Network URL: http://192.168.1.x:8501

Étape 6 : Accéder à l'interface

Ouvrir http://localhost:8501 dans votre navigateur

📚 Pour aller plus loin

Documentation officielle :

Tutoriels avancés :

Communautés :


What's inside

5 numbered steps, 15 subsections, 8 code blocks, 3 test scenarios, 1 directory tree

Change this for your project

  • Replace https://github.com/youssef-elkahlaoui/AIops_tp.git with your own fork URL
  • Replace AIops-RAG/ folder name with your project's root directory name
  • Replace GOOGLE_API_KEY=AIzaSy... placeholder with your actual Gemini API key

Where it goes

Reference documentation for a retrieval pipeline. Keep with the ingestion or retrieval code it describes.

Worth borrowing

  • Mounting ./app:/app/app as a volume for hot reload during development
  • Using a watchdog hash comparison to auto-rebuild the vector store on data changes

Related Documents