Tutoriel : comment créer un chatbot RAG sur mesure facilement 

Tutoriel : comment créer un chatbot RAG sur mesure facilement  Un projet un peu technique à mettre en place, mais cela offre un bon aperçu de la construction à adopter.

On le sait, l’AI peut être victime d’hallucination. Elle peut aussi s’appuyer sur des connaissances générales, pas toujours fiables et pertinentes.  Créer un chatbot personnalisé avec RAG (retrieval-augmented generation) permet de résoudre ces deux problèmes majeurs.  Cela permet à l’IA de scruter les documents fournis (rapports, FAQ, manuels techniques, politiques internes...), de les comprendre et de les intégrer dans son modèle conversationnel. Cela offre une expérience utilisateur fluide et intuitive, avec un accès rapide aux informations recherchées. Les applications sont nombreuses. Un fabricant de matériels industriels peut par exemple fournir une assistance automatique basée sur ses manuels techniques.

Pour créer un chatbot personnalisé avec RAG, nous allons créer environnement virtuel, un dossier de projet, installer les dépendances et lancer l'application. Nous passons par une méthode un peu technique, mais qui doit s'adapter à un grand nombre de machines.

1. Créer un environnement Python pour le projet de chatbot

Nous téléchargeons Python 3.11.8 pour Windows (64-bit), à adapter selon votre machine. Dans Advanced Options, nous cochons les cases Create shortcuts for installed applications et  Add Python to environnement variables ;. 

Pour vérifier que Python et pip sont bien installés, nous ouvrons une nouvelle fenêtre PowerShell ou Invite de commandes et tapons les commandes :

# Vérifier Python
python --version
# Vérifier pip
pip --version
# Résultat attendu :
# Python 3.11.8
# pip 23.0.1 from C:\Users\...\AppData\Local\Programs\Python\Python311\lib\site-packages\pip

Cela devrait afficher les versions installées sans erreur.

Nous installons ensuite les Outils de Build C++. En effet, certaines bibliothèques Python sont écrites en C++ et ont besoin d'outils de compilation pour s'installer correctement sur Windows. Sans ces outils, nous recevrons une erreur lors de l'installation des dépendances. Nous allons sur : https://visualstudio.microsoft.com/fr/visual-cpp-build-tools/, cliquons sur "Télécharger Build Tools". Nous lançons l'installateur, sur l'onglet "Charges de travail", nous cochons la case "Développement Desktop en C++". Puis nous allons sur "Installer" en bas à droite. Nous vérifions l'installation sur PowerShell en tapant : cl.exe

Nous créons par la suite le projet et l’environnement virtuel. Dans Powershell nous écrivons :

# Allez à la racine de votre disque C: (ou un autre emplacement de votre choix)
cd C:\
# Créez le dossier du projet mkdir chatbot-rag-local
# Entrez dans le dossier du projet. C'est une étape cruciale.
cd chatbot-rag-local

Votre invite de commandes doit maintenant afficher PS C:\chatbot-rag-local>.

Maintenant que nous sommes à l'intérieur du dossier du projet, nous allons créer l'environnement virtuel. Il s'agit d'un sous-dossier nommé venv qui contiendra une copie de Python et toutes les dépendances de notre projet. Nous exécutons la commande :

python -m venv venv

Cela crée un dossier venv dans C:\chatbot-rag-local. Il contient une structure (Include, Lib, Scripts) qui isole complètement le projet. Les bibliothèques installerées plus tard iront dans venv\Lib et n'affecteront pas l’installation globale de Python.

Avant d'installer quoi que ce soit, nous "activons" cet environnement. Il indique à PowerShell d'utiliser le Python et le pip situés dans le dossier venv.

.\venv\Scripts\Activate.ps1

Après avoir exécuté cette commande, le début de notre ligne de commande affiche (venv) :

(venv) PS C:\chatbot-rag-local>

Notons que si vous obtenez une erreur de sécurité, exécutez la commande suivante une seule fois pour autoriser les scripts, puis réessayez d'activer.

Plain Text

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Répondez O (Oui) à la question.

2. Création d’un dossier de projet

Maintenant que votre environnement Python est prêt, nous allons lancer le projet de chatbot directement sur notre machine. Dans le dossier du projet chatbot-rag-local, nous allons mettre en place un dossier data, des fichiers .env, requirements.txt, app.py et un dossier templates.

A. Document.txt

Dans le dossier data, nous créons un document.txt. Il est conseillé d’utiliser un texte brut, sans caractères exotiques de longueur raisonnable et encoder en latin-1.  Pour notre chabot RAG, nous prenons un exemple simple d’un texte sur la tour Eiffel. On peut ensuite le remplacer par ce que l’on souhaite. Nous copions collons le texte :

"La Tour Eiffel est une tour de fer de 330 mètres de hauteur située à Paris, à l'extrémité nord-ouest du parc du Champ-de-Mars en bordure de la Seine dans le 7e arrondissement. Son adresse officielle est 5, avenue Anatole-France. Construite en deux ans par Gustave Eiffel et ses collaborateurs pour l'Exposition universelle de Paris de 1889, elle est devenue le symbole de la capitale française et un site touristique de premier plan. Il s'agit du quatrième site culturel français payant le plus visité en 2023, avec 6,3 millions de visiteurs."

B. Fichier .env 

Le fichier .env  sert à stocker la clé d'API secrète.  Pour la prendre, nous nous connectons à notre compte OpenAI sur https://platform.openai.com/. Nous cliquons sur la roue dentelée en haut à droite, sélectionnons "API keys" à gauche et "Create new secret key", que nous copions dans env :

@"
OPENAI_API_KEY=VOTRE_API_KEY
"@ | Out-File -Encoding UTF8NoBOM .env

C. Requirements.txt

Toujours dans le dossier chatbot-rag-local, nous créons un fichier "requirements.txt" :

Nous y mentionnons la liste des dépendances Python :

flask
langchain
langchain-community
langchain-openai
faiss-cpu
python-dotenv

D. app.py

Encore dans le dossier "chatbot-rag-local", nous créons un fichier app.py. C’est le cœur de l’application.  Il contient le code pour créer un chatbot RAG. Il se divise en 3 parties principales. Il charge les dépendances et initialise le système. Il crée la base de données vectorielle. Puis il met en place le serveur Flask pour communiquer avec l'utilisateur. Le code est :

# -*- coding: utf-8 -*-
import os
from flask import Flask, request, render_template, jsonify
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter
# Lire la clé API du fichier .env
api_key = None
try:
    with open('.env', 'r', encoding='utf-8') as f:
        content = f.read()
        for line in content.split('\n'):
            line = line.strip()
            if line.startswith('OPENAI_API_KEY='):
                api_key = line.replace('OPENAI_API_KEY=', '').strip(
               break
except Exception as e:
    print(f"Erreur lors de la lecture du fichier .env: {e}")
if not api_key:
    raise ValueError("Clé API OpenAI non trouvée dans le fichier .env")
print("Clé API chargée avec succès")
print("Chargement du document...")
try:
    loader = TextLoader('./data/document.txt', encoding='latin-1')
    documents = loader.load()
except UnicodeDecodeError:
    loader = TextLoader('./data/document.txt', encoding='latin-1')
    documents = loader.load()
print("Division du document en morceaux...")
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)
print("Création de la base de données vectorielle...")
embeddings = OpenAIEmbeddings(api_key=api_key)
vectorstore = FAISS.from_documents(docs, embeddings)
print("Création du modèle LLM...")
llm = ChatOpenAI(model_, api_key=api_key)
print("Application démarrée !")
app = Flask(__name__, template_folder='templates')
@app.route('/')
def home():
    return render_template('index.html')
@app.route('/ask', methods=['POST'])
def ask():
    try:
        data = request.get_json()
        question = data.get('question', '')     
        if not question:
            return jsonify({"result": "Veuillez poser une question"})
        retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
        relevant_docs = retriever.invoke(question)      
        context = "\n".join([doc.page_content for doc in relevant_docs])     
        prompt = f"Contexte:\n{context}\n\nQuestion: {question}\n\nRéponse:"      
        response = llm.invoke(prompt)     
        return jsonify({"result": response.content})
    except Exception as e:
       return jsonify({"result": f"Erreur: {str(e)}"})
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

Notons que, pour un code plus robuste, Vous pouvez remplacer la partie :

api_key = None try: with open('.env', 'r', encoding='utf-8') as f: content = f.read() for line in content.split('\n'): line = line.strip() if line.startswith('OPENAI_API_KEY='): api_key = line.replace('OPENAI_API_KEY=', '').strip() break

Par :

from dotenv import load_dotenv load_dotenv() api_key = os.getenv('OPENAI_API_KEY') if not api_key: raise ValueError("Clé API OpenAI non trouvée dans le fichier .env")

Vous pouvez aussi remplacer gpt-3.5-turbo par gpt-4-mini dans le code.

E. index.html

Dans le dossier "templates" situé à la racine du projet, nous créons le fichier index.html. Il crée l'interface web du chatbot. Il contient le HTML pour la structure, le CSS pour le style et le JavaScript pour la logique (ce qui se passe quand vous cliquez). Nous copions collons ce code :

<!DOCTYPE html>
<html>
<head>
    <title>Chatbot</title>
    <style>
        body { font-family: Arial; background: #f0f0f0; }
        .container { max-width: 600px; margin: 50px auto; background: white; padding: 20px; border-radius: 10px; }
        #chatbox { height: 400px; border: 1px solid #ddd; padding: 10px; overflow-y: auto; margin-bottom: 10px; background: #fafafa; }
        .msg { margin: 5px 0; padding: 8px; border-radius: 5px; }
        .user { background: #007bff; color: white; text-align: right; }
        .bot { background: #e0e0e0; }
        #userInput { width: 80%; padding: 8px; }
        button { width: 18%; padding: 8px; background: #007bff; color: white; border: none; cursor: pointer; }
    </style>
</head>
<body>
    <div>
        <h1>Chatbot RAG</h1>
        <div id="chatbox"></div>
        <input type="text" id="userInput" placeholder="Votre question...">
        <button onclick="sendMessage()">Envoyer</button>
    </div> 
    <script>
        function sendMessage() {
            var input = document.getElementById('userInput');
            var question = input.value;
                      if (!question) return;
                       var chatbox = document.getElementById('chatbox');
                      var userMsg = document.createElement('div');
            userMsg.className = 'msg user';
           userMsg.textContent = question;
            chatbox.appendChild(userMsg);
                       input.value = '';
                       fetch('/ask', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify({question: question})
            })
            .then(r => r.json())
            .then(d => {
                var botMsg = document.createElement('div');
                botMsg.className = 'msg bot';
                botMsg.textContent = d.result;
                chatbox.appendChild(botMsg);
                chatbox.scrollTop = chatbox.scrollHeight;
            })
            .catch(e => {
                var errMsg = document.createElement('div');
                errMsg.className = 'msg bot';
                errMsg.textContent = 'Erreur: ' + e;
                chatbox.appendChild(errMsg);
            });
        }      
        document.getElementById('userInput').addEventListener('keypress', function(e) {
            if (e.key === 'Enter') sendMessage();
        });
    </script>
</body>
</html>

3. Installation des dépendances

Dans notre terminal PowerShell, avec (venv) activé au début de la ligne de commande, nous tapons :

(venv) PS C:\Users\admin> cd C:\chatbot-rag-local
(venv) PS C:\chatbot-rag-local> pip install -r requirements.txt
(venv) PS C:\chatbot-rag-local> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Cela installe Flask, LangChain, et les autres dépendances nécessaires.

La structure finale du projet est :

chatbot-rag-local/

├── venv/                    (créé automatiquement)

│   ├── Scripts/

│   ├── Lib/

│   └── ...

├── data/

│   └── document.txt

├── templates/

│   └── index.html

├── app.py

├── requirements.txt

└── .env

Toujours dans le même terminal, nous lançons le chatbot avec la commande :

python app.py

Nous voyons apparaître ce message : 

© Copie d'écran

Pour voir le chatbot, nous allons à l’adresse indiquée, par exemple, http://127.0.0.1:5000 dans ce cas.

Sur la page du chatbot, nous posons des questions sur la Tour Eiffel dans la zone appropriée en bas de l’interface.

© Copie d'écran

La réponse du chatbot apparait en gris. Elle correspond bien aux informations données dans le document.txt. Pour arrêter le chatbot, nous appuyons sur Ctrl + C dans PowerShell.

4. Personnaliser et déployer le chatbot 

Pour avoir un autre texte que celui de la tour Eiffel, vous devez modifier le fichier document.txt dans le dossier data. Par exemple : 

powershell
@"
VOTRE_NOUVEAU_TEXTE_ICI
"@ | Out-File -Encoding Default data\document.txt

Après avoir changé le texte, relancez l'application :

powershell
# Arrêtez l'application actuelle (Ctrl+C)
# Puis relancez-la
python app.py

Pour fournir plusieurs fichiers séparés, vous devez modifier le code app.py. Créez plusieurs fichiers dans le dossier data :

powershell
# Document 1
@"
La France est un pays situe en Europe occidentale. Sa capitale est Paris.
"@ | Out-File -Encoding Default data\france.txt

# Document 2
@"
Python est un langage de programmation cree en 1991 par Guido van Rossum.
"@ | Out-File -Encoding Default data\python.txt

Ouvrez ensuite app.py dans Notepad++ et remplacez cette section :

Python
print("Chargement du document...")
try:
    loader = TextLoader('./data/document.txt', encoding='latin-1')
    documents = loader.load()
except UnicodeDecodeError:
    loader = TextLoader('./data/document.txt', encoding='latin-1')
    documents = loader.load()

Par :

Python
print("Chargement des documents...")
import os
from pathlib import Path
documents = []
data_folder = Path('./data')
# Charger tous les fichiers .txt du dossier data
for file_path in data_folder.glob('*.txt'):
    try:
        loader = TextLoader(str(file_path), encoding='latin-1')
        docs = loader.load()
        documents.extend(docs)
        print(f"Charge: {file_path.name}")
    except Exception as e:
        print(f"Erreur en chargeant {file_path.name}: {e}")
if not documents:
    raise ValueError("Aucun document trouve dans le dossier data/")

Sauvegardez et relancez l'application.

Exemple de réponses du chatbot avec deux textes différents fournis © Copie d'écran

Vous pouvez déployer le chatbot sur internet avec un compte Heroku  en passant par https://www.pythonanywhere.com/. Vous pouvez le déployer sur AWS, Google Cloud ou Azure. Ces services offrent plus de puissance mais sont plus complexes à configurer. Consultez leur documentation pour les applications Flask. Sur un site web existant, il est possible de passer par un iframe ou un widget personnalisé.