Como gerar um resultado estruturado com o Nova
O resultado estruturado é essencial para casos de uso de comunicação entre máquinas, já que ele permite que casos de uso subsequentes consumam e processem os resultados gerados com mais eficiência. Seja extraindo informações de documentos, criando assistentes que buscam dados de APIs ou desenvolvendo agentes que realizam ações, essas tarefas exigem modelos básicos para gerar resultados em formatos estruturados específicos.
Os modelos do Nova utilizam a decodificação restrita para garantir a alta confiabilidade do modelo no resultado gerado e permitir que o modelo trate esquemas complexos com facilidade. A decodificação restrita depende de uma gramática para “restringir” os possíveis tokens que um modelo pode gerar em cada etapa. Isso se diferencia das técnicas de geração de prompts usadas historicamente porque altera os tokens reais que um modelo pode escolher ao gerar uma saída. Por exemplo, ao fechar um objeto JSON, o modelo seria restrito a apenas um token } para selecionar. A decodificação restrita é aproveitada toda vez que uma configuração de ferramenta é passada. Como o uso da ferramenta já nos fornece um esquema específico, podemos usá-lo para gerar uma gramática de forma dinâmica com base no esquema desejado pelo desenvolvedor. A decodificação restrita impede que o modelo gere chaves inválidas e impõe os tipos de dados corretos com base no esquema definido.
Para aproveitar o uso da ferramenta com resultado estruturado, a etapa principal é definir o esquema JSON necessário para o resultado. Abaixo está um exemplo de um esquema JSON definido em uma definição tool_config:
tool_config = { "tools": [ { "toolSpec": { "name": "ProductAnalysis", "description": "Analyze product information from text.", "inputSchema": { "json": { "type": "object", "properties": { "name": { "type": "string", "description": "Product name" }, "rating": { "maximum": 5, "description": "Customer rating 1-5", "type": [ "number", "null" ], "minimum": 1 }, "features": { "description": "Key product features", "type": "array", "items": { "type": "string" } }, "category": { "type": "string", "description": "Product category" }, "price": { "type": "number", "description": "Price in USD" } }, "required": [ "name", "category", "price", "features" ] } } } } ], "toolChoice": { "tool": { "name": "ProductAnalysis" } } }
Ao chamar a ferramenta posteriormente usando o modelo, você receberá uma saída que responde no formato do esquema. Por exemplo, abaixo está um exemplo de como chamar o modelo em Python:
import boto3 client = boto3.client("bedrock-runtime") model_id = "amazon.nova-lite-1-5-v1:0" user_query = """The Amazon Kindle Scribe is a state-of-the-art e-reader designed for both reading and writing, featuring a 10.2-inch paper-like display and a premium stylus. This versatile device allows users to enjoy books, take notes, annotate PDFs, and even sketch, making it ideal for readers, students, and professionals. Priced at $339.99, it falls under the electronics category and boasts features like a front light, adjustable warm light settings, and up to 12 weeks of battery life on a single charge. Customer ratings for the Kindle Scribe average around 4.5 stars, reflecting its high user satisfaction.""" messages = [{ "role": "user", "content": [{ "text": user_query }] }] system = [{"text": "Leverage the ProductAnalysis tool to extract product information"}] inference_params = {"temperature": 0} response = client.converse(modelId=model_id, system=system, messages=messages, toolConfig=tool_config, inferenceConfig=inference_params) print(next( block["toolUse"] for block in response["output"]["message"]["content"] if "toolUse" in block ))
A saída então aparece assim:
{ "toolUseId": "tooluse_hke1FUeuRbKXK8DPqIptVg", "name": "ProductAnalysis", "input": { "name": "Amazon Kindle Scribe", "rating": 4.5, "features": [ "10.2-inch paper-like display", "premium stylus", "front light", "adjustable warm light settings", "up to 12 weeks of battery life" ], "category": "electronics", "price": 339.99 } }