AGI
Construire des agents LLM pour RAG à partir de zéro et au-delà : un guide complet
Les LLM comme GPT-3, GPT-4 et leurs homologues open source ont souvent du mal à récupérer des informations à jour et peuvent parfois générer des hallucinations ou des informations incorrectes.
La génération augmentée de récupération (RAG) est une technique qui combine la puissance des LLM avec la récupération de connaissances externes. RAG nous permet de baser les réponses des LLM sur des informations factuelles et à jour, améliorant ainsi considérablement la précision et la fiabilité du contenu généré par l’IA.
Dans cet article de blog, nous allons explorer comment construire des agents LLM pour RAG à partir de zéro, en plongeant profondément dans l’architecture, les détails d’implémentation et les techniques avancées. Nous allons couvrir tout, des bases de RAG à la création d’agents sophistiqués capables de raisonnement complexe et d’exécution de tâches.
Avant de plonger dans la construction de notre agent LLM, comprenons ce qu’est RAG et pourquoi il est important.
RAG, ou Génération Augmentée de Récupération, est une approche hybride qui combine la récupération d’informations avec la génération de texte. Dans un système RAG :
- Une requête est utilisée pour récupérer des documents pertinents à partir d’une base de connaissances.
- Ces documents sont ensuite alimentés dans un modèle de langage avec la requête originale.
- Le modèle génère une réponse basée à la fois sur la requête et les informations récupérées.
Cette approche présente plusieurs avantages :
- Précision améliorée : En basant les réponses sur des informations récupérées, RAG réduit les hallucinations et améliore la précision factuelle.
- Informations à jour : La base de connaissances peut être mise à jour régulièrement, permettant au système d’accéder à des informations actuelles.
- Transparence : Le système peut fournir des sources pour ses informations, augmentant la confiance et permettant la vérification des faits.
Comprendre les agents LLM
Lorsque vous rencontrez un problème sans réponse simple, vous devez souvent suivre plusieurs étapes, réfléchir soigneusement et vous souvenir de ce que vous avez déjà essayé. Les agents LLM sont conçus pour ces types de situations dans les applications de modèles de langage. Ils combinent une analyse de données approfondie, une planification stratégique, une récupération de données et la capacité d’apprendre de leurs actions passées pour résoudre des problèmes complexes.
Qu’est-ce qu’un agent LLM ?
Un agent LLM est un système d’IA avancé conçu pour créer du texte complexe qui nécessite un raisonnement séquentiel. Il peut anticiper, se souvenir de conversations passées et utiliser différents outils pour adapter ses réponses en fonction de la situation et du style nécessaire.
Considérons une question dans le domaine juridique telle que : “Quelles sont les conséquences juridiques potentielles d’une violation de contrat spécifique en Californie ?” Un LLM de base avec un système RAG peut récupérer les informations nécessaires à partir de bases de données juridiques.
Pour un scénario plus détaillé : “À la lumière de nouvelles lois sur la protection des données, quels sont les défis juridiques courants auxquels les entreprises sont confrontées et comment les tribunaux ont-ils abordé ces questions ?” Cette question creuse plus profondément que la simple recherche de faits. Il s’agit de comprendre les nouvelles règles, leur impact sur les différentes entreprises et les réponses des tribunaux. Un agent LLM diviserait cette tâche en sous-tâches, telles que la récupération des dernières lois, l’analyse de cas historiques, la synthèse de documents juridiques et la prévision de tendances basée sur des modèles.
Composants des agents LLM
Les agents LLM se composent généralement de quatre composants :
- Agent/Cerveau : Le modèle de langage de base qui traite et comprend le langage.
- Planification : La capacité de raisonner, de diviser les tâches et de développer des plans spécifiques.
- Mémoire : Conserve les traces d’interactions passées et apprend de celles-ci.
- Utilisation d’outils : Intègre diverses ressources pour effectuer des tâches.
Agent/Cerveau
Au cœur d’un agent LLM se trouve un modèle de langage qui traite et comprend le langage en fonction de vastes quantités de données sur lesquelles il a été formé. Vous commencez par lui donner une invite spécifique, guidant l’agent sur la façon de répondre, quels outils utiliser et quels objectifs viser. Vous pouvez personnaliser l’agent avec une personnalité adaptée à des tâches ou interactions particulières, améliorant ainsi ses performances.
Mémoire
Le composant mémoire aide les agents LLM à gérer des tâches complexes en conservant un enregistrement d’actions passées. Il existe deux principaux types de mémoire :
- Mémoire à court terme : Agit comme un bloc-notes, gardant une trace des discussions en cours.
- Mémoire à long terme : Fonctionne comme un journal, stockant des informations à partir d’interactions passées pour apprendre des modèles et prendre de meilleures décisions.
En combinant ces types de mémoire, l’agent peut offrir des réponses plus personnalisées et se souvenir des préférences de l’utilisateur au fil du temps, créant ainsi une interaction plus connectée et pertinente.
Planification
La planification permet aux agents LLM de raisonner, de diviser les tâches en parties gérables et d’adapter les plans à mesure que les tâches évoluent. La planification implique deux principales étapes :
- Formulation de plan : Diviser une tâche en sous-tâches.
- Réflexion sur le plan : Réviser et évaluer l’efficacité du plan, en incorporant les commentaires pour affiner les stratégies.
Des méthodes comme la Chaîne de Pensée (CoT) et l’Arbre de Pensée (ToT) aident dans ce processus de décomposition, permettant aux agents d’explorer différents chemins pour résoudre un problème.
Pour approfondir le monde des agents d’IA, y compris leurs capacités actuelles et leur potentiel, considérez la lecture de “Auto-GPT & GPT-Engineer : Un guide approfondi sur les agents d’IA les plus performants d’aujourd’hui”
Mise en place de l’environnement
Pour construire notre agent RAG, nous devons configurer notre environnement de développement. Nous allons utiliser Python et plusieurs bibliothèques clés :
- LangChain : Pour orchestrer nos composants LLM et de récupération
- Chroma : En tant que magasin de vecteurs pour les embeddings de documents
- Modèles GPT d’OpenAI : En tant que LLM de base (vous pouvez le remplacer par un modèle open source si vous le préférez)
- FastAPI : Pour créer une API simple pour interagir avec notre agent
Commençons par configurer notre environnement :
<p># Créez un nouvel environnement virtuel python -m venv rag_agent_env source rag_agent_env/bin/activate # Sur Windows, utilisez `rag_agent_env\Scripts\activate`</p> <p># Installez les packages requis pip install langchain chromadb openai fastapi uvicorn
Maintenant, créons un nouveau fichier Python appelé rag_agent.py et importons les bibliothèques nécessaires :
<p>from langchain.embeddings import OpenAIEmbeddings from langchain.vectorstores import Chroma from langchain.text_splitter import CharacterTextSplitter from langchain.llms import OpenAI from langchain.chains import RetrievalQA from langchain.document_loaders import TextLoader import os</p> <p># Définissez votre clé API OpenAI os.environ["OPENAI_API_KEY"] = "votre-clé-api-ici"</p>
Construire un système RAG simple
Maintenant que nous avons configuré notre environnement, construisons un système RAG de base. Nous allons commencer par créer une base de connaissances à partir d’un ensemble de documents, puis l’utiliser pour répondre à des requêtes.
Étape 1 : Préparer les documents
Tout d’abord, nous devons charger et préparer nos documents. Pour cet exemple, supposons que nous avons un fichier texte appelé knowledge_base.txt avec certaines informations sur l’IA et l’apprentissage automatique.
<p># Charger le document loader = TextLoader("knowledge_base.txt") documents = loader.load()</p> <p># Diviser les documents en morceaux text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) texts = text_splitter.split_documents(documents)</p> <p># Créer des embeddings embeddings = OpenAIEmbeddings()</p> <p># Créer un magasin de vecteurs vectorstore = Chroma.from_documents(texts, embeddings)</p>
Étape 2 : Créer une chaîne de questions-réponses basée sur la récupération
Maintenant que nous avons notre magasin de vecteurs, nous pouvons créer une chaîne de questions-réponses basée sur la récupération :
<p># Créer une chaîne de questions-réponses basée sur la récupération qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=vectorstore.as_retriever())</p>
Étape 3 : Interroger le système
Nous pouvons maintenant interroger notre système RAG :
<p>query = "Quelles sont les principales applications de l'apprentissage automatique ?" result = qa.run(query) print(result)
Étape 4 : Créer un agent LLM
Alors que notre système RAG simple est utile, il est assez limité. Améliorons-le en créant un agent LLM qui puisse effectuer des tâches plus complexes et raisonnements sur les informations qu’il récupère.
Un agent LLM est un système d’IA qui peut utiliser des outils et prendre des décisions sur les actions à entreprendre. Nous allons créer un agent qui puisse non seulement répondre à des questions mais également effectuer des recherches sur le Web et des calculs de base.
Tout d’abord, définissons quelques outils pour notre agent :
<p>from langchain.agents import Tool from langchain.tools import DuckDuckGoSearchRun from langchain.tools import BaseTool from langchain.agents import initialize_agent from langchain.agents import AgentType</p> <p># Définir un outil de calculatrice class CalculatorTool(BaseTool): name = "Calculatrice" description = "Utiles pour les questions de mathématiques"</p> <p>def _run(self, query: str) try: return str(eval(query)) except: return "Je n'ai pas pu calculer cela. Assurez-vous que votre entrée est une expression mathématique valide."</p> <p># Créer des instances d'outils search = DuckDuckGoSearchRun() calculator = CalculatorTool()</p> <p># Définir les outils tools = [Tool(name="Recherche", func=search.run, description="Utiles pour les questions sur les événements actuels"), Tool(name="RAG-QA", func=qa.run, description="Utiles pour les questions sur l'IA et l'apprentissage automatique"), Tool(name="Calculatrice", func=calculator._run, description="Utiles pour les calculs mathématiques") ]</p> <p># Initialiser l'agent agent = initialize_agent(tools, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True )</p>
Maintenant, nous avons un agent qui peut utiliser notre système RAG, effectuer des recherches sur le Web et des calculs. Testons-le :
<p>result = agent.run("Quelle est la différence entre l'apprentissage supervisé et non supervisé ? Et qu'est-ce que 15 % de 80 ?") print(result)</p>
Cet agent démontre un avantage clé des agents LLM : ils peuvent combiner plusieurs outils et étapes de raisonnement pour répondre à des requêtes complexes.
Améliorer l’agent avec des techniques RAG avancées
Alors que notre système RAG actuel fonctionne bien, il existe plusieurs techniques avancées que nous pouvons utiliser pour améliorer ses performances :
a) Recherche sémantique avec récupération de passages denses (DPR)
Au lieu d’utiliser une récupération basée sur des embeddings simples, nous pouvons mettre en œuvre le DPR pour une recherche sémantique plus précise :
<p>from transformers import DPRQuestionEncoder, DPRContextEncoder</p> <p>question_encoder = DPRQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base") context_encoder = DPRContextEncoder.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base")</p> <p># Fonction pour encoder les passages def encode_passages(passages): return context_encoder(passages, max_length=512, return_tensors="pt").pooler_output</p> <p># Fonction pour encoder la requête def encode_query(query): return question_encoder(query, max_length=512, return_tensors="pt").pooler_output</p>
b) Expansion de requête
Nous pouvons utiliser l’expansion de requête pour améliorer les performances de récupération :
<p>from transformers import T5ForConditionalGeneration, T5Tokenizer</p>
<p>model = T5ForConditionalGeneration.from_pretrained("t5-small")
tokenizer = T5Tokenizer.from_pretrained("t5-small")</p>
<p>def expand_query(query):
input_text = f"expand query: {query}"
input_ids = tokenizer.encode(input_text, return_tensors="pt")
outputs = model.generate(input_ids, max_length=50, num_return_sequences=3)
expanded_queries = [tokenizer.decode(output, skip_special_tokens=True) for output in outputs]
return expanded_queries</p>
c) Affinement itératif
Nous pouvons mettre en œuvre un processus d’affinement itératif où l’agent peut poser des questions de suivi pour clarifier ou élargir sa récupération initiale :
<p>def iterative_retrieval(initial_query, max_iterations=3):
query = initial_query
for _ in range(max_iterations):
result = qa.run(query)
clarification = agent.run(f"Basé sur ce résultat : '{result}', quelle question de suivi devrais-je poser pour obtenir des informations plus spécifiques ?")
if clarification.lower().strip() == "none":
break
query = clarification
return result</p>
# Utilisez cela dans le processus de votre agent
Mise en œuvre d’un système multi-agents
Pour gérer des tâches plus complexes, nous pouvons mettre en œuvre un système multi-agents où différents agents se spécialisent dans différents domaines. Voici un exemple simple :
<p>class SpecialistAgent:
def __init__(self, name, tools):
self.name = name
self.agent = initialize_agent(tools, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)</p>
<p>def run(self, query):
return self.agent.run(query)</p>
<p># Créer des agents spécialisés
research_agent = SpecialistAgent("Recherche", [Tool(name="RAG-QA", func=qa.run, description="Pour les questions sur l'IA et l'apprentissage automatique")])
math_agent = SpecialistAgent("Mathématiques", [Tool(name="Calculatrice", func=calculator._run, description="Pour les calculs")])
general_agent = SpecialistAgent("Général", [Tool(name="Recherche", func=search.run, description="Pour les requêtes générales")])</p>
<p>class Coordinator:
def __init__(self, agents):
self.agents = agents</p>
<p>def run(self, query):
# Déterminez quel agent utiliser
if "calculate" in query.lower() or any(op in query for op in ['+', '-', '*', '/']):
return self.agents['Mathématiques'].run(query)
elif any(term in query.lower() for term in ['ai', 'apprentissage automatique', 'apprentissage profond']):
return self.agents['Recherche'].run(query)
else:
return self.agents['Général'].run(query)</p>
<p>coordinator = Coordinator({'Recherche': research_agent, 'Mathématiques': math_agent, 'Général': general_agent})</p>
<p># Tester le système multi-agents
result = coordinator.run("Quelle est la différence entre CNN et RNN ? Et calculez 25 % de 120.")
print(result)</p>
Ce système multi-agents permet une spécialisation et peut gérer un plus large éventail de requêtes de manière plus efficace.
Évaluation et optimisation des agents RAG
Pour nous assurer que notre agent RAG fonctionne bien, nous devons mettre en œuvre des métriques d’évaluation et des techniques d’optimisation :
a) Évaluation de la pertinence
Nous pouvons utiliser des métriques telles que BLEU, ROUGE ou BERTScore pour évaluer la pertinence des documents récupérés :
from bert_score import score <p>def evaluate_relevance(query, retrieved_doc, generated_answer): P, R, F1 = score([generated_answer], [retrieved_doc], lang="en") return F1.mean().item()</p>
b) Évaluation de la qualité de la réponse
Nous pouvons utiliser une évaluation humaine ou des métriques automatisées pour évaluer la qualité de la réponse :
<p>from nltk.translate.bleu_score import sentence_bleu</p> <p>def evaluate_answer_quality(reference_answer, generated_answer): return sentence_bleu([reference_answer.split()], generated_answer.split())</p> <p># Utilisez cela pour évaluer les réponses de votre agent
Directions et défis futurs
Alors que nous regardons vers l’avenir des agents RAG, plusieurs directions et défis excitants émergent :
a) RAG multi-modal : Étendre le RAG pour incorporer des données d’image, audio et vidéo.
b) RAG fédéré : Mettre en œuvre le RAG sur des bases de connaissances distribuées et préservant la confidentialité.
c) Apprentissage continu : Développer des méthodes pour que les agents RAG mettent à jour leurs bases de connaissances et leurs modèles au fil du temps.
d) Considérations éthiques : Aborder les préjugés, l’équité et la transparence dans les systèmes RAG.
e) Scalabilité : Optimiser le RAG pour les applications à grande échelle et en temps réel.
Conclusion
Construire des agents LLM pour RAG à partir de zéro est un processus complexe mais gratifiant. Nous avons couvert les bases de RAG, mis en œuvre un système simple, créé un agent LLM, amélioré celui-ci avec des techniques avancées, exploré les systèmes multi-agents et discuté les stratégies d’évaluation et d’optimisation.














