DEV Community

Cover image for Agrega consulta de documentos a tu Asistente de IA Generativa
ensamblador for AWS Español

Posted on

Agrega consulta de documentos a tu Asistente de IA Generativa

  1. Introducción
  2. Pre requisitos
  3. Lanzar la aplicación de IA Conversacional
  4. Flujo de procesamiento de documentos
  5. Uso de los documentos en la consulta
  6. Secuencia de Ejecución de RAG
  7. Conclusiones y siguientes pasos



Introducción

Desde manuales de usuario, reportes técnicos e informes de investigación, hasta contratos legales y transcripciones de llamadas, las empresas acumulan una enorme cantidad de contenido en formato de texto no estructurado. Procesar y extraer conocimiento útil de estos documentos suele ser una tarea tediosa y propensa a errores cuando se hace manualmente. Además, encontrar y recuperar información específica entre cientos o miles de documentos puede ser como buscar una aguja en un pajar.

En este artículo, complementarás el asistente de IA conversacional para ayudar a resolver estos desafíos. Utilizando técnicas de búsqueda semántica en documentos utilizando modelos embeddings como Amazon Titan y procesamiento con LLM como Anthropic Claude en Amazon Bedrock.

Manos a la obra!

Pre requisitos:

Para usar esta aplicación deberas contar con un usuario aws con permisos para usar Bedrock, un perfil local con ese usuario y python3. Aca puedes encontrar los pre requisitos.
Asegúrate de poder ejecutar en la aws cli antes de avanzar:

aws bedrock list-foundation-models
Enter fullscreen mode Exit fullscreen mode

Instrucciones para lanzar la aplicación IA Conversacional

Clonar repositorio

Clona este repositorio y accede a la carpeta:

git clone https://github.com/ensamblador/generative-ai-chat-application.git
cd generative-ai-chat-application/03-personal-assistant-add-data
Enter fullscreen mode Exit fullscreen mode

Configuración del entorno virtual

Esto es un entorno independiente de tu entorno python principal, todo lo que instalas en este entorno venv quedará en la carpeta .venv

Crea y activa entorno virtual con sus dependencias:

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

Lanzar la aplicación

Inicia la aplicación del asistente (puedes elegir el puerto con --server.port):

streamlit run chatbot_app.py --server.port 80
Enter fullscreen mode Exit fullscreen mode

La aplicación estará disponible en http://localhost:80




Flujo de carga de documentos

En este proyecto puedes incorporar tres tipos de documentos: pdf, transcripciones de youtube y sitios web. Puede revisar una lista extensiva de loaders acá.

Documentos pdf

Cuando carga la aplicación veremos un nuevo menú lateral load documents. Ahi podemos seleccionar un archivo pdf cualquiera y cargamos, escribimos un nombre para la colección y le damos al botón Submit

carga documento

Nota: el gif está acelerado, tomó aproximadamente 5 minutos procesar el archivo.

El procesamiento de los documentos para ser utilizados por el asistente se realiza de la siguiente manera

  1. El usuario carga archivos PDF a través de un componente File Loader de Streamlit

pages/load_documents.py

uploaded_files = st.file_uploader("Elija documentos (pdf)", accept_multiple_files=True)
Enter fullscreen mode Exit fullscreen mode
  1. Los PDFs se cargan con PyPDFLoader y se procesan para dividirlos en pasajes individuales

Es decir, obtenermos un documento dividido por splitby caracteres (definidos en los parámetros de side bar), con un overlap de 10% aproximadamente.

vdb_lib.py

def load_and_split_pdf(file_path, splitby):

    text_splitter = RecursiveCharacterTextSplitter(
        separators=["\n\n", "\n", "\. ", " ", ""],
        chunk_size=splitby,
        chunk_overlap=int(splitby/10),
        length_function=len
    )

    loader = PyPDFLoader(file_path)
    docs = loader.load_and_split(text_splitter)
    return docs
Enter fullscreen mode Exit fullscreen mode
  1. Cada una de las partes se procesan por un modelo que convierte texto a vectores, llamados embeddings, lo cual permite calcular distancia entre un texto de otro.

Para la base de vectores utilizamos ChromaDB dado que nos brinda la posibilidad de guardar nuestra base de datos de forma local. Te invito a revisar otras opciones que se pueden integrar como un vector database en langchain.

Para el uso en la aplicación creamos una clase de python que se encarga de inicializar, crear, almacenar y devolver las bases vectores.


bedrock_embeddings = BedrockEmbeddings(model_id="amazon.titan-embed-text-v1")


class CustomChromaClass():
    def __init__(self) -> None:
        if is_local: chroma_path = f"{user_name}/chroma"
        else: chroma_path = f"{volume}/{user_name}/chroma"
        # chroma (lowercase) client
        self.persistent_client = chromadb.PersistentClient(path=chroma_path)
        collections = self.persistent_client.list_collections()
        self.vectordbs = {}

        for collection in collections:
            langchain_chroma = Chroma(
                client=self.persistent_client,
                collection_name=collection.name, 
                embedding_function=bedrock_embeddings
            )
            print(collection.name,":",langchain_chroma._collection.count())
            self.vectordbs[collection.name] = langchain_chroma
        self.vectordb = False

    def create_vectordb(self, name):
        name =  clean_name(name)
        # Chroma (capital C) is langchain chroma wrapper
        vectordb = Chroma(
            client=self.persistent_client,
            embedding_function = bedrock_embeddings,
            collection_name=name
        )
        self.vectordbs[name] = vectordb
        self.vectordb = vectordb
        return vectordb

    def get_vectordb(self, name):
        return self.vectordbs[name]

    def add_docs(self, collection_name, docs, n=10):
        add_docs_by_chunks(self.vectordbs[collection_name], docs, n)

Enter fullscreen mode Exit fullscreen mode

En el siguiente diagrama se muestra el proceso completo.

diagrama de ingesta de documentos

Carga de sitios webs

Como ven, podemos utilizar el mismo concepto para cargar un sitio web completo. Ahora utilizamos WebBaseLoader (basado en Beautiful Soup y Requests) para cargar todo el texto útil de un sitio web en una base de vectores.

from langchain.document_loaders import WebBaseLoader
...
loader = WebBaseLoader(url)
Enter fullscreen mode Exit fullscreen mode

load website

Carga de transcripciones de videos Youtube

Para cargar un video de youtube, tenemos que extraer la transcripción . Ahora utilizamos YoutubeLoader que utiliza youtube-transcript-api para obtener las transcripciones o subtítulos existentes de un video de Youtube.

from langchain.document_loaders import YoutubeLoader
...
loader = YoutubeLoader.from_youtube_url(video_url, add_video_info=True )
Enter fullscreen mode Exit fullscreen mode

load youtube




Uso de los documentos en la consulta

Para consultar la base de datos vectorial, la aplicación busca pasajes similares al texto ingresado como consulta, utilizando la similitud entre embeddings. Luego utiliza estas partes como contexto para reponder. Esta técnica es conocida como Retrieval Augmented Generation. Problemos algunas consultas:

de Bedrock User Guide:

(asegura de hacer click en alguna base de conocimiento disponible que hayas cargado)

Input: cual es la diferencia entre ajuste fino de modelo y continuar el pre entrenamiento?

Consulta

La aplicación se encarga de manejar la conexión a ChromaDB, ejecutar las consultas y retornar los resultados en texto para que el LLM genere la respuesta. Incluso podemos hacer preguntas de clarificación, gracias a la memoria que posee nuestro asistente:

Input: explícamelo mejor, como una analogía de la vida real

Consulta

Podemos consultar otras bases creadas, por ejemplo la transcripción del video Youtube cargado (best apps for productivity):

Input: what apps are mentioned and what do they do?

Consulta

Veamos que nos puede decir del blog que agregamos

de: Welcome to a New Era of Building in the Cloud with Generative AI on AWS

Input: what whas announced around generative ai?

Consulta

Además se pueden combinar varias collections en una sola pregunta. Intentalo.

Secuencia de ejecución de RAG

A continuación vemos la secuencia cuando utilizamos RAG en nuestra pregunta.

secuencia consulta

El wrapper de chroma en langchain nos permite utilizar la base de vectores como un retriever, como vemos en vdb_lib.py

def get_retriever(name):
     if 'chroma_client' in st.session_state:
        vector_db = st.session_state.chroma_client.vectordbs[name]
        return vector_db.as_retriever(search_type = "mmr",  search_kwargs={"k": 10})
Enter fullscreen mode Exit fullscreen mode

Nota: el retriever utiliza mmr (relevancia maxima margina) una forma de decir que no queremos documentos muy similares o repetidos.

Finalmente, utilizamos ConversationalRetrievalChain de Lanchain para procesar todo: el retriever, la memoria y la historia dentro de la conversación.

En chatbot_lib.py se invocará ConversationalRetrievalChain ConversationChain dependiendo si vamos a usar o no alguna colección de chroma.

def get_chat_rag_response(prompt, retriever, memory, streaming_callback=None, invocation_kwargs=None, model_id= None):

    llm = get_llm(streaming_callback, invocation_kwargs, model_id) 
    qa = ConversationalRetrievalChain.from_llm(
        llm,
        verbose=True,
        retriever=retriever,
        memory=memory,
        get_chat_history=lambda h : h # workaround dado que utilizamos la misma memoria para RetrievalChain y ConversationChain
    ) 
    return qa.run({"question": prompt})
Enter fullscreen mode Exit fullscreen mode

Ahora nuestro asistente no solo nos sugiere texto sino que también conoce de nuestros documentos y es capaz de responder utilizando la información relevante de ellos. Lo puedes utilizar para saber que existe detrás de toda esa información en un instante.

how cool is that!




Conclusiones y siguientes pasos

En esta sesión, tomamos el Asistente de IA generativo y lo supercargamos con búsqueda semántica y RAG para responder preguntas encontrando pasajes relevantes en los documentos. A partir de aquí, puedes seguir construyendo sobre esta base de muchas maneras:

Recomendacion para estudio adicional

Stay tuned!

Acerca de los autores:

Top comments (0)