Salidas estructuradas con Amazon Nova: una guía para constructores

Los desarrolladores que construyen aplicaciones de IA enfrentan un desafío común: convertir los datos no estructurados en formatos estructurados. La salida estructurada es crítica para los casos de uso de comunicación de máquina a máquina, porque esto permite que los casos de uso posterior consumen y procesen de manera más efectiva las salidas generadas. Ya sea extrayendo información de los documentos, creando asistentes que obtienen datos de API o en el desarrollo de agentes que toman acciones, estas tareas requieren modelos de base para generar salidas en formatos estructurados específicos.

Lanzamos una decodificación restringida para proporcionar confiabilidad al usar herramientas para salidas estructuradas. Ahora, las herramientas se pueden usar con Amazon Nova Modelos de base (FMS) para extraer datos basados en esquemas complejos, reduciendo los errores de uso de la herramienta en más del 95%.

En esta publicación, exploramos cómo puede usar Amazon Nova FMS para casos de uso de salida estructurados.

Técnicas para implementar salidas estructuradas

Al abordar los requisitos para los casos de uso de salidas estructuradas, hay dos enfoques comunes para la implementación. Puede modificar el mensaje del sistema o aprovechar las llamadas de herramientas. Por ejemplo, en un caso de uso de atención al cliente, es posible que el modelo produzca un JSON con su respuesta al usuario y el sentimiento actual. Por lo tanto, el indicador del sistema se modificaría para incluir la estructura esperada:

Make sure your final response is valid JSON that follows the below response schema: 

##Response schema
```json
{
   "response": "the response to the customer",
   "sentiment": "the current customer sentiment"
}```

La otra opción es proporcionar un Configuración de herramientas. La llamada de herramientas es el acto de proporcionar una API, función de código o esquema (o estructura) requerido por su aplicación final al modelo a través del esquema de solicitud con el API Converse. Esto se usa más al construir aplicaciones de agente, pero también se usa con frecuencia en casos de uso de salida estructurados debido a la capacidad de definir un esquema establecido al que el modelo debe adherirse.

tool_config = {
    "tools": [ 
        {
            "toolSpec": {
                "name": "respondToUser",
                "description": "the formatted response to the customer",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "response": {
                            "description": "the response to the customer",
                            "type": "string"
                        },
                        "sentiment": {
                            "description": "the current customer sentiment",
                            "type": "string"
                        }
                    },
                    "required": [
                        "response",
                        "sentiment"
                    ]
                }
            }
        }
    ]
}

Ambos enfoques pueden ser técnicas efectivas para incitar a la salida del modelo. Sin embargo, la salida sigue siendo no determinista y hay espacio para la falla. En nuestro trabajo con los clientes para implementar casos de uso como flujos de trabajo de agente y aplicaciones y extracción estructurada, hemos observado que la precisión del modelo tiende a disminuir a medida que el esquema se vuelve más complejo.

Salida estructurada con modelos Amazon Nova

Basado en estos aprendizajes, hemos implementado decodificación restringida En nuestro sistema para ayudar a garantizar una alta confiabilidad del modelo en la salida generada y permitir que el modelo maneje esquemas complejos con facilidad. La decodificación restringida se basa en una gramática para constreñir Los posibles tokens que un modelo puede emitir en cada paso. Esto se diferencia de las técnicas de solicitación utilizadas históricamente, porque esto cambia los tokens reales que un modelo puede elegir al generar una salida. Por ejemplo, al cerrar un objeto JSON, el modelo estaría limitado a solo un } Token para seleccionar. La decodificación restringida se usa cada vez que se pasa una configuración de la herramienta. Debido a que el uso de la herramienta ya nos proporciona un esquema específico, podemos usarlo para generar una gramática dinámicamente, basada en el esquema deseado por el desarrollador. La decodificación restringida evita que el modelo genere claves no válidas y aplique los tipos de datos correctos basados en el esquema definido.

Proceso de definición de esquema

Un paso clave en el uso de salidas estructuradas con Amazon Nova es crear una configuración de herramienta. La configuración de la herramienta proporciona una interfaz estándar para definir el esquema de salida esperado. Si bien la intención principal de una configuración de herramienta es proporcionar funcionalidad externa al modelo, esta interfaz JSON también se utiliza en casos de uso de salida estructurados. Esto se puede ilustrar utilizando un caso de uso que extrae recetas del contenido en línea. Para comenzar la integración, creamos una configuración de herramienta que representa los campos específicos que queremos extraer de las facturas. Al crear una configuración de herramienta, es importante ser claro y conciso porque los nombres y descripciones de la propiedad son los que informan al modelo cómo se deben poblar los campos.

tool_config = {
   "tools": [
        {
            "toolSpec": {
                "name": "extract_recipe",
                "description": "Extract recipe for cooking instructions",
                "inputSchema": {
                    "json": {
                        "type": "object",
                        "properties": {
                            "recipe": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "description": "Name of the recipe"
                                    },
                                    "description": {
                                        "type": "string",
                                        "description": "Brief description of the dish"
                                    },
                                    "prep_time": {
                                        "type": "integer",
                                        "description": "Preparation time in minutes"
                                    },
                                    "cook_time": {
                                        "type": "integer",
                                        "description": "Cooking time in minutes"
                                    },
                                    "servings": {
                                        "type": "integer",
                                        "description": "Number of servings"
                                    },
                                    "difficulty": {
                                        "type": "string",
                                        "enum": [
                                            "easy",
                                            "medium",
                                            "hard"
                                        ],
                                        "description": "Difficulty level of the recipe"
                                    },
                                    "ingredients": {
                                        "type": "array",
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "name": {
                                                    "type": "string",
                                                    "description": "Name of ingredient"
                                                },
                                                "amount": {
                                                    "type": "number",
                                                    "description": "Quantity of ingredient"
                                                },
                                                "unit": {
                                                    "type": "string",
                                                    "description": "Unit of measurement"
                                                }
                                            },
                                            "required": [
                                                "name",
                                                "amount",
                                                "unit"
                                            ]
                                        }
                                    },
                                    "instructions": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "description": "Step-by-step cooking instructions"
                                        }
                                    },
                                    "tags": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "description": "Categories or labels for the recipe"
                                        }
                                    }
                                },
                                "required": [
                               ]
                            }
                        },
                        "required": [
                        ]
                    }
                }
            }
        }
    ]
}

Después de que se haya creado la configuración de la herramienta, podemos pasarla a través del API Converse junto con la receta, que estará contenida en el mensaje del usuario. Históricamente, se requiere un indicador del sistema para los casos de uso de salida estructurado para guiar el modelo en cómo generar el contenido, en este caso podemos usarlo para pasar detalles sobre el rol del sistema y la persona.

import boto3

model_response = client.converse(
    modelId="us.amazon.nova-lite-v1:0",
   system=[{"text": "You are an expert recipe extractor that compiles recipe details from blog posts"}],
    messages=[{"role": "user", "content": content}],
    inferenceConfig={"temperature": 0},
    toolConfig=tool_config
)

Al usar la herramienta nativa, utilizar el soporte con decodificación restringida, obtenemos una llamada de herramienta analizada que seguirá la sintaxis correcta y el esquema esperado como se establece en la configuración de la herramienta.

{
    "toolUse": {
        "toolUseId": "tooluse_HDCl-Y8gRa6yWTU-eE97xg",
        "name": "extract_recipe",
        "input": {
            "recipe": {
                "name": "Piacenza Tortelli",
                "description": "Piacenza tortelli, also known as 'tortelli with the tail' due to their elongated shape, are a delicious fresh pasta, easy to make at home!",
                "prep_time": 60,
                "cook_time": 10,
                "servings": 4,
                "difficulty": "hard",
                "ingredients": [
                    {
                        "name": "Type 00 flour",
                        "amount": 2.3,
                        "unit": "cups"
                    },
                    {
                        "name": "Eggs",
                        "amount": 3,
                        "unit": ""
                    },
                    {
                        "name": "Fine salt",
                        "amount": 1,
                        "unit": "pinch"
                    },
                    {
                        "name": "Spinach",
                        "amount": 13.3,
                        "unit": "cups"
                    },
                    {
                        "name": "Cow's milk ricotta cheese",
                        "amount": 1.3,
                        "unit": "cups"
                    },
                    {
                        "name": "Parmigiano Reggiano PDO cheese",
                        "amount": 4.2,
                        "unit": "oz"
                    },
                    {
                        "name": "Fine salt",
                        "amount": 1,
                        "unit": "to taste"
                    },
                    {
                        "name": "Nutmeg",
                        "amount": 1,
                        "unit": "to taste"
                    },
                    {
                        "name": "Butter",
                        "amount": 80,
                        "unit": "g"
                    },
                    {
                        "name": "Sage",
                        "amount": 2,
                        "unit": "sprigs"
                    }
                ],
                "instructions": [
                    "Arrange the flour in a mound and pour the eggs into the center 1; add a pinch of salt and start working with a fork 2, then knead by hand 3.",
                    "You should obtain a smooth dough 4; wrap it in plastic wrap and let it rest for half an hour in a cool place.",
                    "Meanwhile, prepare the filling starting with the spinach: immerse them in boiling salted water 5 and blanch them for a few minutes until wilted 6.",
                    "Drain the spinach and transfer them to cold water 7, preferably with ice. Then squeeze them very well 8 and chop them finely with a knife 9.",
                    "Place the chopped spinach in a bowl, add the ricotta 10, salt, pepper, and nutmeg 11. Also add the grated Parmigiano Reggiano DOP 12.",
                    "Mix well until you get a homogeneous consistency 13.",
                    "At this point, take the dough that has now rested 14, take a portion of it keeping the rest covered. Lightly flatten the dough with a rolling pin 15.",
                    "Roll it out with a pasta machine 16; as you reduce the thickness, fold the dough over itself 17 and roll it out again 18.",
                    "You should get a very thin rectangle, about 0.04-0.08 inches thick 19. Cut 2 strips of dough by dividing the rectangle in half lengthwise 20, then cut out diamonds of 4 inches 21.",
                    "Fill the diamonds with the spinach filling 22 and close them. To do this, bring one of the two longer points inward 23, then fold the two side points towards the center 24.",
                    "Now close the tortello by pinching the dough in the center and moving gradually towards the outside 25. The movement is similar to the closure of culurgiones. Continue in this way until the dough and filling are finished 26; you will get about 40-45 pieces.",
                    "Place a pot full of salted water on the stove. Meanwhile, in a pan, pour the butter and sage 27. Turn on the heat and let it flavor.",
                    "Then cook the tortelli for 5-6 minutes 28, then drain them and toss them in the butter and sage sauce 29.",
                    "Plate and serve the Piacenza tortelli with plenty of grated Parmigiano Reggiano DOP 30!"
                ],
                "tags": [
                    "vegetarian",
                    "Italian"
                ]
            }
        }
    }
}

Ahora, con una decodificación restringida, podemos usar un modelo más pequeño como Amazon Nova Lite para obtener un esquema JSON grande y complejo para usar en nuestra aplicación. Para los casos de uso basados en imágenes con esquemas complejos, le recomendamos que use Nova Pro o Nova Premier para el mejor rendimiento.

Conclusión

Al usar la salida estructurada con Amazon Nova a través de la llamada de herramientas, puede aprovechar los beneficios clave de la decodificación restringida y construir un sistema confiable. Le recomendamos que pruebe esto en sus aplicaciones hoy. Obtenga más información en el Guía del usuario de Amazon Nova. Comience a construir sus aplicaciones de IA con Amazon Nova en el Consola de roca en Amazon.


Sobre los autores

Granjero de jean es un arquitecto generativo de soluciones de IA en el equipo de Inteligencia General Artificial (AGI) de Amazon, especializada en aplicaciones de agente. Con sede en Seattle, Washington, trabaja en la intersección de sistemas de IA autónomos y soluciones comerciales prácticas, ayudando a dar forma al futuro de AGI en Amazon.

Mukund Birje es un gerente de marketing de productos Sr. en el equipo AIML en AWS. En su papel actual, se ha centrado en impulsar la adopción de los modelos de la Fundación Amazon Nova. Tiene más de 10 años de experiencia en marketing y marca en una variedad de industrias. Fuera del trabajo puedes encontrarlo de excursión, leer y probar nuevos restaurantes. Puedes conectarte con él en LinkedIn.