IA Generativa (GenAI)

Del concepto al código: LLM + RAG con Couchbase

Las tecnologías GenAI son sin duda un elemento de tendencia en 2023 y 2024, y como trabajo para  Tikalque publica su propio informe anual radar tecnológico y tendencias report, LLM y genAI no escaparon a mi atención. Como desarrollador, a menudo consulto chatbots de IA generativa para que me ayuden a resolver todo tipo de errores de TypeScript y misteriosos problemas de linting, utilizo herramientas de asistencia de genAI en mi IDE y para mejorar mis PR. Esta tecnología puede cambiarnos la vida.

Como técnicos y, en definitiva, como desarrolladores de software, esta nueva tendencia nos brinda la oportunidad de integrar estas capacidades en todos los proyectos en los que trabajamos, y veo que mis amigos y colegas exploran estas opciones, lo que me llevó a tomar la decisión: ¡yo también debería hacerlo!

Y tenía justo el proyecto:

A menudo me pregunto cómo pueden los artistas aficionados explorar el amplio mundo de los eventos culturales locales y mundiales para llegar a conseguir esa deseada invitación para actuar. No tenemos los recursos, las conexiones y el conocimiento de todo lo disponible. Claro que hay motores de búsqueda y sitios web especializados, pero hay que saber qué y cómo buscar, así que decidí utilizar genAI para obtener recomendaciones.

Paso 1 - ¿Se puede hacer?

Comprobar la viabilidad de un motor de recomendación utilizando uno de los LLM, incluía abrir cuentas en varios servicios de chat genAI y hacerles la misma pregunta:

Somos una aficionado Danza folclórica israelí grupo, incluidos bailarines en sillas de ruedas. Buscamos cultural y folclore eventos y festivales en Europa la posibilidad de que nos inviten a actuar, siempre y cuando cubrir nuestros gastos. ¿Podría recomendarme algunos?

Los resultados en H1 de 2024 variaron entre los distintos servicios de chat:

    • Me remitieron a sitios web especializados que podía consultar para obtener resultados
    • Me dio resultados reales

De entre los que devolvieron resultados, califiqué la calidad de los resultados por su relevancia y precisión, y acabé con OpenAI GPT-3 como opción.

Paso 2 - ¿Es suficiente?

Recordando que incluso uno de los asistentes de chat del paso 1 me sugirió que consultara otros sitios web, ¿qué pasaría si pudiera incluir algunos de esos datos en los resultados?

Teniendo en cuenta que también dependo de quién y cuándo se entrenó el modelo, quería que mis recomendaciones se basaran en más fuentes de datos y sabía que se podía hacer con RAG. En primer lugar, ¿qué es RAG?

Generación de Recuperación Aumentada (RAG)

RAG es el proceso de enriquecer y optimizar los resultados que recibe de LLM añadiendo datos "externos". Si puedo añadir resultados basados en la misma búsqueda en fuentes de datos externas (de sitios web dedicados) puedo ampliar la variedad de los resultados que proporcionará mi aplicación.

Para ello necesitarás:

    • Fuentes de datos externas - Para mi experimento creé una cuenta de prueba para API de eventos de predictHQ
    • Almacenar mis datos externos es un motor que permite la búsqueda por similitud y no una coincidencia exacta

Accesibilidad de los datos para el GAR

Una vez que haya terminado de examinar los datos, su aspecto y las características que contienen, es hora de que seleccione las características de los datos que le gustaría utilizar y hacerlas utilizables para el GAR.

Para permitir una búsqueda de similitudes, tendríamos que transformar nuestros datos en un formato que permita realizar búsquedas y comparable. Dado que no buscamos coincidencias exactas, sino coincidencias similares, existen dos técnicas muy comunes para ello:

Técnica RAG Detalles
Búsqueda vectorial (también conocida como RAG común) Los datos y la pregunta se transforman en vectores de números (puntos flotantes).

Se utilizan cálculos matemáticos para determinar la similitud entre la pregunta y los datos.

GraphRAG Los datos y la pregunta se transforman en gráfico vértices y aristas.

Las relaciones gráficas se comparan por similitud

El proceso de creación de la representación de los datos se denomina incrustaciónEn este artículo nos centraremos en la búsqueda vectorial.

Métrica de similitud

Hay 3 opciones comunes (en pocas palabras):

    • Producto de puntos: Cálculo de la similitud a partir del producto de los valores de cada vector.
    • Coseno: Basado en el ángulo entre los vectores
    • L2_norm: Distancia euclidiana entre los vectores, basada en el ángulo entre los vectores y la longitud de cada vector.

Más información opciones de similitud vectorial.

Paso 3 - ¿Cómo lo hago?

Antes de sumergirnos en cómo vamos a hacer esto y en algo de código real y capturas de pantalla, veamos cómo se construiría tal arquitectura, y cómo Couchbase entra en escena:

 



Lo que esto significa en la práctica es:

    • Ingestión app to:
      1. Obtener datos de la API externa
      2. Crear incrustaciones vectoriales
      3. Cargar datos en una colección Couchbase
    • Crear un índice de búsqueda vectorial en Couchbase
    • Solicitud inmediata a:
      1. Pedir resultados a los datos de Couchbase
      2. Añadir los resultados de la búsqueda vectorial a la consulta LLM como contexto
      3. Devolver los resultados cohesionados a los usuarios

Aplicación por ingestión

Este proceso fue probablemente el más largo, pasé tiempo creando incrustaciones en distintos campos y formatos. Por simplicidad, al final opté por utilizar únicamente la información geográfica que había recopilado:

Para crear la incrustación elegí utilizar incrustaciones textuales como punto de partida, es decir, "comparar" representación de texto con representación de texto. La incrustación en sí incluye aproximadamente 1500 números (que es el pequeño).

El código en sí no es extremadamente complejo, sin embargo puede llevar mucho tiempo, crear 1 incrustación para 5000 eventos me llevó aproximadamente 1 hora en mi MacBook pro M1 de 16 GB.

El código completo utilizando pandas2 puede encontrarse en este repositorio.

Colección Couchbase e índice de búsqueda

Para poder buscar datos similares entre la pregunta y los resultados que hemos preparado basándonos en una API externa, vamos a...

    1. Crear una colección Couchbase
    2. Sube los datos preparados a una colección de Couchbase incluidas las incrustaciones
    3. Crear un índice de búsqueda en los campos de incrustación eligiendo el algoritmo de similitud vectorial para comparar vectores.

Nueva colección Couchbase

Para mi aplicación elegí utilizar el servicio alojado Couchbase - Capella, la configuración es muy fácil. Me registré, elegí el servicio Cloud y creé un nuevo proyecto.

Al hacer clic en mi proyecto y navegar hasta la pestaña Herramientas de datos, ahora puedo crear una nueva colección para los datos que he preparado:

Para subir los datos que preparé hay varias opciones: como el tamaño del archivo era bastante grande opté por utilizar la opción cbimport utilidad de hacerlo.

Observe que he elegido el ID de los documentos JSON para que sea el documento clave en la colección.

Recuerde que antes de hacerlo, es necesario:

    • Cree un usuario/contraseña de acceso a la base de datos con privilegios de escritura como mínimo
    • Abrir el cluster para llamadas desde su host
    • Descargar un certificado para el clúster

El esquema del documento inferido muestra que el incrustación con el tipo de matriz de números:

Para permitir la búsqueda por similitud vectorial, creemos el índice de búsqueda accediendo a la pestaña Búsqueda.

Obviamente debemos seleccionar el campo de incrustación para el índice de búsqueda, pero observe que hay más parámetros que configurar:

Ya hemos discutido lo que la métrica de similitud es, sólo tenga en cuenta que Couchbase apoyo l2_norm (es decir, la distancia euclidiana) y el producto punto, elegí "producto punto"que puede ser más beneficioso para mi sistema de recomendación.

El siguiente paso consiste en elegir campos adicionales de los documentos que se devolverían siempre que se atenúe un vector similar a la pregunta:

Si no añade al menos un campo, su aplicación fallará porque no habrá ningún dato devuelto.

Ahí está, la selección de campos índice:

Hemos llegado a un punto crucial en nuestro proyecto, ahora podemos empezar a ejecutar la búsqueda de similitud en los datos que hemos preparado, pero puede que no tengas una búsqueda de similitud que funcione en tu primer intento. Le daré algunos consejos para obtener resultados de su búsqueda de similitud o para comprobar por qué no obtiene resultados:

    • Asegúrese de que su técnica de incrustación, al crear los datos y preparar una búsqueda son idénticos
    • Comience con un formato sencillo y predecible para la información que desea comparar. Por ejemplo , , .
    • Asegúrese de que no tiene información adicional que se añade accidentalmente a los datos que está creando incrustaciones para (por ejemplo, tuve saltos de línea)
    • Asegúrese de que la búsqueda de coincidencia exacta funciona:
      • Búsqueda de los datos exactos para los que creó incrustaciones
      • Compare el vector de incrustación para asegurarse de que se crean incrustaciones idénticas en la parte de generación y búsqueda (la depuración será útil aquí). Si hay alguna diferencia, vuelva a los pasos 1-3.

Una vez que tenga una búsqueda por similitud que funcione, añada gradualmente más campos, cambie formatos, incrustaciones y cualquier otra cosa que considere que falta.

Recuerde que cualquier cambio en las incrustaciones significa:

    1. Recrear las incrustaciones
    2. Carga de los datos de los cambios en una colección truncada
    3. Cambiar el índice de búsqueda si es necesario
    4. Es necesario cambiar el código

Estos pasos pueden llevar mucho tiempo, especialmente la creación de incrustaciones, por lo que es posible que desee comenzar con:

    • Una pequeña parte de sus documentos
    • Una técnica de incrustación pequeña/rápida

LLM y solicitud de RAG

Lo que nuestra aplicación necesita hacer es:

    1. Pedir a Couchbase que encuentre resultados similares a la pregunta del usuario
    2. Añade los resultados al contexto de la pregunta al LLM
    3. Haz una pregunta al LLM

Para simplificar he creado este código en Python como un cuaderno Jupyter que se puede encontrar en este repositorio. Para ello he utilizado las siguientes bibliotecas:

    1. Couchbase: Conectar y autenticar a mi clúster Capella
    2. Cadena LangChainun marco para el desarrollo de aplicaciones basadas en grandes modelos lingüísticos (LLM), para:
      1. Incrustaciones
      2. Uso de Couchbase como almacén de vectores
      3. "Chateando" con OpenAI
    3. LangGraph: Un marco para la construcción de aplicaciones LLM con estado y multiactores, para la creación de un flujo de la aplicación LLM.

Si has estado leyendo sobre, e incluso intentando construir tu propia aplicación LLM probablemente estés algo familiarizado con LangChain, es un conjunto de librerías que te permiten escribir, construir, desplegar y monitorizar una aplicación, tiene muchos agentes y extensiones que te permiten integrar diferentes partes en tu código, como una API de terceros, una base de datos, una búsqueda web y muchas más.

Últimamente, también aprendí sobre LangGraph del hogar de LangChain, que te permite como desarrollador construir topologías más complejas de la aplicación LLM con condiciones, bucles (¡el grafo no tiene que ser un DAG!), interacción del usuario, y quizás la característica más buscada: Mantener el estado.

Antes de ver el código echemos un vistazo al archivo de entorno (.env) para ver qué credenciales y otros datos confidenciales necesitamos:

El estado de cada nodo del grafo es:

Es importante tener en cuenta que a menos que se defina un reductor el estado se sobrescribirá entre cada nodo del gráfico, el miembro messages de la clase state tiene un reductor que añadirá los nuevos mensajes a la lista.

Para conectarnos a Couchbase y usarlo como almacén de vectores para la aplicación LLM, nos autenticamos en el cluster, y pasamos la conexión del cluster al objeto LangChain para el almacén de vectores:

Hay dos detalles importantes a tener en cuenta:

    • La integración en la aplicación debe ser idéntico al utilizado en la parte de ingestión
    • El nombre por defecto del campo de incrustación es 'incrustación', si el nombre del campo respectivo es diferente en su índice de búsqueda necesita establecerlo durante la instanciación de CouchbaseVectorStore (embedding_key)

En este momento, estás listo para escribir tu aplicación LangGraph y usar Couchbase como almacén de vectores. Vamos a montarlo: cada grafo necesita nodos, punto de inicio y aristas dirigidas.

Nuestro gráfico obtendrá datos del almacén de vectores y continuará añadiendo esta información al contexto de la solicitud LLM.

Se traduce en el código anterior a dos nodos:

    1. vector_search (punto de entrada)
    2. chatbot (punto final)

Como una imagen vale más que mil palabras, he utilizado el siguiente código para visualizar el gráfico:

Lo que dio lugar al siguiente dibujo:

Para más opciones de visualización en langGraph, véase este Cuaderno Jupyter de LangGraph.

Preguntar al almacén vectorial significa buscar datos con una ubicación similar, puede observar que el formato de la consulta es el mismo que en el texto incrustado, los resultados se añaden al estado para ser utilizados en el siguiente nodo.

El nodo del chatbot toma la información de los mensajes y la incrusta en la pregunta dirigida al LLM.

Tenga en cuenta que el estado se guarda en la base de datos en memoria sqlite. Para utilizar el gráfico no dude en utilizar el siguiente ejemplo:

Y ya está, has creado una aplicación LLM para recomendar eventos culturales a grupos de aficionados a los que pedir invitaciones.

Resumen

Comenzar con las aplicaciones LLM es emocionante y, en mi humilde opinión, como una rampa divertida, emocionante y factible debido a su pronta naturaleza, sin embargo, hacer que nuestra aplicación sea mejor y más robusta esconde más desafíos.

En este artículo, me centré en el reto de aprovechar el conocimiento de nuestro modo con datos externos a través de la técnica o RAG y cómo se puede aprovechar Couchbase para hacerlo.

Es importante recordar que la creación de incrustaciones que la aplicación LLM encontrará en la búsqueda vectorial, puede no funcionar en su primer intento. Compruebe el formato, intente empezar con incrustaciones sencillas y utilice la depuración en la medida de lo posible.

También demostré las capacidades de LangGraph de LangChain que permite crear decisiones y flujos complejos en la aplicación LLM.

Disfruta de tu viaje con las solicitudes de LLM.



Comparte este artículo
Recibe actualizaciones del blog de Couchbase en tu bandeja de entrada
Este campo es obligatorio.

Autor

Publicado por Sigal Shaharabani - Responsable técnico, Tikal

Soy Líder Técnico y Líder de Grupo en Tikal, con una gran pasión por los sistemas backend y de datos. En mi tiempo libre disfruto nadando y bailando folclore israelí.

Deja un comentario

¿Listo para empezar con Couchbase Capella?

Empezar a construir

Consulte nuestro portal para desarrolladores para explorar NoSQL, buscar recursos y empezar con tutoriales.

Utilizar Capella gratis

Ponte manos a la obra con Couchbase en unos pocos clics. Capella DBaaS es la forma más fácil y rápida de empezar.

Póngase en contacto

¿Quieres saber más sobre las ofertas de Couchbase? Permítanos ayudarle.