QA AI Bot con un LLM locale e documenti

Tradotto dall'originale in spagnolo. Leggi in spagnolo

In questo tutorial impareremo a costruire un bot di domande e risposte (QA Bot) in Python usando un Large Language Model (LLM) locale e documenti salvati in una cartella.

iStock AI Generator

Prerequisiti

Per iniziare, assicurati di aver installato le seguenti librerie eseguendo questi comandi nel terminale:

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

Caricare i documenti

Funzione per leggere i documenti

Definiamo una funzione che legge i documenti da una cartella usando 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

Poi passiamo la cartella alla funzione load_docs per caricare i documenti.

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

Dividere i documenti in frammenti

Per rendere l’elaborazione più efficiente, divideremo i documenti in frammenti più piccoli.

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)

Inizializzare gli embedding e il database vettoriale

Inizializziamo la classe SentenceTransformerEmbeddings e poi creiamo un database vettoriale con Chroma.

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

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

Quindi inizializziamo Chroma con i documenti e gli embedding.

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

Completare il caricamento dei documenti

Carichiamo i documenti dalla cartella persistente e otteniamo un oggetto retriever.

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

Creare il bot di domande e risposte

Useremo la pipeline di transformers per creare il nostro QA Bot.

from transformers import pipeline

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

Formattare i documenti recuperati

Definiamo una funzione per formattare i documenti restituiti dal retriever.

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

Interagire con il bot

Stampiamo un messaggio di benvenuto e creiamo un ciclo per interagire con il 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")

Codice completo

Ecco il codice completo usato in questo tutorial:

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")

Con questo codice puoi creare il tuo bot di domande e risposte usando documenti locali e un LLM. Prova a personalizzarlo e ad ampliarlo in base alle esigenze del tuo progetto!

Maximiliano Díaz Doglia

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

Pubblicato in: IA