Maison > développement back-end > Tutoriel Python > Le guide ultime de la génération augmentée par récupération (RAG)

Le guide ultime de la génération augmentée par récupération (RAG)

Barbara Streisand
Libérer: 2024-12-21 18:55:10
original
839 Les gens l'ont consulté

L'évolution rapide des modèles d'IA générative comme ChatGPT d'OpenAI a révolutionné le traitement du langage naturel, permettant à ces systèmes de générer des réponses cohérentes et contextuellement pertinentes. Cependant, même les modèles les plus avancés sont confrontés à des limites lorsqu’ils traitent des requêtes spécifiques à un domaine ou fournissent des informations très précises. Cela conduit souvent à des problèmes tels que des hallucinations : des cas où les modèles produisent des détails inexacts ou fabriqués.

Retrieval-Augmented Generation (RAG), un cadre innovant conçu pour combler cette lacune. En intégrant de manière transparente des sources de données externes, RAG permet aux modèles génératifs de récupérer des informations de niche en temps réel, améliorant ainsi considérablement leur précision et leur fiabilité.

Dans cet article, nous plongerons dans la mécanique de RAG, explorerons son architecture et discuterons des limites des modèles génératifs traditionnels qui ont inspiré sa création. Nous mettrons également en évidence des mises en œuvre pratiques, des techniques avancées et des méthodes d'évaluation, montrant comment RAG transforme la façon dont l'IA interagit avec des données spécialisées.

Commencer

Table des matières

  • Qu'est-ce que RAG
  • Architecture de RAG
  • Flux de processus RAG
  • RAG vs réglage fin
  • Types de RAG
  • Applications de RAG
  • Créer un système de chat PDF avec RAG
  • Ressources

Qu'est-ce que RAG

Retrieval-Augmented Generation (RAG) est un cadre avancé qui améliore les capacités des modèles d'IA génératifs en intégrant la récupération en temps réel de données externes. Bien que les modèles génératifs excellent dans la production de textes cohérents et semblables à ceux des humains, ils peuvent échouer lorsqu'on leur demande de fournir des informations précises, à jour ou spécifiques à un domaine. C'est là qu'intervient RAG, en veillant à ce que les réponses soient non seulement créatives mais également fondées sur des sources fiables et pertinentes.

RAG fonctionne en connectant un modèle génératif à un mécanisme de récupération, généralement alimenté par des bases de données vectorielles ou des systèmes de recherche. Lorsqu'une requête est reçue, le composant de récupération recherche dans de vastes ensembles de données externes pour récupérer les informations pertinentes. Le modèle génératif synthétise ensuite ces données, produisant un résultat à la fois précis et contextuellement perspicace.

En abordant des défis clés tels que les hallucinations et la connaissance limitée du domaine, RAG libère le potentiel des modèles génératifs pour exceller dans des domaines spécialisés. Ses applications couvrent divers secteurs, depuis l'automatisation du support client avec des réponses précises, permettant aux chercheurs d'accéder à des connaissances organisées à la demande. RAG représente une avancée significative pour rendre les systèmes d'IA plus intelligents, plus fiables et plus utiles dans des scénarios du monde réel.

Architecture de RAG

Une compréhension claire de l'architecture RAG est essentielle pour libérer tout son potentiel et ses avantages. À la base, le cadre repose sur deux composants principaux : le Retriever et le Generator, travaillant ensemble dans un flux transparent de traitement de l'information.

Ce processus global est illustré ci-dessous :
The ultimate guide to Retrieval-Augmented Generation (RAG)
source : https://weaviate.io/blog/introduction-to-rag

  • Récupération — L'étape d'inférence dans RAG commence par la récupération, où les données pertinentes pour une requête utilisateur sont récupérées à partir d'une source de connaissances externe. Dans une configuration RAG de base, la recherche de similarité est couramment utilisée, intégrant la requête et les données externes dans le même espace vectoriel pour identifier les correspondances les plus proches. Le Retriever joue un rôle clé dans la récupération de documents, en utilisant des méthodes telles que Sparse Retrieval et Dense Retrieval. Sparse Retrieval, utilisant des techniques telles que TF-IDF ou BM25, s'appuie sur des correspondances de mots exactes mais a du mal avec les synonymes et la paraphrase, tandis que Dense Retrieval exploite des modèles de transformateur comme BERT ou RoBERTa pour créer des représentations vectorielles sémantiques, permettant des correspondances plus précises et nuancées.
  • Augmentation — Après avoir récupéré les points de données les plus pertinents de la source externe, le processus d'augmentation intègre ces informations en les intégrant dans un modèle d'invite prédéfini.
  • Génération — Dans la phase de génération, le modèle utilise l'invite augmentée pour élaborer une réponse cohérente et contextuellement précise en combinant sa compréhension du langage interne avec les données externes récupérées. Alors que l'augmentation intègre des faits externes, la génération transforme ces informations enrichies en texte naturel, semblable à celui d'un humain, adapté à la requête de l'utilisateur.

Flux de processus RAG

Toutes les étapes et composants essentiels du flux de processus RAG, illustrés dans la figure ci-dessous.

The ultimate guide to Retrieval-Augmented Generation (RAG)
source : https://www.griddynamics.com/blog/retrieval-augmented-Generation-llm

  • Chargement de documents : la première étape du processus RAG implique la préparation des données, qui comprend le chargement de documents à partir du stockage, l'extraction, l'analyse, le nettoyage et le formatage du texte pour le fractionnement des documents. Les données texte peuvent se présenter sous différents formats, tels que du texte brut, des PDF, des documents Word, CSV, JSON, HTML, Markdown ou du code de programmation. La préparation de ces diverses sources pour les LLM nécessite généralement de les convertir en texte brut par extraction, analyse et nettoyage.
  • Répartition des documents : les documents sont divisés en segments plus petits et gérables via le fractionnement ou le regroupement du texte, ce qui est essentiel pour gérer des documents volumineux et respecter les limites de jetons dans les LLM (par exemple, les 2 048 jetons de GPT-3). Les stratégies incluent une segmentation de taille fixe ou sensible au contenu, l'approche dépendant de la structure et des exigences des données. The ultimate guide to Retrieval-Augmented Generation (RAG)

Diviser des documents en morceaux plus petits peut sembler simple, mais cela nécessite un examen attentif de la sémantique pour éviter de diviser les phrases de manière inappropriée, ce qui peut affecter les étapes ultérieures telles que la réponse aux questions. Une approche naïve de segmentation de taille fixe peut entraîner des informations incomplètes dans chaque segment. La plupart des algorithmes de segmentation de documents utilisent la taille des fragments et le chevauchement, où la taille des fragments est déterminée par le nombre de caractères, de mots ou de jetons, et les chevauchements assurent la continuité en partageant le texte entre les fragments adjacents. Cette stratégie préserve le contexte sémantique à travers les morceaux.

  • Incorporation de texte : les morceaux de texte sont transformés en intégrations vectorielles, qui représentent chaque morceau de manière à permettre une comparaison facile de la similarité sémantique. Les intégrations vectorielles mappent des données complexes, comme le texte, dans un espace mathématique où des points de données similaires se regroupent. Ce processus capture la signification sémantique du texte, de sorte que les phrases ayant une signification similaire, même si elles sont formulées différemment, sont mappées les unes à côté des autres dans l'espace vectoriel. Par exemple, « Le chat poursuit la souris » et « Le félin poursuit le rongeur » seraient mappés sur des points proches malgré leur formulation différente.

The ultimate guide to Retrieval-Augmented Generation (RAG)
source : https://www.griddynamics.com/blog/retrieval-augmented-Generation-llm

  • Magasin de vecteurs : une fois les documents segmentés et convertis en intégrations vectorielles, ils sont stockés dans un magasin de vecteurs, une base de données spécialisée pour le stockage et la gestion des vecteurs. Un magasin de vecteurs permet des recherches efficaces de vecteurs similaires, ce qui est crucial pour l'exécution d'un modèle RAG. La sélection d'un magasin vectoriel dépend de facteurs tels que l'échelle des données et les ressources informatiques disponibles.

Certaines des bases de données vectorielles importantes sont :

  • FAISS : Développé par Facebook AI, FAISS gère efficacement de grandes collections de vecteurs de haute dimension et effectue des recherches de similarité et un regroupement dans des environnements de haute dimension. Il optimise l'utilisation de la mémoire et la durée des requêtes, ce qui le rend adapté à la gestion de milliards de vecteurs.
  • Chroma : base de données vectorielles open source en mémoire, Chroma est conçue pour les applications LLM, offrant une plate-forme évolutive pour le stockage, la recherche et la récupération de vecteurs. Il prend en charge le déploiement dans le cloud et sur site et est polyvalent dans la gestion de différents types et formats de données.
  • Weaviate : une base de données vectorielles open source qui peut être auto-hébergée ou entièrement gérée. Il se concentre sur les hautes performances, l’évolutivité et la flexibilité, prenant en charge un large éventail de types de données et d’applications. Il permet le stockage à la fois de vecteurs et d'objets, permettant la combinaison de techniques de recherche basées sur des vecteurs et sur des mots-clés.
  • Pinecone : une base de données vectorielles gérée basée sur le cloud, conçue pour simplifier le développement et le déploiement d'applications ML à grande échelle. Contrairement à de nombreuses bases de données vectorielles, Pinecone utilise un code propriétaire et fermé. Il excelle dans la gestion des vecteurs de grande dimension et convient à des applications telles que la recherche de similarité, les systèmes de recommandation, la personnalisation et la recherche sémantique. Pinecone dispose également d'une capacité de filtrage en une seule étape.
  • Récupération de documents : Le processus de récupération dans les systèmes de recherche d'informations, tels que la recherche de documents ou la réponse à des questions, commence lorsqu'une requête est reçue et transformée en vecteur en utilisant le même modèle d'intégration que l'indexation de documents. L'objectif est de renvoyer des fragments de document pertinents en comparant le vecteur de requête avec les vecteurs de fragments stockés dans l'index (magasin de vecteurs). Le rôle du récupérateur est d'identifier et de renvoyer les identifiants des morceaux de documents pertinents, sans stocker les documents. Diverses méthodes de recherche peuvent être utilisées, telles que la recherche de similarité (basée sur la similarité cosinus) et la récupération basée sur un seuil, qui renvoie uniquement les documents dépassant un certain score de similarité. De plus, la récupération assistée par LLM est utile pour les requêtes impliquant à la fois le filtrage de contenu et de métadonnées.

The ultimate guide to Retrieval-Augmented Generation (RAG)
source : https://www.griddynamics.com/blog/retrieval-augmented-Generation-llm

  • Génération de réponse : dans le processus de récupération, les morceaux de document pertinents sont combinés avec la requête de l'utilisateur pour générer un contexte et une invite pour le LLM. L'approche la plus simple, appelée méthode « Stuff » dans LangChain, consiste à canaliser tous les morceaux dans la même fenêtre contextuelle pour une réponse directe et simple. Cependant, cette méthode peine à gérer de gros volumes de documents et des requêtes complexes en raison des limitations de la fenêtre contextuelle. Pour résoudre ce problème, des méthodes alternatives telles que Map-reduce, Refine et Map-rerank sont utilisées. Map-reduce envoie les documents séparément au LLM, puis combine les réponses. Affiner met à jour de manière itérative l'invite pour affiner la réponse, tandis que Map-rerank classe les documents en fonction de leur pertinence, idéal pour plusieurs réponses convaincantes.

The ultimate guide to Retrieval-Augmented Generation (RAG)

RAG vs réglage fin

RAG (Retrieval-Augmented Generation) et le réglage fin sont deux méthodes clés pour étendre les capacités LLM, chacune adaptée à différents scénarios. Le réglage fin implique de recycler les LLM sur des données spécifiques à un domaine pour effectuer des tâches spécialisées, idéales pour les cas d'utilisation statiques et restreints comme l'image de marque ou l'écriture créative qui nécessitent un ton ou un style spécifique. Cependant, cette méthode est coûteuse, prend du temps et ne convient pas aux données dynamiques et fréquemment mises à jour.

D'autre part, RAG améliore les LLM en récupérant dynamiquement des données externes sans modifier les pondérations du modèle, ce qui le rend rentable et idéal pour les environnements en temps réel basés sur les données comme les applications juridiques, financières ou de service client. RAG permet aux LLM de gérer des corpus de documents internes volumineux et non structurés, offrant des avantages significatifs par rapport aux méthodes traditionnelles de navigation dans des référentiels de données désordonnés.

Le réglage fin excelle dans la création de résultats nuancés et cohérents, tandis que RAG fournit des informations à jour et précises en exploitant des bases de connaissances externes. Dans la pratique, RAG est souvent le choix privilégié pour les applications nécessitant des réponses adaptables en temps réel, en particulier dans les entreprises gérant de vastes données non structurées.

Types de RAG

Il existe plusieurs types d'approches de génération de récupération augmentée (RAG), chacune adaptée à des cas d'utilisation et à des objectifs spécifiques. Les principaux types incluent :

The ultimate guide to Retrieval-Augmented Generation (RAG)
source : https://x.com/weaviate_io/status/1866528335884325070

  • RAG natif : fait référence à une approche étroitement intégrée dans laquelle les composants de récupération et de génération d'un système de génération augmentée de récupération sont conçus pour fonctionner de manière transparente au sein de la même architecture. Contrairement aux implémentations traditionnelles qui s'appuient sur des outils ou des API externes, RAG natif optimise l'interaction entre les mécanismes de récupération et les modèles génératifs, permettant un traitement plus rapide et une pertinence contextuelle améliorée. Cette approche utilise souvent un traitement en mémoire ou des bases de données locales hautement optimisées, réduisant ainsi la latence et la surcharge des ressources. Les systèmes RAG natifs sont généralement adaptés à des cas d'utilisation spécifiques, offrant une efficacité, une précision et une rentabilité améliorées en éliminant les dépendances vis-à-vis des services tiers.
  • Récupérer et reclasser RAG : se concentre sur l'affinement du processus de récupération pour améliorer la précision et la pertinence. Dans cette méthode, un ensemble initial de documents ou de morceaux est récupéré en fonction de la similarité sémantique de la requête, généralement déterminée par la similarité cosinus dans l’espace d’intégration. Par la suite, un modèle de reclassement réorganise les documents récupérés en fonction de leur pertinence contextuelle par rapport à la requête. Cette étape de reclassement exploite souvent des modèles ou des transformateurs d’apprentissage profond, permettant un classement plus nuancé au-delà des mesures de similarité de base. En donnant la priorité aux documents les plus pertinents, cette approche garantit que le modèle génératif reçoit des informations contextuellement enrichies, améliorant ainsi considérablement la qualité des réponses.
  • RAG multimodal : étend le paradigme RAG traditionnel en incorporant plusieurs modalités de données, telles que du texte, des images, de l'audio ou de la vidéo, dans le pipeline de génération augmentée par récupération. Il permet au système de récupérer et de générer des réponses qui intègrent diverses formes de données. Par exemple, dans un scénario impliquant des requêtes basées sur des images, le système peut récupérer des images pertinentes ainsi que du contenu textuel pour créer une réponse plus complète. Le RAG multimodal est particulièrement utile dans des domaines tels que le commerce électronique, l'imagerie médicale et l'analyse de contenu multimédia, où les informations reposent souvent sur une combinaison d'informations textuelles et visuelles.
  • Graph RAG : exploite les structures de données basées sur des graphiques pour modéliser et récupérer des informations en fonction des relations et des connexions entre les entités. Dans cette approche, les connaissances sont organisées sous forme de graphe où les nœuds représentent des entités (par exemple, des concepts, des documents ou des objets) et les bords capturent leurs relations (par exemple, sémantiques, hiérarchiques ou temporelles). Les requêtes sont traitées pour identifier les sous-graphiques ou les chemins pertinents pour l'entrée, et ces sous-graphiques sont ensuite introduits dans le modèle génératif. Cette méthode est particulièrement utile dans des domaines tels que la recherche scientifique, les réseaux sociaux et la gestion des connaissances, où les connaissances relationnelles sont essentielles.
  • RAG hybride : combine plusieurs techniques de récupération, telles que la récupération dense et clairsemée, pour améliorer les performances sur divers types de requêtes. La récupération dense utilise des intégrations vectorielles pour capturer les similitudes sémantiques, tandis que la récupération clairsemée s'appuie sur des méthodes basées sur des mots clés, comme BM25, pour des correspondances précises. En intégrant ces méthodes, Hybrid RAG équilibre précision et rappel, le rendant polyvalent dans des scénarios où les requêtes peuvent être très spécifiques ou abstraites. Il est particulièrement efficace dans les environnements contenant des données hétérogènes, garantissant que la sémantique de haut niveau et les mots-clés spécifiques sont pris en compte lors de la récupération.
  • Agentic RAG (Router) : utilise une couche de prise de décision pour acheminer dynamiquement les requêtes vers les modules de récupération et de génération appropriés en fonction de leurs caractéristiques. Le routeur analyse les requêtes entrantes pour déterminer le chemin de traitement optimal, qui peut impliquer différentes méthodes de récupération, sources de données ou même des modèles génératifs spécialisés. Cette approche garantit que le système adapte ses opérations aux besoins spécifiques de chaque requête, améliorant ainsi l'efficacité et la précision dans diverses applications.
  • Agentic RAG (Multi-Agent RAG) : Multi-Agent RAG implique un cadre collaboratif dans lequel plusieurs agents spécialisés gèrent des aspects distincts du processus de récupération et de génération. Chaque agent est responsable d'une tâche spécifique, telle que récupérer des données d'un domaine particulier, reclasser les résultats ou générer des réponses dans un style spécifique. Ces agents communiquent et collaborent pour fournir des résultats cohérents. Multi-Agent RAG est particulièrement puissant pour les requêtes complexes et multi-domaines, car il permet au système de tirer parti de l'expertise de différents agents pour fournir des réponses complètes et nuancées.

Applications du RAG

Le framework RAG (Retrieval-Augmented Generation) a diverses applications dans divers secteurs en raison de sa capacité à intégrer dynamiquement des connaissances externes dans des modèles de langage génératifs. Voici quelques applications importantes :

  • Support client et service : les systèmes RAG sont largement utilisés dans le support client pour créer des chatbots intelligents capables de répondre à des requêtes complexes en récupérant les données pertinentes des manuels de produits, des bases de connaissances et des documents de politique de l'entreprise. Cela garantit que les clients reçoivent des informations précises et à jour, améliorant ainsi leur expérience.
  • Analyse de documents juridiques : dans le domaine juridique, RAG peut analyser, récupérer et générer des résumés ou des réponses à partir de vastes corpus de jurisprudence, de contrats et de documents juridiques. Il est particulièrement utile pour effectuer des recherches juridiques, rédiger des contrats et veiller au respect de la réglementation.
  • Analyse financière : RAG est employé dans les services financiers pour analyser les rapports sur les bénéfices, les tendances du marché et les documents réglementaires. En récupérant des données financières pertinentes, il peut aider les analystes à générer des informations, des rapports ou même des réponses en temps réel aux requêtes sur les performances du marché.
  • Soins de santé et diagnostics médicaux : Dans le domaine de la santé, RAG est utilisé pour récupérer et synthétiser des informations à partir de la littérature médicale, des dossiers des patients et des directives de traitement. Il facilite le diagnostic, la découverte de médicaments et les recommandations de traitement personnalisées, garantissant ainsi aux cliniciens l'accès aux données les plus récentes et les plus pertinentes.
  • Éducation et apprentissage en ligne : les outils basés sur RAG aident à une éducation personnalisée en récupérant le matériel de cours et en générant des réponses ou des guides d'étude personnalisés. Ils peuvent améliorer les plateformes d'apprentissage en fournissant des explications contextuelles et du contenu dynamique basé sur les requêtes des utilisateurs.
  • E-Commerce et Retail : Dans le e-commerce, les systèmes RAG améliorent les moteurs de recherche et de recommandation de produits en récupérant les données des catalogues et des avis clients. Ils activent également des assistants d'achat conversationnels qui fournissent des suggestions de produits personnalisées en fonction des préférences de l'utilisateur.
  • Assistants virtuels intelligents : RAG améliore les assistants virtuels comme Alexa ou Siri en fournissant des réponses précises et contextuellement pertinentes, en particulier pour les requêtes nécessitant des connaissances externes, telles que les mises à jour météorologiques en temps réel ou les informations commerciales locales.

Construire un système de discussion PDF à l'aide de RAG

Dans cette section, nous développerons une application rationalisée capable de comprendre le contenu d'un PDF et de répondre aux requêtes des utilisateurs basées sur ce contenu à l'aide de la génération de récupération augmentée (RAG). La mise en œuvre exploite la plateforme LangChain pour faciliter les interactions avec les LLM et les magasins de vecteurs. Nous utiliserons le LLM d'OpenAI et ses modèles d'intégration pour construire un magasin de vecteurs FAISS pour une récupération efficace des informations.

Installation des dépendances

  • Créez et activez un environnement virtuel en exécutant la commande suivante.
python -m venv venv
source venv/bin/activate #for ubuntu
venv/Scripts/activate #for windows
Copier après la connexion
  • Installez les bibliothèques langchain, langchain_community, openai, faiss-cpu, PyPDF2, streamlit, python-dotenv, tiktoken à l'aide de pip.
pip install langchain langchain_community openai faiss-cpu PyPDF2 streamlit python-dotenv tiktoken
Copier après la connexion

Configuration de l'environnement et des informations d'identification

  • Créez un fichier nommé .env. Ce fichier stockera vos variables d'environnement, y compris la clé OpenAI, le modèle et les intégrations.
  • Ouvrez le fichier .env et ajoutez le code suivant pour spécifier vos informations d'identification OpenAI :
OPENAI_API_KEY=sk-proj-xcQxBf5LslO62At...
OPENAI_MODEL_NAME=gpt-3.5-turbo
OPENAI_EMBEDDING_MODEL_NAME=text-embedding-3-small
Copier après la connexion

Importation de variables d'environnement

  • Créez un fichier nommé app.py.
  • Ajoutez les informations d'identification OpenAI aux variables d'environnement.
from dotenv import load_dotenv
import os
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
OPENAI_MODEL_NAME = os.getenv("OPENAI_MODEL_NAME")
OPENAI_EMBEDDING_MODEL_NAME = os.getenv("OPENAI_EMBEDDING_MODEL_NAME")
Copier après la connexion

Importation des bibliothèques requises

Importez les bibliothèques essentielles pour créer l'application, en gérant les PDF tels que langchain, streamlit, pyPDF.

import streamlit as st
from PyPDF2 import PdfReader
from langchain.text_splitter import CharacterTextSplitter
from langchain.prompts import PromptTemplate
from langchain_community.embeddings import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
from langchain_community.chat_models import ChatOpenAI
from htmlTemplates import bot_template, user_template, css
Copier après la connexion

Définir une fonction pour extraire du texte à partir de PDF

  • Utilisez PyPDF2 pour extraire le texte des fichiers PDF téléchargés.
def get_pdf_text(pdf_files):
    text = ""
    for pdf_file in pdf_files:
        reader = PdfReader(pdf_file)
        for page in reader.pages:
            text += page.extract_text()
    return text
Copier après la connexion

Diviser le texte extrait en morceaux

Divisez un texte volumineux en morceaux plus petits et gérables à l'aide de CharacterTextSplitter de LangChain.

def get_chunk_text(text):
    text_splitter = CharacterTextSplitter(
        separator="\n",
        chunk_size=1000,
        chunk_overlap=200,
        length_function=len
    )
    chunks = text_splitter.split_text(text)
    return chunks
Copier après la connexion

Création d'un magasin de vecteurs pour l'intégration de texte

Générez des intégrations pour des morceaux de texte et stockez-les dans une base de données vectorielles à l'aide de FAISS.

def get_vector_store(text_chunks):
    embeddings = OpenAIEmbeddings(openai_api_key=OPENAI_API_KEY, model=OPENAI_EMBEDDING_MODEL_NAME)
    vectorstore = FAISS.from_texts(texts=text_chunks, embedding=embeddings)
    return vectorstore
Copier après la connexion

Construire une chaîne de récupération conversationnelle

Définissez une chaîne qui récupère les informations du magasin de vecteurs et interagit avec l'utilisateur via un LLM.

def get_conversation_chain(vector_store):
    llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY, model_name=OPENAI_MODEL_NAME, temperature=0)
    memory = ConversationBufferMemory(memory_key='chat_history', return_messages=True)
    system_template  =  """
    Use  the following pieces of context and chat history to answer the question at the end. 
    If you don't know the answer, just say that you don't know, don't try to make up an answer.

    Context: {context}

    Chat history: {chat_history}

    Question: {question}
    Helpful Answer:
    """
    prompt = PromptTemplate(
        template=system_template,
        input_variables=["context", "question",  "chat_history"],
    )
    conversation_chain = ConversationalRetrievalChain.from_llm(
        verbose = True,
        llm=llm,
        retriever=vector_store.as_retriever(),
        memory=memory,
        combine_docs_chain_kwargs={"prompt": prompt}
    )
    return conversation_chain
Copier après la connexion

Gestion des requêtes des utilisateurs

Traitez les entrées de l'utilisateur, transmettez-les à la chaîne de conversation et mettez à jour l'historique des discussions.

def handle_user_input(question):
    try:
        response = st.session_state.conversation({'question': question})
        st.session_state.chat_history = response['chat_history']
    except Exception as e:
        st.error('Please select PDF and click on Process.')
Copier après la connexion

Création d'un modèle HTML personnalisé pour un chat simplifié

Pour créer une interface de discussion personnalisée pour les messages des utilisateurs et des robots à l'aide de CSS, concevez des modèles personnalisés et stylisez-les avec CSS.

  • Créez un fichier nommé htmlTemplates.py et ajoutez-y le code suivant.
css = '''
<style>
.chat-message {
    padding: 1rem; border-radius: 0.5rem; margin-bottom: 1rem; display: flex
}
.chat-message.user {
    background-color: #2b313e
}
.chat-message.bot {
    background-color: #475063
}
.chat-message .avatar {
  width: 10%;
}
.chat-message .avatar img {
  max-width: 30px;
  max-height: 30px;
  border-radius: 50%;
  object-fit: cover;
}
.chat-message .message {
  width: 90%;
  padding: 0 1rem;
  color: #fff;
}
'''

bot_template = '''
<div>



<h3>
  
  
  Displaying chat history
</h3>

<p>Show the user and AI conversation history in a reverse order with HTML templates for formatting.<br>
</p>

<pre class="brush:php;toolbar:false">def display_chat_history():
    if st.session_state.chat_history:
        reversed_history = st.session_state.chat_history[::-1]

        formatted_history = []
        for i in range(0, len(reversed_history), 2):
            chat_pair = {
                "AIMessage": reversed_history[i].content,
                "HumanMessage": reversed_history[i + 1].content
            }
            formatted_history.append(chat_pair)

        for i, message in enumerate(formatted_history):
            st.write(user_template.replace("{{MSG}}", message['HumanMessage']), unsafe_allow_html=True)
            st.write(bot_template.replace("{{MSG}}", message['AIMessage']), unsafe_allow_html=True)
Copier après la connexion

Création d'une interface d'application Streamlit

Configurez l'interface principale de l'application pour le téléchargement de fichiers, la saisie de questions et l'affichage de l'historique des discussions.

def main():
    st.set_page_config(page_title='Chat with PDFs', page_icon=':books:')
    st.write(css, unsafe_allow_html=True)

    if "conversation" not in st.session_state:
        st.session_state.conversation = None
    if "chat_history" not in st.session_state:
        st.session_state.chat_history = None

    st.header('Chat with PDFs :books:')

    question = st.text_input("Ask anything to your PDF:")
    if question:
        handle_user_input(question)

    if st.session_state.chat_history is not None:
        display_chat_history()

    with st.sidebar:
        st.subheader("Upload your Documents Here: ")
        pdf_files = st.file_uploader("Choose your PDF Files and Press Process button", type=['pdf'], accept_multiple_files=True)

        if pdf_files and st.button("Process"):
            with st.spinner("Processing your PDFs..."):
                try:
                    # Get PDF Text
                    raw_text = get_pdf_text(pdf_files)
                    # Get Text Chunks
                    text_chunks = get_chunk_text(raw_text)
                    # Create Vector Store
                    vector_store = get_vector_store(text_chunks)
                    st.success("Your PDFs have been processed successfully. You can ask questions now.")
                    # Create conversation chain
                    st.session_state.conversation = get_conversation_chain(vector_store)
                except Exception as e:
                    st.error(f"An error occurred: {e}")

if __name__ == '__main__':
    main()
Copier après la connexion

Code complet pour l'application PDF Chat

Ce qui suit est l'implémentation complète du code pour l'application PDF Chat. Il intègre la configuration des variables d'environnement, l'extraction de texte, le stockage vectoriel et les fonctionnalités RAG dans une solution rationalisée :

from dotenv import load_dotenv
import os
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
OPENAI_MODEL_NAME = os.getenv("OPENAI_MODEL_NAME")
OPENAI_EMBEDDING_MODEL_NAME = os.getenv("OPENAI_EMBEDDING_MODEL_NAME")

import streamlit as st
from PyPDF2 import PdfReader
from langchain.text_splitter import CharacterTextSplitter
from langchain.prompts import PromptTemplate
from langchain_community.embeddings import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
from langchain_community.chat_models import ChatOpenAI
from htmlTemplates import bot_template, user_template, css

def get_pdf_text(pdf_files):
    text = ""
    for pdf_file in pdf_files:
        reader = PdfReader(pdf_file)
        for page in reader.pages:
            text += page.extract_text()
    return text

def get_chunk_text(text):
    text_splitter = CharacterTextSplitter(
        separator="\n",
        chunk_size=1000,
        chunk_overlap=200,
        length_function=len
    )
    chunks = text_splitter.split_text(text)
    return chunks

def get_vector_store(text_chunks):
    embeddings = OpenAIEmbeddings(openai_api_key=OPENAI_API_KEY, model=OPENAI_EMBEDDING_MODEL_NAME)
    vectorstore = FAISS.from_texts(texts=text_chunks, embedding=embeddings)
    return vectorstore

def get_conversation_chain(vector_store):
    llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY, model_name=OPENAI_MODEL_NAME, temperature=0)
    memory = ConversationBufferMemory(memory_key='chat_history', return_messages=True)
    system_template  =  """
    Use  the following pieces of context and chat history to answer the question at the end. 
    If you don't know the answer, just say that you don't know, don't try to make up an answer.

    Context: {context}

    Chat history: {chat_history}

    Question: {question}
    Helpful Answer:
    """
    prompt = PromptTemplate(
        template=system_template,
        input_variables=["context", "question",  "chat_history"],
    )
    conversation_chain = ConversationalRetrievalChain.from_llm(
        verbose = True,
        llm=llm,
        retriever=vector_store.as_retriever(),
        memory=memory,
        combine_docs_chain_kwargs={"prompt": prompt}
    )
    return conversation_chain

def handle_user_input(question):
    try: 
        response = st.session_state.conversation({'question': question})
        st.session_state.chat_history = response['chat_history']
    except Exception as e:
        st.error('Please select PDF and click on OK.')

def display_chat_history():
    if st.session_state.chat_history:
        reversed_history = st.session_state.chat_history[::-1]

        formatted_history = []
        for i in range(0, len(reversed_history), 2):
            chat_pair = {
                "AIMessage": reversed_history[i].content,
                "HumanMessage": reversed_history[i + 1].content
            }
            formatted_history.append(chat_pair)

        for i, message in enumerate(formatted_history):
            st.write(user_template.replace("{{MSG}}", message['HumanMessage']), unsafe_allow_html=True)
            st.write(bot_template.replace("{{MSG}}", message['AIMessage']), unsafe_allow_html=True)

def main():
    st.set_page_config(page_title='Chat with PDFs', page_icon=':books:')
    st.write(css, unsafe_allow_html=True)

    if "conversation" not in st.session_state:
        st.session_state.conversation = None
    if "chat_history" not in st.session_state:
        st.session_state.chat_history = None

    st.header('Chat with PDFs :books:')

    question = st.text_input("Ask anything to your PDF:")
    if question:
        handle_user_input(question)

    if st.session_state.chat_history is not None:
        display_chat_history()

    with st.sidebar:
        st.subheader("Upload your Documents Here: ")
        pdf_files = st.file_uploader("Choose your PDF Files and Press Process button", type=['pdf'], accept_multiple_files=True)

        if pdf_files and st.button("Process"):
            with st.spinner("Processing your PDFs..."):
                try:
                    # Get PDF Text
                    raw_text = get_pdf_text(pdf_files)
                    # Get Text Chunks
                    text_chunks = get_chunk_text(raw_text)
                    # Create Vector Store
                    vector_store = get_vector_store(text_chunks)
                    st.success("Your PDFs have been processed successfully. You can ask questions now.")
                    # Create conversation chain
                    st.session_state.conversation = get_conversation_chain(vector_store)
                except Exception as e:
                    st.error(f"An error occurred: {e}")

if __name__ == '__main__':
    main()

Copier après la connexion

Exécutez l'application

Exécutez l'application avec Streamlit à l'aide de la commande suivante.

streamlit run app.py
Copier après la connexion

Vous obtiendrez le résultat comme suit,
The ultimate guide to Retrieval-Augmented Generation (RAG)

Merci d'avoir lu cet article !!

Merci Gowri M Bhatt d'avoir révisé le contenu.

Si vous avez apprécié cet article, veuillez cliquer sur le bouton cœur ♥ et partager pour aider les autres à le trouver !

Le code source complet de ce tutoriel peut être trouvé ici,

codemaker2015/pdf-chat-using-RAG | github.com

Ressources

  • Automatisation des processus métiers RAG et LLM : Une stratégie technique - Grid Dynamics | www.griddynamics.com
  • Introduction à la génération augmentée de récupération (RAG) | Tisser
  • Techniques, défis et avenir des modèles de langage augmentés - Gradient Flow
  • Génération augmentée de récupération à l'échelle de la planète | Arcus

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal