Bienvenue à exoco-lmd.com! Partagez et consultez des solutions d'examens et d'exercices des programmes LMD et formation d'ingénieur.

Shoutbox

Recent

Membres
Stats
  • Total des messages: 7147
  • Total des sujets: 6951
  • Online today: 4306
  • Online ever: 5619
  • (Février 22, 2026, 01:46:55 PM)
Membres en ligne
Users: 0
Guests: 4181
Total: 4181

Créer un RAG pas à pas : Embeddings, FAISS et LangChain expliqués pas à pas

Démarré par Exocoeur, Février 21, 2026, 01:55:41 PM

« précédent - suivant »

Exocoeur

Qu'est-ce que le RAG ?

RAG = Retrieval Augmented Generation (Génération Augmentée par Récupération)





ÉtapeDescriptionAnalogie
RetrievalChercher les informations pertinentesChercher dans un livre avec l'index
Augmented  Enrichir le prompt avec ces informations    Donner des notes à un étudiant avant l'examen
Generation      Le LLM génère une réponse basée sur ces infos            L'étudiant répond en s'appuyant sur ses notes


I) Créer un RAG

# ============================================================================
# IMPORTATION DES BIBLIOTHÈQUES NÉCESSAIRES
# ============================================================================

from langchain.vectorstores import FAISS  # Base de données vectorielle
from langchain.chat_models import ChatOpenAI  # Modèle de langage (LLM)
from langchain.chains import RetrievalQA  # Chaîne pour faire du Question-Answering avec récupération
from langchain.prompts import PromptTemplate  # Pour personnaliser les prompts (non utilisé ici)
from dotenv import load_dotenv  # Pour charger les variables d'environnement
import os  # Pour accéder aux variables d'environnement


# ============================================================================
# CONFIGURATION DU MODÈLE DE LANGAGE (LLM)
# ============================================================================

# Chargement des variables d'environnement depuis le fichier .env
load_dotenv()

# Récupération des informations de connexion depuis les variables d'environnement
# Cela permet de ne pas exposer les clés API directement dans le code
api_key = os.getenv("OPENAI_API_KEY")  # Votre clé API
model_name = os.getenv("OPENAI_MODEL_NAME")  # Nom du modèle (ex: "gpt-4", "gpt-3.5-turbo")

# Initialisation du modèle de langage
llm = ChatOpenAI(
    model_name=model_name,  # Modèle générique à utiliser
    openai_api_key=api_key,  # Clé d'authentification
    temperature=0  # 0 = réponses déterministes, 1 = réponses créatives
)


# ============================================================================
# ÉTAPE 1 : CHARGEMENT DE LA BASE DE DONNÉES VECTORIELLE FAISS
# ============================================================================

# Chemin vers la base de données FAISS créée précédemment
faiss_index_path = "faiss_db"

print(f"Chargement de la base de données FAISS depuis : {faiss_index_path}")

# Chargement de la base de données vectorielle
# ⚠️ allow_dangerous_deserialization=True : nécessaire pour charger des fichiers pickle
# (à utiliser uniquement avec des sources de confiance)
db = FAISS.load_local(
    faiss_index_path,
    embeddings=embeddings,  # Même modèle d'embeddings utilisé lors de la création
    allow_dangerous_deserialization=True
)

print("✅ Base de données chargée avec succès")


# ============================================================================
# ÉTAPE 2 : CRÉATION DU RETRIEVER (RÉCUPÉRATEUR DE DOCUMENTS)
# ============================================================================

# Le retriever va chercher les morceaux de texte les plus pertinents
# en fonction de la question posée

retriever = db.as_retriever(
    search_kwargs={"k": 3}  # k=3 : récupère les 3 chunks les plus similaires à la question
)

print("✅ Retriever configuré pour récupérer 3 documents pertinents")


# ============================================================================
# ÉTAPE 3 : CRÉATION DE LA CHAÎNE RAG (Retrieval Augmented Generation)
# ============================================================================

# RAG = Récupération + Génération
# 1. On récupère les documents pertinents (Retrieval)
# 2. On les donne au LLM pour générer une réponse (Generation)

rag_chain = RetrievalQA.from_chain_type(
    llm=llm,  # Le modèle de langage qui va générer la réponse
    chain_type="stuff",  # "stuff" = concatène tous les documents récupérés dans le prompt
                         # Autres options : "map_reduce", "refine", "map_rerank"
    retriever=retriever,  # Le retriever qui va chercher les documents pertinents
    return_source_documents=True  # Retourne aussi les documents sources utilisés
)

print("✅ Chaîne RAG créée et prête à répondre aux questions")


# ============================================================================
# ÉTAPE 4 : INTERROGATION DU SYSTÈME RAG
# ============================================================================

# Question à poser au système
question = "Quelles idées Paul Graham donne-t-il pour les startups ?"

print(f"\n📝 Question posée : {question}\n")

# Exécution de la chaîne RAG
# Le système va :
# 1. Chercher les 3 chunks les plus pertinents dans la base FAISS
# 2. Les donner au LLM avec la question
# 3. Générer une réponse basée sur ces documents
result = rag_chain({"query": question})


# ============================================================================
# ÉTAPE 5 : AFFICHAGE DES RÉSULTATS
# ============================================================================

print("=" * 80)
print("🤖 RÉPONSE DU SYSTÈME RAG")
print("=" * 80)

# Affichage de la réponse générée
print("\n📌 Réponse :")
print(result['result'])

# Affichage des documents sources utilisés
print("\n📚 Documents sources utilisés :")
for i, doc in enumerate(result['source_documents'], 1):
    print(f"\n--- Document {i} ---")
    print(doc.page_content[:200] + "...")  # Affiche les 200 premiers caractères
    print(f"Source : {doc.metadata}")  # Métadonnées (fichier source, page, etc.)

print("\n" + "=" * 80)


# ============================================================================
# RÉSUMÉ DU PROCESSUS RAG
# ============================================================================
#
# 1. 📥 CHARGEMENT : On charge la base de données vectorielle FAISS
# 2. 🔍 RETRIEVAL : On cherche les documents pertinents pour la question
# 3. 🤖 GENERATION : Le LLM génère une réponse basée sur ces documents
# 4. ✅ RÉSULTAT : On obtient une réponse précise et sourcée
#
# AVANTAGES DU RAG :
# - Réponses basées sur vos propres documents
# - Pas d'hallucinations (le LLM s'appuie sur des sources réelles)
# - Traçabilité (on peut voir quels documents ont été utilisés)
# - Mise à jour facile (il suffit de mettre à jour la base FAISS)
#
# ============================================================================

II) Intéroger un RAG

# ============================================================================
# IMPORTATION DES BIBLIOTHÈQUES NÉCESSAIRES
# ============================================================================

from langchain.vectorstores import FAISS  # Base de données vectorielle
from langchain.chat_models import ChatOpenAI  # Modèle de langage (LLM)
from langchain.chains import RetrievalQA  # Chaîne pour faire du Question-Answering avec récupération
from langchain.prompts import PromptTemplate  # Pour personnaliser les prompts (non utilisé ici)
from dotenv import load_dotenv  # Pour charger les variables d'environnement
import os  # Pour accéder aux variables d'environnement


# ============================================================================
# ⚠️ IMPORTANT : CRÉATION DU FICHIER .env
# ============================================================================
#
# Avant d'exécuter ce code, vous DEVEZ créer un fichier nommé ".env"
# à la racine de votre projet (au même niveau que ce script Python)
#
# Contenu du fichier .env :
# -------------------------
# OPENAI_API_KEY=sk-votre-clé-api-ici
# OPENAI_MODEL_NAME=gpt-3.5-turbo
#
# ⚠️ SÉCURITÉ :
# - Ne JAMAIS partager ce fichier .env
# - Ne JAMAIS le commiter sur Git
# - Ajouter ".env" dans votre fichier .gitignore
#
# Structure du projet :
# ---------------------
# mon_projet/
# ├── .env                    ← Fichier à créer (contient les clés secrètes)
# ├── .gitignore              ← Ajouter ".env" dedans
# ├── script_rag.py           ← Ce fichier
# ├── faiss_db/               ← Base de données vectorielle
# └── requirements.txt        ← Dépendances Python
#
# ============================================================================


# ============================================================================
# CONFIGURATION DU MODÈLE DE LANGAGE (LLM)
# ============================================================================

# Chargement des variables d'environnement depuis le fichier .env
# Cette fonction lit le fichier .env et charge les variables dans l'environnement
load_dotenv()

# Récupération des informations de connexion depuis les variables d'environnement
# Cela permet de ne pas exposer les clés API directement dans le code
api_key = os.getenv("OPENAI_API_KEY")  # Votre clé API OpenAI
model_name = os.getenv("OPENAI_MODEL_NAME")  # Nom du modèle (ex: "gpt-4", "gpt-3.5-turbo")

# ⚠️ Vérification que les variables ont bien été chargées
if not api_key:
    raise ValueError(
        "❌ ERREUR : La clé API n'a pas été trouvée !\n"
        "Assurez-vous d'avoir créé un fichier .env avec :\n"
        "OPENAI_API_KEY=votre-clé-ici"
    )

if not model_name:
    raise ValueError(
        "❌ ERREUR : Le nom du modèle n'a pas été trouvé !\n"
        "Assurez-vous d'avoir créé un fichier .env avec :\n"
        "OPENAI_MODEL_NAME=gpt-3.5-turbo"
    )

print("✅ Variables d'environnement chargées avec succès")
print(f"   Modèle utilisé : {model_name}")

# Initialisation du modèle de langage
llm = ChatOpenAI(
    model_name=model_name,  # Modèle générique à utiliser
    openai_api_key=api_key,  # Clé d'authentification
    temperature=0  # 0 = réponses déterministes, 1 = réponses créatives
)


# ============================================================================
# ÉTAPE 1 : CHARGEMENT DE LA BASE DE DONNÉES VECTORIELLE FAISS
# ============================================================================

# Chemin vers la base de données FAISS créée précédemment
faiss_index_path = "faiss_db"

print(f"Chargement de la base de données FAISS depuis : {faiss_index_path}")

# Chargement de la base de données vectorielle
# ⚠️ allow_dangerous_deserialization=True : nécessaire pour charger des fichiers pickle
# (à utiliser uniquement avec des sources de confiance)
db = FAISS.load_local(
    faiss_index_path,
    embeddings=embeddings,  # Même modèle d'embeddings utilisé lors de la création
    allow_dangerous_deserialization=True
)

print("✅ Base de données chargée avec succès")


# ============================================================================
# ÉTAPE 2 : CRÉATION DU RETRIEVER (RÉCUPÉRATEUR DE DOCUMENTS)
# ============================================================================

# Le retriever va chercher les morceaux de texte les plus pertinents
# en fonction de la question posée

retriever = db.as_retriever(
    search_kwargs={"k": 3}  # k=3 : récupère les 3 chunks les plus similaires à la question
)

print("✅ Retriever configuré pour récupérer 3 documents pertinents")


# ============================================================================
# ÉTAPE 3 : CRÉATION DE LA CHAÎNE RAG (Retrieval Augmented Generation)
# ============================================================================

# RAG = Récupération + Génération
# 1. On récupère les documents pertinents (Retrieval)
# 2. On les donne au LLM pour générer une réponse (Generation)

rag_chain = RetrievalQA.from_chain_type(
    llm=llm,  # Le modèle de langage qui va générer la réponse
    chain_type="stuff",  # "stuff" = concatène tous les documents récupérés dans le prompt
                         # Autres options : "map_reduce", "refine", "map_rerank"
    retriever=retriever,  # Le retriever qui va chercher les documents pertinents
    return_source_documents=True  # Retourne aussi les documents sources utilisés
)

print("✅ Chaîne RAG créée et prête à répondre aux questions")


# ============================================================================
# ÉTAPE 4 : INTERROGATION DU SYSTÈME RAG
# ============================================================================

# Question à poser au système
question = "Quelles idées Paul Graham donne-t-il pour les startups ?"

print(f"\n📝 Question posée : {question}\n")

# Exécution de la chaîne RAG
# Le système va :
# 1. Chercher les 3 chunks les plus pertinents dans la base FAISS
# 2. Les donner au LLM avec la question
# 3. Générer une réponse basée sur ces documents
result = rag_chain({"query": question})


# ============================================================================
# ÉTAPE 5 : AFFICHAGE DES RÉSULTATS
# ============================================================================

print("=" * 80)
print("🤖 RÉPONSE DU SYSTÈME RAG")
print("=" * 80)

# Affichage de la réponse générée
print("\n📌 Réponse :")
print(result['result'])

# Affichage des documents sources utilisés
print("\n📚 Documents sources utilisés :")
for i, doc in enumerate(result['source_documents'], 1):
    print(f"\n--- Document {i} ---")
    print(doc.page_content[:200] + "...")  # Affiche les 200 premiers caractères
    print(f"Source : {doc.metadata}")  # Métadonnées (fichier source, page, etc.)

print("\n" + "=" * 80)


# ============================================================================
# RÉSUMÉ DU PROCESSUS RAG
# ============================================================================
#
# 1. 📥 CHARGEMENT : On charge la base de données vectorielle FAISS
# 2. 🔍 RETRIEVAL : On cherche les documents pertinents pour la question
# 3. 🤖 GENERATION : Le LLM génère une réponse basée sur ces documents
# 4. ✅ RÉSULTAT : On obtient une réponse précise et sourcée
#
# AVANTAGES DU RAG :
# - Réponses basées sur vos propres documents
# - Pas d'hallucinations (le LLM s'appuie sur des sources réelles)
# - Traçabilité (on peut voir quels documents ont été utilisés)
# - Mise à jour facile (il suffit de mettre à jour la base FAISS)
#
# ============================================================================


Exocoeur

Hors ligne Annonceur

  • Jr. Member
  • **
  • Messages: na
  • Karma: +0/-0
Re : message iportant de l'auteur
« le: un jour de l'année »




Exocoeur

Dites nous comment obtenir une clé api pour chatgp ou autre, en Algérie? Y a t-il un fournisseur officiel?

Exocoeur


Suggestions pour vous



Suggestions pour vous