Dominar la generación controlada con Gemini 1.5: cumplimiento con esquemas para desarrolladores

SEP 03, 2024
Lewis Liu Group Product Manager Gemini
Terry Koo Research Scientist Google Deepmind

Gran parte de la emoción actual en torno a la IA generativa se centra en “lo que podría ser”, es decir, los posibles experimentos y avances con modelos fundamentales. Pero en Google siempre nos comprometimos a proporcionar un ecosistema integral de IA que te ayude no solo a probar los mejores modelos de su clase, sino también a adoptarlos en aplicaciones prácticas.

Como parte de ese viaje, presentamos la generación controlada para Gemini 1.5 Pro en Google I/O a principios de este año, y nos encantaron la rápida adopción y los comentarios positivos que recibimos. Hoy, damos un paso más con la presentación de la generación controlada para Gemini 1.5 Flash y agregamos compatibilidad con “enum”. De esta manera, brindamos a los desarrolladores una herramienta eficaz para generar de forma fiable respuestas que cumplan con un esquema definido. Además, la generación controlada también se activa automáticamente en CUALQUIER modo cuando utilizas la llamada a función en Gemini 1.5.


¿Qué es la generación controlada y por qué es importante?

La generación controlada vendría a ser como un plano para la producción del modelo. Cuando defines un esquema de respuesta, indicas el formato y la estructura precisos de las respuestas de la IA. Ya sea que se trate de extraer entidades en formato JSON para un procesamiento continuo o clasificar artículos de noticias dentro de tu propia taxonomía, la generación controlada ayuda a garantizar la coherencia y reduce la necesidad de un posprocesamiento lento.

Para integrar por completo la IA en el desarrollo de software, deben suceder dos cosas: una transferencia perfecta de los equipos de ciencia de datos y aprendizaje automático a los desarrolladores de aplicaciones, y una integración perfecta de los resultados del modelo dentro de los sistemas existentes. Con la generación controlada, puedes realizar lo siguiente:

  • Permitir que la IA produzca datos fácilmente utilizables y legibles por máquinas, lo que reduce la necesidad de un posprocesamiento y un análisis engorrosos.

  • Generar resultados en formatos como JSON, lo que convierte a tu IA en un ciudadano de primera clase en la economía de las API. Se puede conectar sin problemas a los flujos de trabajo existentes.

  • Incorporar una dosis de previsibilidad en los resultados de la IA, lo que permite anticipar de manera confiable el formato y la estructura de los datos que produce tu modelo de IA.

En palabras de Chris Curro, ingeniero principal de aprendizaje automático de The Estée Lauder Companies, uno de nuestros primeros evaluadores: “Estamos diseñando flujos de trabajo de razonamiento complejo sobre la base de Gemini 1.5 para crear experiencias de consumidores y empleados que, de otro modo, serían imposibles. La naturaleza amigable para el desarrollador de la generación controlada permitió a nuestro equipo trabajar rápidamente e impulsar el valor comercial”.

La función se basa en el reciente avance que nuestro equipo de Google desarrolló, llamado “decodificación controlada”. Puedes obtener más información sobre nuestras técnicas subyacentes en este documento.

En la API de Gemini y la API de Vertex AI, presentamos el concepto de “esquema de respuesta”. Un esquema de respuesta funciona como una plantilla, ya que indica los elementos, los tipos de datos y la estructura general de los resultados de la IA. El esquema se basa en la definición de esquema OpenAPI 3.0, por lo que siempre sabrás que estás creando en un estándar abierto y compatible. Si incluyes un esquema de respuesta en tu instrucción, le indicas al modelo que se adhiera a tus reglas definidas, lo que genera resultados predecibles y estructurados.


El ingrediente secreto de Google

  • La generación controlada de Gemini agrega una latencia mínima a tus llamadas de API existentes, incluso en la primera llamada de API.

  • Géminis admite enum como tipo y pronto se incluirán otros.

  • Gemini hace cumplir los esquemas y no requiere almacenar tus datos.


Primeros pasos

La función de generación controlada está disponible tanto en Gemini 1.5 Pro como en Gemini 1.5 Flash, en Google AI Studio y Vertex AI.


Ejemplo: creación de una app de planificación de comidas con esquema JSON

Imagina que estás creando una app para sugerir recetas en diferentes situaciones. Las recetas se deben generar en un formato estructurado para que las pueda incorporar fácilmente la app y esta se las pueda presentar visualmente al usuario. En el siguiente ejemplo, se muestra cómo se puede usar la generación controlada para generar un conjunto de recetas de una comida de varios platos.

from vertexai.generative_models import GenerationConfig, GenerativeModel
vertexai.init(project=project_id, location="us-central1")
 
response_schema = {
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "course": {
                "type": "string",
                "enum": [
                    "appetizer",
                    "salad",
                    "soup",
                    "main",
                    "dessert",
                ],
            },
            "name": {
                "type": "string",
            },
            "ingredients": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "unit": {
                            "type": "string",
                            "enum": [
                                "count",
                                "cup",
                                "tablespoon",
                                "teaspoon",
                                "pound",
                                "ounce",
                            ],
                        },
                        "amount": {
                            "type": "number",
                        },
                        "name": {
                            "type": "string",
                        },
                    },
                    "required": ["name"],
                },
            },
            "steps": {
                "type": "array",
                "items": {
                    "type": "string",
                },
            },
        },
        "required": ["course", "name"],
    },
}
 
prompt = (
    "Algunos amigos vendrán a la ciudad y quiero invitarlos a cenar.  "
    "¿Puedes planificarme una comida de tres platos?  "
    "No tengo mucha experiencia en la cocina, así que necesito recetas simples."
)
 
model = GenerativeModel ("gemini-1.5-pro-001")
 
response = model.generate_content (
    prompt,
    generation_config=GenerationConfig(
        response_mime_type="application/json",
        response_schema=response_schema
),
)

El resultado de este modelo confirma de manera precisa el esquema especificado en el cuerpo de la solicitud y la aplicación lo puede utilizar directamente.

[
    {
        "course": "appetizer",
        "name": "Caprese Skewers",
        "ingredients": [
            {
                "name": "cherry tomatoes",
                "amount": 1,
                "unit": "cup"
            },
            {
                "name": "fresh mozzarella balls",
                "amount": 1,
                "unit": "cup"
            },
            {
                "name": "fresh basil leaves",
                "amount": 12,
                "unit": "count"
            },
            {
                "name": "olive oil",
                "amount": 2,
                "unit": "tablespoon"
            },
            {
                "name": "balsamic glaze",
                "amount": 2,
                "unit": "tablespoon"
            },
            {
                "name": "salt",
                "amount": 1,
                "unit": "teaspoon"
            },
            {
                "name": "black pepper",
                "amount": 1,
                "unit": "teaspoon"
            }
        ],
        "steps": [
            "Thread cherry tomatoes, mozzarella balls, and basil leaves onto skewers.",
            "Drizzle with olive oil and balsamic glaze.",
            "Season with salt and pepper to taste."
        ]
    },
    {
        "course": "main",
        "name": "One-Pan Lemon Herb Salmon",
        "ingredients": [
            {
                "name": "salmon fillets",
                "amount": 4,
                "unit": "count"
            },
            {
                "name": "asparagus",
                "amount": 1,
                "unit": "pound"
            },
            {
                "name": "cherry tomatoes",
                "amount": 1,
                "unit": "cup"
            },
            {
                "name": "lemon",
                "amount": 1,
                "unit": "count"
            },
            {
                "name": "dried oregano",
                "amount": 1,
                "unit": "teaspoon"
            },
            {
                "name": "dried thyme",
                "amount": 1,
                "unit": "teaspoon"
            },
            {
                "name": "salt",
                "amount": 1,
                "unit": "teaspoon"
            },
            {
                "name": "black pepper",
                "amount": 1,
                "unit": "teaspoon"
            },
            {
                "name": "olive oil",
                "amount": 2,
                "unit": "tablespoon"
            }
        ],
        "steps": [
            "Preheat oven to 400 degrees F (200 degrees C).",
            "Line a baking sheet with parchment paper.",
            "Place salmon fillets on one side of the baking sheet and spread asparagus and cherry tomatoes on the other side.",
            "Squeeze lemon juice over the salmon and vegetables.",
            "Sprinkle with oregano, thyme, salt, and pepper.",
            "Drizzle with olive oil.",
            "Bake for 15-20 minutes, or until salmon is cooked through and vegetables are tender."
        ]
    },
    {
        "course": "dessert",
        "name": "Fruit Salad with Honey Yogurt",
        "ingredients": [
            {
                "name": "strawberries",
                "amount": 1,
                "unit": "cup"
            },
            {
                "name": "blueberries",
                "amount": 1,
                "unit": "cup"
            },
            {
                "name": "raspberries",
                "amount": 1,
                "unit": "cup"
            },
            {
                "name": "greek yogurt",
                "amount": 1,
                "unit": "cup"
            },
            {
                "name": "honey",
                "amount": 2,
                "unit": "tablespoon"
            }
        ],
        "steps": [
            "In a large bowl, combine strawberries, blueberries, and raspberries.",
            "In a separate bowl, mix together greek yogurt and honey.",
            "Serve fruit salad with a dollop of honey yogurt."
        ]
    }
]

Clasificar la condición del producto con el esquema Enum

Para restringir los resultados del modelo en un conjunto de valores predefinidos, puedes usar "text/x.enum".

import vertexai
from vertexai.generative_models import GenerationConfig, GenerativeModel
 
vertexai.init(project=project_id, location="us-central1")
model = GenerativeModel("gemini-1.5-flash-001")
 
response_schema = {
     "type": "STRING",
     "enum": ["nuevo en su envase", "como nuevo", "poco usado", "usado", "dañado", "sucio"]
}
 
prompt = [
     "Descripción del artículo: El artículo es un abrigo de invierno largo que tiene muchas rasgaduras en las costuras y está en muy mal estado. Tiene manchas grandes de dudosa procedencia."
]
 
 
response = model.generate_content(
     prompt,
     generation_config=GenerationConfig(
         response_mime_type="text/x.enum", response_schema=response_schema
     ),
)
print(response.candidates[0])

La salida del modelo contiene la simple clasificación del producto como "dañado".

content {
  role: "model"
  parts {
    text: "dañado"
  }
}

Limitaciones

  • La generación controlada admite un subconjunto del esquema OpenAPI 3.0.

  • El contenido de salida sigue dependiendo de la capacidad de razonamiento y extracción del modelo. El uso de generación controlada impone el formato de salida, pero no la respuesta real.

  • Si la instrucción no tiene suficiente información para un campo obligatorio, la generación controlada puede generar una respuesta basada en los datos con los que se entrenó. Si se establece el valor nullable como True en el campo, se puede mitigar esta limitación.


Resumen

Con la generación controlada, cuentas con una herramienta eficaz para generar respuestas que cumplan con un esquema definido. Puedes aplicarla en muchos de tus flujos de trabajo actuales para que sea más fiable y predictiva. Nos comprometemos a proporcionar a los desarrolladores funciones de API fáciles de usar a fin de orientar y controlar mejor el comportamiento del modelo. La generación controlada es solo el comienzo.

Para comenzar a usar esta función, puedes obtener más detalles en la página de documentación de Google AI Studio o Vertex AI.