Pular para o conteúdo

Uma equipe editorial e uma comunidade que criam com IA

← Prompt engineering

Prompt engineering · · 7 min de leitura

Chain-of-thought vs structured outputs: quando usar cada um

Quando você precisa de raciocínio e quando precisa de um JSON rígido. A tensão, os custos e um guia de decisão.

Chain-of-thought (CoT) e structured outputs são duas ferramentas que puxam o modelo em direções opostas. O CoT quer que o modelo pense em voz alta: de forma prolixa, livre, passo a passo. O structured output quer que o modelo trave a resposta num formato rígido, um JSON que passe na validação do schema. Essa tensão é real e custa dinheiro, latência e confiabilidade se você escolher errado. Este texto destrincha as duas abordagens e oferece um guia de decisão concreto para quem desenvolve em cima da API.

O que é chain-of-thought e quando ele realmente ajuda

CoT é um prompt que pede ao modelo para gerar etapas de raciocínio antes da resposta final. É o clássico “think step by step”, mas hoje vai muito além: os modelos de raciocínio produzem um fluxo de pensamento separado antes de emitir a resposta destinada ao usuário.

O CoT ajuda quando a tarefa exige raciocínio em várias etapas: matemática e aritmética, depuração de lógica (“por que este código retorna undefined”), planejamento de uma sequência de ações de um agente, comparação de muitas condições, inferência jurídica ou diagnóstico. Quando a resposta é função de uma cadeia de conclusões intermediárias, forçar essa cadeia aumenta de fato a precisão. O modelo não “chuta” o final; ele o deduz.

O CoT não ajuda em tarefas de uma etapa só: classificar um texto curto, extrair um campo de uma fatura, tomar uma decisão de sim ou não com base em uma única regra. Nesses casos, o raciocínio acrescenta tokens, latência e às vezes um ruído que reduz a qualidade. Gerar 400 tokens de “reflexões” para devolver um único rótulo é desperdício.

O que são structured outputs

Structured outputs são mecanismos que obrigam o modelo a devolver dados num formato previsível. Há três formas principais:

  • JSON mode: o modelo garante um JSON sintaticamente válido, mas sem controle sobre campos específicos.
  • response_format com schema (por exemplo, JSON Schema / constrained decoding): o modelo garante um JSON em conformidade com {"type":"object","required":["score"]}. Isso é grammar-constrained decoding: o sampler rejeita os tokens que quebrariam o schema.
  • Function calling / tool schemas: o modelo escolhe uma ferramenta e preenche os argumentos dela conforme a declaração, por exemplo get_weather(city: string).

O benefício é óbvio: um pipeline de produção recebe dados que vão direto para o JSON.parse e para a validação com Zod, sem parsing com regex. Nada de “o modelo acrescentou uma frase antes da chave de abertura”. Confiabilidade no nível de um contrato, e não de uma esperança.

Onde está a tensão

Aqui a coisa fica interessante. O constrained decoding limita o espaço de tokens que o modelo pode gerar: a cada passo, só são permitidos os tokens que levam a um JSON válido. Mas o raciocínio é, por natureza, livre. Se você obriga o modelo a emitir {"answer": já no primeiro token, tira dele o espaço para pensar. O efeito: em tarefas difíceis de matemática ou lógica, a qualidade pode cair, porque o modelo “pula para a resposta” em vez de deduzi-la.

Isso não é teoria. Quem já plugou um schema rígido de response_format numa tarefa que exige análise viu as respostas ficarem rasas. O modelo ganha um formato, mas perde o processo. E, em tarefas de raciocínio, o processo é a qualidade.

Como os modelos modernos permitem combinar os dois

A boa notícia: você não precisa escolher. Existem três padrões comprovados para combinar uma coisa com a outra.

Padrão 1: raciocínio, depois um campo estruturado

Um schema com dois campos: {"reasoning": string, "answer": ...}, em que reasoning vem primeiro. O modelo preenche esse campo com texto livre (tem espaço para o CoT) e depois, já “tendo pensado”, produz o answer estruturado. A ordem dos campos no schema importa: o raciocínio precisa vir antes da resposta, porque o modelo gera de forma sequencial. Um campo reasoning depois de answer é inútil: isso é racionalização, não raciocínio.

Padrão 2: reasoning tokens + uma resposta estruturada

Os modelos de raciocínio separam o “pensamento” da “resposta” no nível da API. O modelo pensa livremente num fluxo separado, e a resposta final para o usuário pode ser restringida por um schema. Você ganha CoT completo e JSON limpo na saída, sem concessões. Hoje, essa é a opção mais forte para tarefas difíceis que precisam cair num pipeline.

Padrão 3: duas chamadas

Chamada A: CoT livre, que devolve texto. Chamada B: pega esse texto e o “traduz” para um schema estrito (uma extração barata, de uma etapa só). É mais caro e mais lento (dois round-trips), mas dá controle total e funciona em qualquer modelo, inclusive nos que não têm modo de raciocínio nativo. É um bom fallback para modelos mais antigos e oferece isolamento total de erros: se o parsing falhar, você sabe que a culpa é da chamada B, e não do raciocínio.

Latência e custo

Cada token de raciocínio é tempo e dinheiro. O CoT pode multiplicar os tokens de saída por 5-20× em comparação com uma resposta seca. Nos modelos de raciocínio, os reasoning tokens normalmente são cobrados como saída e podem sair caros. Três consequências:

  • Latência: uma saída mais longa significa mais tempo até o último token. Para uma UI síncrona (chat, autocomplete), isso pode ser fatal.
  • Custo: uma tarefa com CoT pode custar várias vezes mais para a mesma entrada. Com um milhão de requisições por mês, isso vira uma linha real no orçamento.
  • O padrão de duas chamadas dobra os round-trips de rede: você soma o overhead de latência da conexão, e não só o da geração.

Regra: não pague por raciocínio onde você não precisa dele. Uma classificação num modelo pequeno, sem CoT, muitas vezes sai 10× mais barata e mais rápida, com qualidade idêntica.

Confiabilidade em pipelines de produção

Produção tem uma régua diferente da de um protótipo. Aqui o que conta é quantas requisições a cada 10 mil precisam de intervenção manual. Um CoT puro, que devolve texto, é frágil: você precisa fazer parsing de texto livre com regex e, de vez em quando, o modelo muda a formatação e o parser quebra. O structured output com constrained decoding elimina essa classe de bugs: o JSON é válido por definição.

Por isso, para qualquer saída que alimenta outro sistema (um banco de dados, uma fila, o próximo passo do agente), use structured output por padrão. Deixe o texto livre para a saída que um humano vai ler. E, quando você precisar tanto da qualidade do raciocínio quanto da confiabilidade do formato, combine os dois com o padrão 1 ou 2. Sempre valide o resultado com Zod na fronteira do sistema, mesmo com constrained decoding: o schema do provedor e o seu contrato de domínio não são a mesma coisa.

Guia de decisão

Use CoT quando: a tarefa tem várias etapas (matemática, lógica, depuração, planejamento de agentes), a precisão aumenta com raciocínio explícito e um humano lê a saída ou você tem orçamento de tokens e de latência. Sinal de alerta: se você não consegue nomear as etapas intermediárias, o CoT provavelmente não vai trazer ganho nenhum.

Use structured output quando: o resultado alimenta um pipeline, a tarefa é de uma etapa só (extração, classificação, roteamento, preenchimento de argumentos de ferramentas) e o que importa é a confiabilidade do parsing e a baixa latência. Um modelo pequeno mais um schema costuma ser a solução mais barata e mais confiável.

Combine os dois quando: você precisa de raciocínio e de uma saída legível por máquina. Escolha reasoning tokens + uma resposta estruturada (padrão 2) se o modelo suportar. Caso contrário, um schema {reasoning, answer} com o raciocínio primeiro (padrão 1). Mantenha o padrão de duas chamadas como fallback para modelos mais antigos ou para quando você precisar de isolamento total de erros.

Erros comuns

  • Um campo reasoning depois de answer no schema. O modelo já respondeu; o resto é teatro. O raciocínio vem sempre primeiro.
  • Um schema rígido numa tarefa difícil, sem espaço para pensar. Você ganha formato e perde qualidade. Acrescente um campo para o CoT ou use reasoning tokens.
  • CoT de 400 tokens numa classificação em que um único rótulo bastaria. Você paga por ruído.
  • Nenhuma validação com Zod “porque o schema do provedor garante o JSON”. Ele garante a sintaxe, não o seu contrato de domínio nem as faixas de valores.

TL;DR

O CoT aumenta a qualidade em tarefas de várias etapas, mas custa tokens e latência. O structured output dá confiabilidade de parsing, mas um schema rígido sufoca o raciocínio. Para tarefas de uma etapa num pipeline: structured. Para raciocínio que um humano vai ler: CoT. Quando você precisa dos dois, combine: reasoning tokens + uma resposta estruturada, ou um schema com um campo reasoning antes de answer. E sempre valide o resultado na fronteira do sistema.

Chain-of-thought vs structured outputs: quando usar cada um | vibecoding.inc