Cómo utilizar la API de ChatGPT en Python para tus datos en tiempo real

Uso de la API de ChatGPT en Python para datos en tiempo real

El GPT de OpenAI ha surgido como la principal herramienta de IA a nivel mundial y es competente para responder consultas basadas en sus datos de entrenamiento. Sin embargo, no puede responder preguntas sobre temas desconocidos:

  • Eventos recientes después de septiembre de 2021
  • Tus documentos no públicos
  • Información de conversaciones anteriores

Esta tarea se vuelve aún más complicada cuando se trata de datos en tiempo real que cambian con frecuencia. Además, no puedes alimentar a GPT con contenido extenso, ni puede retener tus datos durante períodos prolongados. En este caso, necesitas crear una aplicación personalizada de LLM (Modelo de Aprendizaje de Lenguaje) de manera eficiente para dar contexto al proceso de respuesta. Este artículo te guiará a través de los pasos para desarrollar dicha aplicación utilizando la biblioteca de código abierto LLM App en Python. El código fuente se encuentra en GitHub (enlazado a continuación en la sección “Construir una API de ChatGPT en Python para Ventas”).

Objetivos de Aprendizaje

Aprenderás lo siguiente a lo largo del artículo:

  • La razón por la que necesitas agregar datos personalizados a ChatGPT
  • Cómo utilizar incrustaciones, ingeniería de comandos y ChatGPT para obtener mejores respuestas a preguntas
  • Crear tu propio ChatGPT con datos personalizados utilizando la aplicación LLM
  • Crear una API de ChatGPT en Python para encontrar descuentos o precios de venta en tiempo real

¿Por qué proporcionar a ChatGPT una base de conocimiento personalizada?

Antes de adentrarnos en las formas de mejorar ChatGPT, exploremos primero los métodos manuales e identifiquemos sus desafíos. Normalmente, ChatGPT se amplía mediante ingeniería de comandos. Supongamos que quieres encontrar descuentos/ofertas/cupones en tiempo real de varios mercados en línea.

Por ejemplo, cuando le preguntas a ChatGPT “¿Puedes encontrar descuentos esta semana para zapatos Adidas de hombre?”, una respuesta estándar que puedes obtener desde la interfaz de usuario de ChatGPT sin tener conocimientos personalizados es:

Como se puede ver, GPT ofrece consejos generales sobre cómo ubicar descuentos pero carece de especificidad en cuanto a dónde o qué tipo de descuentos, entre otros detalles. Ahora, para ayudar al modelo, lo complementamos con información de descuentos proveniente de una fuente confiable de datos. Debes interactuar con ChatGPT agregando el contenido del documento inicial antes de publicar las preguntas reales. Recopilaremos estos datos de muestra del conjunto de datos de ofertas de productos de Amazon e insertaremos solo un elemento JSON que tenemos en el comando:

Como se puede ver, obtienes la salida esperada y esto es bastante simple de lograr ya que ChatGPT ahora está consciente del contexto. Sin embargo, el problema con este método es que el contexto del modelo está restringido (la longitud máxima de texto de GPT-4 es de 8,192 tokens). Esta estrategia rápidamente se vuelve problemática cuando los datos de entrada son enormes, ya que puedes esperar miles de elementos descubiertos en ventas y no puedes proporcionar esta gran cantidad de datos como un mensaje de entrada. Además, una vez que hayas recopilado tus datos, es posible que desees limpiar, formatear y preprocesar los datos para garantizar su calidad y relevancia.

Si utilizas el punto final de Completado de Chat de OpenAI o construyes complementos personalizados para ChatGPT, se presentan otros problemas como los siguientes:

  • Costo – Al proporcionar información y ejemplos más detallados, el rendimiento del modelo puede mejorar, pero a un mayor costo (para GPT-4 con una entrada de 10k tokens y una salida de 200 tokens, el costo es de $0.624 por predicción). El envío repetido de solicitudes idénticas puede aumentar los costos a menos que se utilice un sistema de caché local.
  • Latencia – Un desafío al utilizar APIs de ChatGPT para producción, como las de OpenAI, es su imprevisibilidad. No hay garantía de un servicio consistente.
  • Seguridad – Al integrar complementos personalizados, cada punto final de API debe especificarse en la especififación OpenAPI para su funcionalidad. Esto significa que estás revelando la configuración interna de tu API a ChatGPT, un riesgo del que muchas empresas son escépticas.
  • Evaluación sin conexión – Realizar pruebas sin conexión en el código y la salida de datos, o replicar el flujo de datos localmente, es un desafío para los desarrolladores. Esto se debe a que cada solicitud al sistema puede generar respuestas variables.

Utilizando Incrustaciones, Ingeniería de Comandos y ChatGPT para la Respuesta a Preguntas

Un enfoque prometedor que encuentras en internet es utilizar LLMs para crear incrustaciones y luego construir tus aplicaciones utilizando estas incrustaciones, como para sistemas de búsqueda y consulta. En otras palabras, en lugar de consultar a ChatGPT utilizando el punto final de Completado de Chat, harías la siguiente consulta:

Dado los siguientes datos de descuentos: {input_data}, responde a esta consulta: {user_query}.

El concepto es sencillo. En lugar de publicar directamente una pregunta, el método primero crea vectores de incrustación a través de la API de OpenAI para cada documento de entrada (texto, imagen, CSV, PDF u otros tipos de datos), luego indexa las incrustaciones generadas para una recuperación rápida y las almacena en una base de datos de vectores y aprovecha la pregunta del usuario para buscar y obtener documentos relevantes de la base de datos de vectores. Estos documentos se presentan a ChatGPT junto con la pregunta como un indicador. Con este contexto adicional, ChatGPT puede responder como si hubiera sido entrenado en el conjunto de datos interno.

Por otro lado, si utilizas la aplicación LLM de Pathway, ni siquiera necesitas bases de datos de vectores. Implementa la indexación de datos en tiempo real en memoria leyendo datos de cualquier almacenamiento compatible, sin necesidad de consultar una base de datos de documentos vectoriales que conlleva costos como un mayor trabajo de preparación, infraestructura y complejidad. Mantener sincronizados los datos de origen y los vectores es doloroso. Además, es aún más difícil si los datos de entrada subrayados cambian con el tiempo y requieren una reindexación.

ChatGPT con datos personalizados utilizando la aplicación LLM

Estos simples pasos a continuación explican un enfoque de canalización de datos para construir una aplicación ChatGPT para tus datos con la aplicación LLM.

  1. Recopilación: Tu aplicación lee los datos de varias fuentes de datos (CSV, JSON Lines, bases de datos SQL, Kafka, Redpanda, Debezium, etc.) en tiempo real cuando se habilita el modo de transmisión con Pathway (también puedes probar la ingestión de datos en modo estático). También mapea cada fila de datos en un esquema de documento estructurado para gestionar mejor conjuntos de datos grandes.
  2. Preprocesamiento: Opcionalmente, puedes realizar una limpieza sencilla de los datos eliminando duplicados, información irrelevante y datos ruidosos que podrían afectar la calidad de tus respuestas y extrayendo los campos de datos que necesitas para un procesamiento posterior. Además, en esta etapa, puedes enmascarar u ocultar datos de privacidad para evitar que se envíen a ChatGPT.
  3. Incrustación: Cada documento se incrusta con la API de OpenAI y se obtiene el resultado incrustado.
  4. Indexación: Construye un índice en las incrustaciones generadas en tiempo real.
  5. Búsqueda: Dada una pregunta del usuario, digamos desde una interfaz compatible con API, genera una incrustación para la consulta desde la API de OpenAI. Utilizando las incrustaciones, recupera el índice de vectores por relevancia a la consulta sobre la marcha.
  6. Pregunta: Inserta la pregunta y las secciones más relevantes en un mensaje para GPT. Devuelve la respuesta de GPT (punto final de finalización de chat).

Construir una API de Python ChatGPT para Ventas

Una vez que tengamos una imagen clara de los procesos de cómo funciona la aplicación LLM en la sección anterior. Puedes seguir los pasos a continuación para comprender cómo construir una aplicación de búsqueda de descuentos. El código fuente del proyecto se puede encontrar en GitHub. Si deseas comenzar a usar rápidamente la aplicación, puedes omitir esta parte, clonar el repositorio y ejecutar el ejemplo de código siguiendo las instrucciones del archivo README.md allí.

Objetivo del Proyecto de Ejemplo

Inspirado en este artículo sobre búsqueda empresarial, nuestra aplicación de ejemplo debe exponer un punto final de API REST HTTP en Python para responder a las consultas de los usuarios sobre las ventas actuales recuperando las últimas ofertas de varias fuentes (CSV, Jsonlines, API, brokers de mensajería o bases de datos) y aprovechando las incrustaciones de la API de OpenAI y los puntos finales de finalización de chat para generar respuestas del asistente de IA.

Paso 1: Recopilación de Datos (Ingestión de Datos Personalizados)

Para simplificar, podemos utilizar cualquier archivo JSON Lines como fuente de datos. La aplicación toma archivos JSON Lines como discounts.jsonl y utiliza estos datos al procesar las consultas de los usuarios. La fuente de datos espera tener un objeto doc para cada línea. Asegúrate de convertir tus datos de entrada primero a Jsonlines. Aquí tienes un ejemplo de un archivo Jsonline con una sola fila:

{"doc": "{'position': 1, 'link': 'https://www.amazon.com/deal/6123cc9f', 'asin': 'B00QVKOT0U', 'is_lightning_deal': False, 'deal_type': 'DEAL_OF_THE_DAY', 'is_prime_exclusive': False, 'starts_at': '2023-08-15T00:00:01.665Z', 'ends_at': '2023-08-17T14:55:01.665Z', 'type': 'multi_item', 'title': 'Deal on Crocs, DUNLOP REFINED(\u30c0\u30f3\u30ed\u30c3\u30d7\u30ea\u30d5\u30a1\u30a4\u30f3\u30c9)', 'image': 'https://m.media-amazon.com/images/I/41yFkNSlMcL.jpg', 'deal_price_lower': {'value': 35.48, 'currency': 'USD', 'symbol': '$', 'raw': '35.48'}, 'deal_price_upper': {'value': 52.14, 'currency': 'USD', 'symbol': '$', 'raw': '52.14'}, 'deal_price': 35.48, 'list_price_lower': {'value': 49.99, 'currency': 'USD', 'symbol': '$', 'raw': '49.99'}, 'list_price_upper': {'value': 59.99, 'currency': 'USD', 'symbol': '$', 'raw': '59.99'}, 'list_price': {'value': 49.99, 'currency': 'USD', 'symbol': '$', 'raw': '49.99 - 59.99', 'name': 'List Price'}, 'current_price_lower': {'value': 35.48, 'currency': 'USD', 'symbol': '$', 'raw': '35.48'}, 'current_price_upper': {'value': 52.14, 'currency': 'USD', 'symbol': '$', 'raw': '52.14'}, 'current_price': {'value': 35.48, 'currency': 'USD', 'symbol': '$', 'raw': '35.48 - 52.14', 'name': 'Current Price'}, 'merchant_name': 'Amazon Japan', 'free_shipping': False, 'is_prime': False, 'is_map': False, 'deal_id': '6123cc9f', 'seller_id': 'A3GZEOQINOCL0Y', 'description': 'Deal on Crocs, DUNLOP REFINED(\u30c0\u30f3\u30ed\u30c3\u30d7\u30ea\u30d5\u30a1\u30a4\u30f3\u30c9)', 'rating': 4.72, 'ratings_total': 6766, 'page': 1, 'old_price': 49.99, 'currency': 'USD'}"}

La parte interesante es que la aplicación siempre está al tanto de los cambios en la carpeta de datos. Si agregas otro archivo JSON Lines, la aplicación LLM hace magia y actualiza automáticamente la respuesta del modelo de IA.

Paso 2: Carga de datos y mapeo

Con el conector de entrada JSON Lines de Pathway, leeremos el archivo local JSONlines, mapearemos las entradas de datos en un esquema y crearemos una tabla de Pathway. Consulta el código fuente completo en app.py:

...
sales_data = pw.io.jsonlines.read(
    "./examples/data",
    schema=DataInputSchema,
    mode="streaming"
)

Mapea cada fila de datos en un esquema de documento estructurado. Consulta el código fuente completo en app.py:

class DataInputSchema(pw.Schema):
    doc: str

Paso 3: Incrustación de datos

Cada documento se incrusta con la API de OpenAI y se obtiene el resultado incrustado. Consulta el código fuente completo en embedder.py:

...
embedded_data = embeddings(context=sales_data, data_to_embed=sales_data.doc)

Paso 4: Indexación de datos

Luego construimos un índice instantáneo sobre las incrustaciones generadas:

index = index_embeddings(embedded_data)

Paso 5: Procesamiento e indexación de consultas de usuario

Creamos un punto final REST, tomamos una consulta de usuario del cuerpo de la solicitud de la API y incrustamos la consulta de usuario con la API de OpenAI.

...
query, response_writer = pw.io.http.rest_connector(
    host=host,
    port=port,
    schema=QueryInputSchema,
    autocommit_duration_ms=50,
)

embedded_query = embeddings(context=query, data_to_embed=pw.this.query)

Paso 6: Búsqueda de similitud e ingeniería de mensajes

Realizamos una búsqueda de similitud utilizando el índice para identificar las coincidencias más relevantes para la incrustación de la consulta. Luego construimos un mensaje que combina la consulta del usuario con los resultados de datos relevantes obtenidos y enviamos el mensaje al punto final de finalización de ChatGPT para producir una respuesta adecuada y detallada.

responses = prompt(index, embedded_query, pw.this.query)

Seguimos el mismo enfoque de aprendizaje en contexto cuando creamos el mensaje y agregamos conocimiento interno a ChatGPT en prompt.py.

prompt = f"Dados los siguientes datos de descuentos: \\n {docs_str} \\nresponde a esta consulta: {query}"

Paso 7: Devolver la respuesta

El último paso es simplemente devolver la respuesta de la API al usuario.

# Construye el mensaje utilizando los datos indexados
responses = prompt(index, embedded_query, pw.this.query)

Paso 9: Poner todo junto

Ahora, si juntamos todos los pasos anteriores, tienes una API de Python habilitada para LLM para datos de descuento personalizados lista para usar, como se muestra en el script de Python app.py.

import pathway as pw

from common.embedder import embeddings, index_embeddings
from common.prompt import prompt


def run(host, port):
    # Dada una pregunta del usuario como consulta desde tu API
    query, response_writer = pw.io.http.rest_connector(
        host=host,
        port=port,
        schema=QueryInputSchema,
        autocommit_duration_ms=50,
    )

    # Datos en tiempo real provenientes de fuentes externas como un archivo jsonlines
    sales_data = pw.io.jsonlines.read(
        "./examples/data",
        schema=DataInputSchema,
        mode="streaming"
    )

    # Calcula las incrustaciones para cada documento utilizando la API de incrustaciones de OpenAI
    embedded_data = embeddings(context=sales_data, data_to_embed=sales_data.doc)

    # Construye un índice sobre las incrustaciones generadas en tiempo real
    index = index_embeddings(embedded_data)

    # Genera incrustaciones para la consulta a partir de la API de incrustaciones de OpenAI
    embedded_query = embeddings(context=query, data_to_embed=pw.this.query)

    # Construye el mensaje utilizando los datos indexados
    responses = prompt(index, embedded_query, pw.this.query)

    # Envía el mensaje a ChatGPT y obtén la respuesta generada.
    response_writer(responses)

    # Ejecuta el flujo de trabajo
    pw.run()


class DataInputSchema(pw.Schema):
    doc: str


class QueryInputSchema(pw.Schema):
    query: str

(Opcional) Paso 10: Agregar una interfaz de usuario interactiva

Para hacer que tu aplicación sea más interactiva y amigable para el usuario, puedes usar Streamlit para construir una aplicación de frontend. Consulta la implementación en este archivo app.py.

Ejecutar la aplicación

Sigue las instrucciones en el archivo README.md (enlazado anteriormente) en la sección “Cómo ejecutar el proyecto” y podrás comenzar a hacer preguntas sobre descuentos, y la API responderá según la fuente de datos de descuentos que hayas agregado.

Después de darle este conocimiento a GPT utilizando la interfaz de usuario (aplicando una fuente de datos), mira cómo responde:

La aplicación tiene en cuenta tanto la API de Rainforest como el archivo discounts.csv (fusiona los datos de estas fuentes instantáneamente), los indexa en tiempo real y utiliza estos datos al procesar consultas.

Mejoras adicionales

Solo hemos descubierto algunas capacidades de la aplicación LLM al agregar conocimientos específicos del dominio, como descuentos, a ChatGPT. Hay más cosas que puedes lograr:

  • Incorpora datos adicionales de APIs externas, junto con varios archivos (como Jsonlines, PDF, Doc, HTML o formato de texto), bases de datos como PostgreSQL o MySQL, y transmite datos desde plataformas como Kafka, Redpanda o Debedizum.
  • Mantén una instantánea de datos para observar las variaciones en los precios de venta a lo largo del tiempo, ya que Pathway proporciona una función incorporada para calcular las diferencias entre dos alteraciones.
  • Más allá de hacer que los datos sean accesibles a través de API, la aplicación LLM te permite transmitir datos procesados a otros conectores aguas abajo, como herramientas de BI y análisis. Por ejemplo, configúralo para recibir alertas al detectar cambios de precios.