Structured Outputs
As saídas estruturadas restringem a resposta de um modelo de IA a um esquema, como o JSON Schema, durante a decodificação, permitindo que os aplicativos analisem cada resposta de forma confiável.
As saídas estruturadas são respostas de modelos limitadas a um formato predefinido, geralmente um Schema JSON que especifica as chaves obrigatórias, os respetivos tipos e os valores permitidos, para que o software possa analisar cada resposta sem limpeza adicional. Um modelo de linguagem grande (LLM) a quem se peça educadamente uma resposta em JSON costuma cumprir, mas ainda pode acrescentar uma frase em prosa, escrever uma chave incorretamente ou parar a meio de um objeto, e qualquer uma destas situações quebra o programa que lê a resposta. As saídas estruturadas eliminam esse risco com a descodificação restrita: em cada passo da geração, o motor de inferência só permite os tokens que mantêm a saída válida segundo o schema. Quando a OpenAI adicionou a funcionalidade à sua API em agosto de 2024, informou que o gpt-4o-2024-08-06 com saídas estruturadas obteve 100% na sua avaliação de conformidade com schemas JSON complexos, em comparação com menos de 40% para o GPT-4 (gpt-4-0613) sem a funcionalidade.
Modo JSON e saídas estruturadas#
As APIs dos fornecedores oferecem dois níveis de garantia. O modo JSON, introduzido pela OpenAI em novembro de 2023, garante apenas que a resposta é sintaticamente válida como JSON, pelo que ainda podem faltar chaves ou estas podem ter nomes incorretos. As saídas estruturadas garantem que a resposta corresponde ao schema fornecido. Na API Structured Outputs da OpenAI, os programadores definem o schema como um modelo Pydantic em Python ou um objeto Zod em JavaScript, e uma recusa é apresentada num campo separado em vez de quebrar o formato. As saídas estruturadas do Claude da Anthropic compilam cada schema numa gramática, o que acrescenta latência na primeira utilização do schema, e guardam a gramática compilada em cache durante 24 horas. Ambos os fornecedores só suportam um subconjunto do JSON Schema; por exemplo, o da Anthropic não suporta schemas recursivos nem limites numéricos como minimum.
Como funciona a decodificação restrita#
Em cada passo, um LLM produz uma pontuação, ou logit, para cada token do seu vocabulário, e a descodificação escolhe a partir da distribuição softmax resultante. A descodificação restrita define primeiro como menos infinito a pontuação de todos os tokens que quebrariam o formato, impedindo que sejam escolhidos. Brandon Willard e Rémi Louf mostraram como fazê-lo de forma eficiente em Efficient Guided Generation for Large Language Models: uma expressão regular ou um Schema JSON é compilado numa máquina de estados finitos, e um índice criado uma única vez sobre o vocabulário enumera os tokens válidos para cada estado, pelo que cada passo requer apenas uma consulta. A biblioteca de código aberto Outlines implementa o método, e motores de disponibilização como o vLLM oferecem geração orientada por gramáticas para modelos abertos.
O exemplo seguinte aplica manualmente a ideia ao GPT-2 dos Transformers do Hugging Face. O código escreve o texto fixo do schema — as chavetas, as chaves e as aspas —, e, para cada valor, o modelo só pode escolher entre os tokens permitidos pelo schema:
import json
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("gpt2")
model = AutoModelForCausalLM.from_pretrained("gpt2")
prompt = "Review: The battery died after two days and support never replied.\nJSON:"
# Descodificação gulosa sem restrições: nada obriga a resposta a seguir um schema
ids = tokenizer(prompt, return_tensors="pt").input_ids
free = model.generate(ids, max_new_tokens=16, do_sample=False, pad_token_id=tokenizer.eos_token_id)
print("free:", repr(tokenizer.decode(free[0, ids.shape[1] :])))
def choose(text, options):
"""Return the option GPT-2 scores highest after text, with every other token masked out."""
logits = model(tokenizer(text, return_tensors="pt").input_ids).logits[0, -1]
allowed = torch.tensor([tokenizer.encode(option)[0] for option in options])
masked = torch.full_like(logits, float("-inf"))
masked[allowed] = logits[allowed]
return tokenizer.decode(masked.argmax())
# Descodificação restrita: o schema escreve as chaves e o modelo só pode escolher valores permitidos
with torch.no_grad():
text = prompt + ' {"sentiment": "'
text += choose(text, ["positive", "negative"]) + '", "stars": '
text += choose(text, ["1", "2", "3", "4", "5"]) + "}"
print("constrained:", json.loads(text[len(prompt) :]))O resultado apresenta free: ' The battery died after two days and support never replied.\n\nJSON: The' e constrained: {'sentiment': 'positive', 'stars': 1}. Sem restrições, o GPT-2 repete a avaliação em vez de escrever JSON, enquanto a versão restrita pode sempre ser analisada. O resultado analisado também revela o limite da técnica: o modelo de 124 milhões de parâmetros avaliou como positiva, com uma estrela, uma bateria descarregada e um apoio ao cliente silencioso. O schema fixou o formato, mas os valores continuaram a refletir o juízo do próprio modelo.
Usos e compromissos#
- Extração de dados: Extrair nomes, datas, totais e itens de linha de faturas, contratos ou emails diretamente para linhas de uma base de dados.
- Chamada de funções: Uma chamada de ferramenta é uma saída estruturada cujo schema corresponde aos parâmetros da ferramenta. O uso estrito de ferramentas nas APIs da OpenAI e da Anthropic aplica a mesma garantia aos argumentos das ferramentas.
- Fluxos de trabalho agênticos: Decisões de encaminhamento expressas como valores de enumeração e resultados intermédios passados entre as etapas de uma cadeia de prompts como objetos tipados.
- Modelos de visão e linguagem: Deteções devolvidas como listas de etiquetas e coordenadas de caixas, que o código de desenho ou avaliação pode consumir diretamente.
A anotação inteligente orientada por classes na Ultralytics Platform depende desse último tipo de saída. Ela solicita que modelos de visão de provedores como OpenAI, Anthropic e Google detectem as classes de um conjunto de dados e adiciona cada objeto retornado como uma caixa delimitadora editável; por isso, cada resposta precisa nomear uma classe e fornecer coordenadas em um formato que o código possa analisar. Esses modelos não retornam pontuações de confiança, então a Platform oculta as configurações de confiança e IoU enquanto um deles está selecionado. O VLM Leaderboard compara a precisão com que esses modelos detectam objetos em conjuntos de dados do mundo real, classificando as caixas de cada modelo pela ordem em que são listadas.
Os formatos estritos podem prejudicar a precisão em tarefas de raciocínio. Em Let Me Speak Freely?, Zhi Rui Tam e colegas identificaram uma redução significativa no raciocínio de LLMs sujeito a restrições de formato, sendo as quedas maiores quanto mais estritas as restrições. A API da OpenAI gera as chaves pela ordem indicada no schema, pelo que uma solução comum é colocar um campo de raciocínio em texto livre antes do campo da resposta, para que o modelo escreva a sua cadeia de pensamento antes de se comprometer com a resposta restrita.










