Desbloqueando el Poder de los LLM: Salidas Estructuradas para Apps

Towardsdatascience

Mientras que los modelos de lenguaje grandes (LLM) como ChatGPT y Gemini han revolucionado la interacción humana con la IA a través de interfaces de chat intuitivas, su utilidad se extiende mucho más allá de la conversación casual. Para las aplicaciones de software, que forman una base de usuarios vasta y creciente para estos potentes modelos, la salida de texto de formato libre y no estructurado de una interfaz de chat típica presenta un desafío significativo. A diferencia de los humanos, los programas de software requieren que los datos se adhieran a formatos o esquemas específicos para procesarlos de manera efectiva. Esta diferencia fundamental hace necesarias técnicas que obliguen a los LLM a generar salidas estructuradas, desbloqueando su potencial para tareas automatizadas.

La generación de salidas estructuradas implica guiar a un LLM para que produzca datos que se ajusten a un formato predefinido, comúnmente JSON o expresiones regulares (RegEx). Por ejemplo, un esquema JSON podría especificar las claves esperadas y sus tipos de datos asociados (p. ej., cadena, entero), asegurando que el LLM entregue un objeto perfectamente formateado. Esta capacidad es crucial para aplicaciones como la extracción de información precisa de grandes cuerpos de texto o incluso imágenes (utilizando LLM multimodales), como obtener fechas de compra, precios totales y nombres de tiendas de recibos digitales. Para abordar esta necesidad, los ingenieros han desarrollado varios enfoques populares.

Un método sencillo implica confiar en los proveedores de API de LLM que ofrecen capacidades de salida estructurada incorporadas. Servicios de empresas como OpenAI y Gemini de Google permiten a los desarrolladores definir un esquema de salida, a menudo utilizando clases de Python como Pydantic, y pasarlo directamente al endpoint de la API. El principal atractivo de este enfoque radica en su simplicidad; el proveedor maneja las complejidades subyacentes, permitiendo a los desarrolladores centrarse en definir su estructura de datos. Sin embargo, esta conveniencia conlleva inconvenientes significativos. Introduce la dependencia del proveedor, limitando los proyectos a proveedores específicos y potencialmente excluyendo el acceso a un ecosistema más amplio de modelos, incluyendo muchas alternativas de código abierto potentes. Además, expone las aplicaciones a posibles fluctuaciones de precios y oscurece los mecanismos técnicos en juego, dificultando la depuración y una comprensión más profunda.

Una segunda estrategia común emplea técnicas de prompting y reprompting. Esto implica instruir explícitamente al LLM, típicamente dentro del prompt del sistema, para que se adhiera a una estructura específica, a menudo reforzada con ejemplos. Después de que el LLM genera su respuesta, un parser intenta validar la salida contra el esquema deseado. Si el parsing tiene éxito, el proceso se completa. Sin embargo, la inherente falta de fiabilidad del prompting por sí solo significa que los LLM pueden desviarse de las instrucciones, añadiendo texto superfluo, omitiendo campos o utilizando tipos de datos incorrectos. Cuando el parsing falla, el sistema debe iniciar un proceso de recuperación de errores, a menudo “reprompteando” al LLM con feedback para corregir su salida. Aunque los parsers pueden proporcionar información detallada sobre errores específicos, la necesidad de reprompting introduce un factor de coste significativo. El uso de LLM suele facturarse por token, lo que significa que cada reintento duplica efectivamente el coste de esa interacción. Los desarrolladores que emplean este método deben implementar salvaguardias, como límites codificados en los reintentos, para evitar facturas inesperadamente altas. A pesar de estos desafíos, han surgido librerías como instructor para simplificar este enfoque, automatizando la definición de esquemas, la integración con varios proveedores de LLM y los reintentos automáticos.

El método más robusto y a menudo preferido es la decodificación restringida. A diferencia del prompting, esta técnica garantiza una salida válida y conforme al esquema sin necesidad de reintentos costosos. Aprovecha la lingüística computacional y la comprensión de cómo los LLM generan texto, token por token. Los LLM son autorregresivos, lo que significa que predicen el siguiente token basándose en todos los anteriores. La capa final de un LLM calcula las probabilidades para cada token posible en su vocabulario. La decodificación restringida interviene en esta etapa limitando los tokens disponibles en cada paso de generación.

Esto se logra definiendo primero la estructura de salida deseada utilizando una expresión regular (RegEx). Este patrón RegEx se compila luego en un Autómata Finito Determinista (AFD), esencialmente una máquina de estados que puede validar si una secuencia de texto se ajusta al patrón. El AFD proporciona un mecanismo preciso para determinar, en cualquier momento dado, qué tokens son válidos para seguir la secuencia actual mientras se adhiere al esquema. Cuando el LLM calcula las probabilidades de los tokens, los logits (valores pre-softmax) de todos los tokens no permitidos por el AFD se anulan efectivamente. Esto fuerza al modelo a seleccionar solo del conjunto válido, garantizando así que la salida generada siga estrictamente la estructura requerida. Crucialmente, este proceso no incurre en ningún coste computacional adicional una vez que se establece el AFD. Librerías como Outlines simplifican la implementación de la decodificación restringida, permitiendo a los desarrolladores definir esquemas utilizando clases Pydantic o RegEx directos, e integrándose sin problemas con numerosos proveedores de LLM.

En conclusión, generar salidas estructuradas a partir de LLM es una capacidad fundamental que extiende su aplicación mucho más allá del chat centrado en humanos. Si bien depender de los proveedores de API ofrece una simplicidad inicial y el prompting con recuperación de errores brinda flexibilidad, la decodificación restringida se destaca como el enfoque más potente y rentable. Al guiar fundamentalmente el proceso de generación de tokens del LLM, asegura salidas fiables y adheridas al esquema, lo que la convierte en el método preferido para integrar LLM en sistemas de software sofisticados.