QA AI Bot avec un LLM local et des documents

Traduit de l'original en espagnol. Lire en espagnol

Dans ce tutoriel, nous allons apprendre à créer un bot de questions-réponses (QA Bot) en Python avec un Large Language Model (LLM) local et des documents stockés dans un dossier.

iStock AI Generator

Prérequis

Pour commencer, assurez-vous d’avoir installé les bibliothèques suivantes en exécutant ces commandes dans votre terminal :

pip install chromadb
pip install langchain
pip install transformers
pip install -U langchain-community

Charger les documents

Fonction de lecture des documents

Nous allons définir une fonction qui lit des documents depuis un répertoire à l’aide de DirectoryLoader.

from langchain_community.document_loaders import DirectoryLoader
from langchain_community.document_loaders import TextLoader

def load_docs(directory):
    loader = DirectoryLoader(directory, glob="**/*.txt", loader_cls=TextLoader)
    documents = loader.load()
    return documents

Ensuite, nous passons le répertoire à la fonction load_docs pour charger les documents.

directory = 'Docs/'
documents = load_docs(directory)

Découper les documents en fragments

Pour rendre le traitement plus efficace, nous découperons les documents en fragments plus petits.

from langchain.text_splitter import RecursiveCharacterTextSplitter

def split_docs(documents, chunk_size=1000, chunk_overlap=20):
  text_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
  docs = text_splitter.split_documents(documents)
  return docs

docs = split_docs(documents)

Initialiser les embeddings et la base de données vectorielle

Nous initialisons la classe SentenceTransformerEmbeddings, puis créons une base de données vectorielle avec Chroma.

from langchain_community.embeddings.sentence_transformer import SentenceTransformerEmbeddings
from langchain_community.vectorstores import Chroma

embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")

Ensuite, nous initialisons Chroma avec les documents et les embeddings.

persist_directory = "zero"
vectordb = Chroma.from_documents(
    documents=docs, embedding=embeddings, persist_directory=persist_directory
)

Fin du chargement des documents

Nous chargeons les documents depuis le répertoire persistant et obtenons un objet retriever.

vectordb = Chroma(persist_directory=persist_directory, embedding_function=embeddings)
vectordb.get()
retriever = vectordb.as_retriever(search_type="similarity", search_kwargs={"k": 2})

Création du bot de questions-réponses

Nous utiliserons le pipeline de transformers pour créer notre QA Bot.

from transformers import pipeline

question_answerer = pipeline("question-answering", model='distilbert-base-cased-distilled-squad')

Formater les documents récupérés

Nous définissons une fonction pour formater les documents renvoyés par le retriever.

def format_docs(docs):
    if docs:
        return "\n\n".join(doc.page_content for doc in docs)

Interaction avec le bot

Nous affichons un message de bienvenue et créons une boucle pour interagir avec le bot.

print("\033[92m" + "¡Bienvenido al Bot de QA AI ZEROGAP!" + "\033[0m")
print("\033[92m" + "###############################" + "\033[0m")
print("\033[92m" + "###############################" + "\033[0m")
print("\n")
while True:
    question = input("\033[93m" + "Tú: " + "\033[0m")
    print("\n")
    if question == "quit":
        break
    context = retriever.invoke(question)
    formated_context = format_docs(context)
    result = question_answerer(question=question, context=formated_context)

    print("\033[92m" + result['answer'] + "\033[0m")
    print("\n")

Code complet

Voici le code complet utilisé dans ce tutoriel :

from langchain_community.document_loaders import DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_community.document_loaders import TextLoader
from langchain_community.embeddings.sentence_transformer import SentenceTransformerEmbeddings
from transformers import pipeline

def load_docs(directory):
    loader = DirectoryLoader(directory, glob="**/*.txt", loader_cls=TextLoader)
    documents = loader.load()
    return documents

directory = 'Docs/'
documents = load_docs(directory)

def split_docs(documents, chunk_size=1000, chunk_overlap=20):
  text_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
  docs = text_splitter.split_documents(documents)
  return docs

docs = split_docs(documents)

embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")

persist_directory = "zero"
vectordb = Chroma.from_documents(
    documents=docs, embedding=embeddings, persist_directory=persist_directory
)

vectordb = Chroma(persist_directory=persist_directory, embedding_function=embeddings)
vectordb.get()
retriever = vectordb.as_retriever(search_type="similarity", search_kwargs={"k": 2})

question_answerer = pipeline("question-answering", model='distilbert-base-cased-distilled-squad')

def format_docs(docs):
    if docs:
        return "\n\n".join(doc.page_content for doc in docs)

print("\033[92m" + "¡Bienvenido al Bot de QA AI ZEROGAP!" + "\033[0m")
print("\033[92m" + "###############################" + "\033[0m")
print("\033[92m" + "###############################" + "\033[0m")
print("\n")
while True:
    question = input("\033[93m" + "Tú: " + "\033[0m")
    print("\n")
    if question == "quit":
        break
    context = retriever.invoke(question)
    formated_context = format_docs(context)
    result = question_answerer(question=question, context=formated_context)

    print("\033[92m" + result['answer'] + "\033[0m")
    print("\n")

Avec ce code, vous pouvez créer votre propre bot de questions-réponses à partir de documents locaux et d’un LLM. Essayez de le personnaliser et de l’enrichir selon les besoins de votre projet !

Maximiliano Díaz Doglia

AI Platform Engineer & Full-Stack Developer
Building Enterprise Integrations & Automations

Publié dans : IA