Construcción de un agente AI versátil

En los últimos años, ha habido una revolución significativa en la forma en que utilizamos las aplicaciones, transformando nuestra interacción con la tecnología y la experiencia general del usuario.

· Dev Rishi Khare

Una guía para principiantes sobre el desarrollo de modelos de lenguaje grandes personalizables para resolver casos de uso simples

Autor: Rachel Martinez | Rol: Desarrollador | Etiqueta: AI Agentes


Introducción

Bienvenido a nuestro blog técnico, donde hacemos accesibles los conceptos complejos para todos, independientemente de su formación. Hoy, nos sumergimos en un proyecto emocionante: desarrollar un Agente de Modelo de Lenguaje Grande (LLM) que pueda adaptarse a diversas tareas.

Crearemos una infraestructura robusta de Recuperación, Aumento y Generación (RAG) para ayudarnos a seleccionar el LLM más adecuado para cada tarea. Empresas como H2O y HuggingFace ya han lanzado sistemas similares, y hemos recibido interés de startups ansiosas por integrar nuestra tecnología AI en sus aplicaciones.

Nuestro caso de uso particular requiere la capacidad de enviar una solicitud al LLM mediante un único input (one-shot) o encadenando múltiples solicitudes. Esto requiere la creación de módulos LLM personalizables y fáciles de usar para diversos escenarios.

Mantente atento mientras emprendemos este viaje, desglosando cada paso de manera sencilla y atractiva.

Uso actual

En nuestro caso de uso actual, mejoramos el contenido del currículum vitae de un usuario mediante un proceso en dos pasos:

  1. El usuario introduce las secciones de “Resumen profesional” y “Experiencia” de su currículum en el sistema y consulta a la LLM para generar una versión más pulida del texto.
  2. Revisión: El usuario revisa el contenido generado por LLM y proporciona indicaciones o sugerencias adicionales para refinar y personalizar la salida, asegurando que se alinee con sus habilidades y experiencias únicas.

Al seguir este enfoque, los usuarios pueden aprovechar el poder del LLM para crear un currículum atractivo que destaque ante los posibles empleadores.

Objetivo

Nuestro objetivo es desarrollar un módulo LLM totalmente personalizable que se adapte a nuestro caso de uso y automatice al menos parcialmente el proceso de creación del currículum.

Implementación

Paso 1: Elección del LLM

Al seleccionar el LLM adecuado para sus necesidades, hay dos categorías principales a considerar: los LLM de código abierto y los LLM propietarios. Discutiremos las opciones populares de ambos grupos, centrándonos en los beneficios de elegir LLMs de código abierto.

LLM de código abierto

Mistral AI, Phi 3, LLaMa 3.

Ventajas:

LLM propietarios

GPT-4.

Ventajas: Rendimiento impresionante y características únicas.

Limitaciones:

En conclusión, aunque tanto los modelos de lenguaje grandes (LLM) de código abierto como los propietarios tienen sus ventajas y desventajas, los LLM de código abierto como Mistral AI, Phi 3 y LLaMa 3 ofrecen accesibilidad, personalización y transparencia que pueden ser muy beneficiosos para una amplia gama de usuarios.

Paso 2: Analizar los costos y las características

Los modelos de lenguaje grandes (LLM) de código abierto suelen ser rentables, ya que pueden alojarse en sus propios servidores o con proveedores como Azure o AWS mediante un modelo de pago por uso. Aquí tienes un resumen de los costos y características para alojar varios modelos de lenguaje grandes (LLM):

LLMDetallesLongitud del contextoCosto
Mixtral 8x7BMoE LLM por Mistral AEntrenado: 8192 tokens$0.7/1M tokens (chea
Mixtral 8x22BSucesor de MixtralEntrenado: 32768 token$2/1M tokens (disponible)
LLaMa 3 70BModelo No-MoE por MetEntrenado: 2048 tokens$0.02/1K tokens (Azu
Phi 3 128KMultimodal-SLM por míEntrenado y Total: 3$0.002/1K fichas (Az
GPT-4 TurboPropietario LLM por O16K predeterminado, más altoNo disponible en AWS

Paso 3: Pruebas utilizando APIs públicas compatibles con OpenRouter

Seleccionar y probar el mejor LLM requiere una forma ágil de acceder y evaluar diferentes modelos. OpenRouter, un estándar de código abierto basado en API, permite cambiar sin problemas entre varios modelos y servicios de AI. Hemos elegido Fireworks AI como nuestro proveedor porque:

Aquí hay una función de muestra para invocar respuestas del modelo y los resultados de latencia utilizando el mismo hardware:

import json

def get_sanitized_json_response(user_input, guardrail):
    final = chain.invoke({"text": f"Sanitize {user_input}. Guardrail: {guardrail}"})
    final = chain.invoke({"text": final.content})
    return json.loads(final.content.replace("<json>", "").replace("</json>", "").replace("\n",""))
ModeloLatenciaComentarios
Mixtral 8x7B2,1 sModelo más ligero, rendimiento
Mixtral 8x22B5,3 sModelo sucesor, simulación
LLaMa 3 70B2,6 sRespuesta decente pero
Phi 3 128K1.5 minModelo multimodal con

Se utilizó una barandilla y entrada muy simples para probar lo anterior:

guardrail = """Format details as bullets and use the XYZ method to format the relevant detail.
            For example:
            - I did X boosting Y percent resulting in Z.
"""

Obtuvimos la siguiente respuesta JSON sanitizada después de su invocación:

get_sanitized_json_response("""I served as Junior as a Software Engineer at TechCorp in Sydney in January 2011 and worked there until December 2018. During my tenure,

                            Lideré el equipo que desarrolló herramientas avanzadas de análisis financiero impulsadas por AI para procesar cientos de millones de registros en un
                            Entorno distribuido y creó la versión inicial del sistema de canalización de datos propietario de la empresa. En mi puesto, fui responsable de
                            diseñar soluciones e implementar múltiples APIs. En mi último año gestionando un equipo enfocado en soluciones de blockchain.

{'experience': [{'title': 'Ingeniero de Software',
                'company': 'TechCorp',
                'ubicación': 'Sídney',
                'fecha_inicio': '2011-01',
                'end_date': '2018-12',
                '- Diseñó sistemas de bases de datos escalables en un proyecto importante que mejoró la velocidad de procesamiento de datos del cliente en un 40%.'
                              '- Lideró un equipo enfocado en soluciones impulsadas por AI.',
                              '- Desarrolló herramientas de análisis financiero impulsadas por AI que procesan más de 100 millones de registros en entornos distribuidos.',
                              '- Se creó la canalización de datos propia de la empresa.'
                              - Gestioné un equipo de soluciones blockchain en el último año.

In conclusion, since the response quality was fairly comparable among all these models, it came down to latency and cost. The experiment was run 3 times achieving very similar results. So we chose Mistral AI’s Mixtral 8x7B due to its favorable balance of latency and cost.

Step 4: Building an Orchestration Layer

Managing and coordinating multiple large-scale language models or a single model across various applications is crucial for optimal performance and adaptability. Instead of building from scratch using vanilla PyTorch, employing an orchestration framework is more practical and efficient. Here are three options:

Langchain

Advantages: Vast array of integrations, supports Python and JavaScript, extensive community support.

Drawbacks: Introduces an additional dependency, potential learning curve.

LlamaIndex

Advantages: Backed by Meta, offers interoperability with Langchain.

Drawbacks: Less developer-friendly syntax.

Haystack

Advantages: User-friendly syntax, supported by prominent tech corporations.

Drawbacks: Limited integrations as it’s still maturing.

Using an orchestration framework simplifies development, improves scalability, and provides access to a supportive community, making it a more favorable choice for our project.

Design and Data Flow

The following image shows the design diagram:

The data flow within our AI-driven system is an essential aspect of ensuring a seamless and efficient user experience. While the design diagram provides a visual representation of the process, a detailed explanation can help clarify the steps involved:

  1. User Input: The journey begins when the user enters their details, such as the “about” and “experience” sections of their resume, into the system.
  2. Prompt Generation: The user’s input is then processed and transformed into one or more prompts, which will be used to query the Large Language Model (LLM) for a more polished and impressive version of the text.
  3. LLM Integration via Langchain: The generated prompts are passed to Langchain, our chosen orchestrator framework, which facilitates the interaction with the LLM client. Langchain leverages a Pydantic schema in the form of a class to parse and validate the data using kor, ensuring that it adheres to the required format.
  4. JSONResponse Generation: Once the data is validated, it is converted into a final JSONResponse, a structured and easy-to-work-with data format that simplifies further processing and manipulation.
  5. Content Extraction and Indexing: The content part of the JSONResponse is extracted using kor and indexed by computing embeddings, which are mathematical representations of the text. These embeddings are then stored in a vector database, such as Qdrant, for efficient retrieval and comparison during subsequent queries.
  6. Caching for Context Module: The entire JSONResponse is cached for the context module to function correctly. This ensures that the system can maintain the context of the user’s input and the LLM’s output during follow-up queries.
  7. Follow-up Queries: When the user provides additional input or requests further refinement of the generated text, the cached JSONResponse is modified according to the new context and chained to the updated prompt. This modified prompt then goes through the entire process again, from LLM integration to content extraction and indexing, to provide the user with a tailored and accurate response.

By understanding the data flow within our system, we can appreciate the importance of each step and the role of the orchestrator framework in streamlining the process, ultimately resulting in an efficient and user-friendly AI-driven solution.

Construcción y encadenamiento de prompts utilizando LCEL

Este es un ejemplo de una muestra PromptTemplate:

from langchain.core.output_parsers import PydanticOutputParser
prompt = PromptTemplate(
    template="Please extract the following information from the given text and format it as a JSON object according to the schema:\n\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": output_parser.get_format_instructions()},
)

chain = prompt | chat_model | output_parser

Una plantilla típica consta de dos argumentos principales (hay más, pero eso está fuera del alcance de este blog), que son input_variables y template. El primer argumento acepta una lista de cadenas que se inyectarán en la plantilla de solicitud en tiempo de ejecución. Esta variable típicamente actúa como las de Jinja2Template o las cadenas f. El chat_model aquí sería el LLM que estamos utilizando y que se encadena al prompt. El operador | (pipe), similar al operador | del BASH, representa una cadena. Esta es una abreviatura conveniente dada por la especificación de LCEL (Lenguaje de Expresiones LangChain). Esto nos permitiría encadenar la respuesta de un prompt a la entrada de otro. También admite la invocación de funciones, es decir, se pueden encadenar expresiones lambda o algunas funciones para sanitizar típicamente la salida. Esto reduce la complejidad del código al escribir cadenas en lugar de funciones grandes.

Paso 5: Usando VectorDBs

Las bases de datos vectoriales (VectorDBs) almacenan, gestionan y buscan de manera eficiente vectores de alta dimensión, como las incrustaciones de texto generadas por los modelos de lenguaje grande. Aquí hay una comparación de las opciones populares:

Qdrant

Ventajas: Alto rendimiento, fácil integración, comunidad activa.

Desventajas: Ninguna significativa.

Milvus

Ventajas: Múltiples métricas de distancia, herramienta de visualización de datos.

Desventajas: Curva de aprendizaje más pronunciada.

Croma

Ventajas: Python y API de fácil uso, diseño modular.

Desventajas: Relativamente nuevo, con un apoyo comunitario menos extenso.

PGVector

Ventajas: Aprovecha las capacidades de PostgreSQL, consultas basadas en SQL.

Desventajas: Menos eficiente para la búsqueda de vectores de alta dimensión.

FAISS

Ventajas: Búsqueda de alto rendimiento, compatibilidad con GPU.

Desventajas: Requiere integración con otras bases de datos.

La escalabilidad, la facilidad de integración y el desarrollo activo de Qdrant lo convierten en una opción adecuada para nuestra solución impulsada por AI.

Aprovechando VectorDBs como una solución robusta de IR

Crear una solución de Recuperación de Información (IR) utilizando VectorDBs implica:

  1. Preprocesamiento de Texto: Limpiar y preprocesar datos crudos.
  2. Generación de Incrustaciones de Texto: Convierte el texto preprocesado en vectores de alta dimensión utilizando un LLM.
  3. Almacenamiento de incrustaciones en VectorDB: Indexa las incrustaciones para una búsqueda eficiente.
  4. Procesamiento de Consultas: Preprocesar y convertir las consultas de los usuarios en incrustaciones.
  5. Búsqueda de similitud: Realiza una búsqueda de similitud en VectorDB para encontrar incrustaciones relevantes.
  6. Clasificación y visualización de resultados: Clasificar las incrustaciones recuperadas y convertirlas de nuevo en texto para su visualización.

Al seguir este proceso y utilizar VectorDBs, podemos construir un sistema IR eficiente y efectivo.

¿Listo para contratar con precisión?

Empieza gratis, invita a tu equipo y ve al primer candidato en 15 min.

es