8.8 KiB
Documentation Technique - Chatbot RAG Multi-Clients
Cette documentation explique le fonctionnement global de l'application de chatbot RAG (Retrieval-Augmented Generation) multi-tenants, ainsi que les concepts mathématiques des vecteurs et des embeddings utilisés pour la recherche sémantique.
1. Architecture Générale (RAG)
L'application utilise le pattern RAG (Retrieval-Augmented Generation). Contrairement à un chatbot classique qui s'appuie uniquement sur les connaissances générales d'un grand modèle de langage (LLM), le RAG permet d'injecter des données issues de documents propres à l'utilisateur (fichiers PDF, pages de sites web) directement dans le prompt du LLM pour garantir des réponses précises, sourcées et sans hallucinations.
graph TD
A[Utilisateur pose une question] --> B[Recherche Vectorielle]
B -->|Convertit la question en vecteur| C[Weaviate Cloud]
C -->|Retourne les segments de texte pertinents| D[Prompt RAG]
D -->|Construit le prompt : Contexte + Question| E[Mistral AI]
E -->|Génère la réponse finale| F[Retour à l'utilisateur]
Les Composants de l'Application :
- Frontend (Livewire & JS Widget) : Une interface de discussion moderne et réactive qui peut être intégrée sur n'importe quel site internet externe via une simple balise
<script>. - Backend (Laravel 11) : Gère le multi-tenancy (isolation des chatbots par client), l'orchestration des données, l'historique et les appels aux services tiers.
- Parser PDF (Python + PyMuPDF + Mistral Vision) : Un script Python haute fidélité qui extrait le texte en respectant la mise en page (colonnes, tableaux) et utilise un modèle de vision pour décrire les images et pictos.
- Base de Données Vectorielle (Weaviate Cloud) : Stocke et recherche les données textuelles sous forme de coordonnées mathématiques (vecteurs).
- LLM & Embeddings (Mistral AI) : Fournit le modèle d'embeddings pour vectoriser le texte et le modèle de langage (
mistral-small-latest) pour formuler les réponses.
2. Comment Fonctionnent les Vecteurs et les Embeddings ?
Qu'est-ce qu'un Embedding ?
Un embedding (ou plongement lexical) est la conversion d'un texte (un mot, une phrase ou un paragraphe) en une suite de nombres décimaux, appelée vecteur.
Par exemple, le modèle d'embedding de Mistral AI prend un texte et le transforme en un vecteur de 1024 dimensions (une liste de 1024 nombres comme [0.012, -0.045, 0.189, ...]).
La Représentation Spatiale
Imaginez un espace géométrique.
- Dans un espace à 2 dimensions (un plan
X, Y), on peut placer des points. - Dans notre espace d'embedding, nous avons 1024 dimensions.
La force de cette transformation est que le positionnement des vecteurs dépend du sens sémantique du texte. Des textes qui partagent le même sens ou traitent du même sujet se retrouvent géométriquement très proches les uns des autres dans cet espace multi-dimensionnel.
[Espace Sémantique Virtuel]
(Tri des déchets)
* "Bac jaune" (Technologie)
* "Recycler carton" * "Ordinateur portable"
* "Processeur silicium"
Dans ce schéma simplifié, les vecteurs de "Bac jaune" et "Recycler carton" sont proches, alors que "Ordinateur portable" est très éloigné de ces deux concepts.
La Recherche Sémantique (Similarité Cosinus)
Lorsque l'utilisateur pose une question (ex: "Où jeter mes boîtes en carton ?") :
- La question est convertie en vecteur (vecteur A).
- Weaviate compare ce vecteur A avec tous les vecteurs stockés dans la base de données (vecteurs B, C, D...).
- Il calcule l'angle entre les vecteurs à l'aide de la similarité cosinus. Plus le cosinus de l'angle est proche de 1, plus les sens sémantiques sont proches.
- Weaviate retourne instantanément les segments de texte (chunks) les plus proches, même si les mots exacts de la question ne figurent pas dans le document (ex: comprendre que "carton" est lié à "emballage").
3. Le Flux de Traitement Étape par Étape
Étape A : L'indexation des Données (Ingestion)
1. Pour les sites web :
Le crawler interne explore le site récursivement (limité au même domaine) pour récupérer le code HTML de chaque page. Le HTML est nettoyé des balises inutiles (scripts, styles, menus) pour ne garder que le contenu informatif.
2. Pour les PDF :
Le script parse_pdf.py extrait le texte en ordonnant les blocs de haut en bas et de gauche à droite (évitant le mélange de texte des PDF multicolonnes). Si l'option Vision AI est cochée :
- Les images du PDF sont extraites en mémoire.
- Elles sont encodées en Base64 et envoyées au modèle de vision de Mistral (
pixtral-12b-2409). - La description générée (ex: "Pictogramme montrant que les bouteilles en plastique vont dans le bac jaune") est insérée dans le texte à l'emplacement de l'image.
3. Découpage (Chunking) :
Le texte complet est découpé en segments (chunks) d'environ 800 caractères avec un chevauchement de 120 caractères. Le chevauchement garantit qu'aucune information n'est coupée au milieu d'une phrase importante.
4. Vectorisation et Stockage :
Chaque segment est envoyé à Mistral AI pour obtenir son vecteur d'embedding, puis stocké dans Weaviate avec les métadonnées suivantes :
content: Le texte brut du segment.source: L'URL ou le nom du fichier PDF d'origine.title: Le titre de la page ou de la section.chatbotId: L'identifiant unique du chatbot (pour cloisonner les données de chaque client).
Étape B : La Discussion (Génération)
[Question utilisateur]
│
▼
[Recherche Weaviate (Filtre par Chatbot ID)]
│
▼
[Extraction du Contexte sémantique]
│
▼
[Prompt injecté au LLM]
┌──────────────────────────────────────────────────────────┐
│ INSTRUCTIONS : Réponds uniquement avec le contexte. │
│ CONTEXTE : [Contenu du PDF GUIDE-PREVENTION-2025.pdf] │
│ QUESTION : Quels sont les horaires de Villeneuve ? │
└──────────────────────────────────────────────────────────┘
│
▼
[Génération Mistral AI]
│
▼
[Réponse structurée + Sources affichées]
- Réception de la question : L'utilisateur envoie un message depuis le widget.
- Recherche contextuelle : La question est vectorisée. Weaviate recherche les 4 segments les plus proches en filtrant strictement par le
chatbotIddu client pour éviter les fuites de données entre locataires (multi-tenancy). - Construction du prompt strict :
- Si des segments sont trouvés, ils sont insérés dans le prompt système comme contexte.
- Les instructions interdisent formellement au modèle d'utiliser ses connaissances globales si la réponse n'est pas dans le contexte.
- Appel LLM : Mistral AI génère la réponse finale en français.
- Affichage : Le widget affiche la réponse et ajoute un badge cliquable affichant la source (ex:
GUIDE-PREVENTION-2025.pdf) pour assurer une transparence totale envers l'utilisateur final.
4. Structure des Fichiers Clés
- parse_pdf.py : Script autonome Python d'analyse de PDF (PyMuPDF + Mistral Vision).
- WeaviateService.php : Gestion de la base vectorielle (création du schéma, indexation des vecteurs, recherche sémantique avec filtres GraphQL, et suppression).
- MistralService.php : Interfacage avec l'API Mistral (génération de réponses avec prompt système contraint RAG).
- DocumentIngestionService.php : Pipeline d'ingestion globale (crawl de site récursif, nettoyage HTML, exécution sécurisée du parser PDF).
- AdminDashboard.php & admin-dashboard.blade.php : Interface d'administration pour la configuration et l'indexation.
- Chatbot.php & chatbot.blade.php : Composant Livewire du widget de discussion de l'utilisateur.