Saídas estruturadas com IA: JSON confiável para automações em Python

Aprenda a transformar texto em dados validados com Structured Outputs, Pydantic e a Responses API para criar automações Python mais confiáveis.

Compartilhe

Fluxo de inteligência artificial transformando dados desorganizados em blocos estruturados para automação

Python + IA: Fundamentos e Projetos Práticos

Ambiente, sintaxe e variáveis em Python

Ambiente, Sintaxe Básica e Variáveis em Python — Bootcamp Dia 1

Tipos de dados, entrada e conversão em Python

Tipos de Dados, Entrada e Conversão no Python — Bootcamp Dia 2

Operadores em Python

Operadores Aritméticos, Relacionais e Lógicos em Python — Bootcamp Dia 3

Estruturas condicionais em Python

Estrutura Condicional com if, elif e else em Python — Bootcamp Dia 4

Loops e estruturas de repetição em Python

Repetição com for, while e range() no Python — Bootcamp Dia 5

Listas em Python

Como Trabalhar com Listas no Python — Bootcamp Dia 6

Tuplas e sets em Python

Tuplas e Sets em Python — Estruturas Imutáveis e Conjuntos Inteligentes | Bootcamp Dia 7

Dicionários em Python

Dicionários em Python: chave e valor, o jeito inteligente de armazenar dados

Funções em Python

Funções em Python: Escreva Menos, Faça Mais

Tratamento de erros em Python

Tratamento de Erros em Python: programe com segurança

Leitura e Escrita de Arquivos em Python

Leitura e Escrita de Arquivos em Python: salve seus dados no mundo real

Como Salvar Listas de Dicionários em Arquivo JSON com Python

Salvando Dados Estruturados com JSON em Python

Como Trabalhar com Datas em Python — Idade, Diferença e Formatação

Trabalhando com Datas e Horários em Python

Funções com Múltiplos Retornos em Python — Análise de Dados com Elegância

Funções com Múltiplos Retornos em Python: eficiência e organização

Parâmetros Opcionais e Valores Padrão em Python

Parâmetros Opcionais e Valores Padrão em Python

Como Usar args e kwargs em Funções Python

*args e **kwargs em Python: flexibilidade total nas funções

Como Usar List Comprehensions em Python

List Comprehensions em Python: código elegante e eficiente

Como Manipular Arquivos CSV com Python

Manipulando Arquivos CSV com Python: automatize leitura e escrita de dados

Como Usar Pandas em Python para Análise de Dados

Começando com Pandas em Python: análise de dados para IA e automações

Como Limpar e Preparar Dados com Pandas | Bootcamp Dia 20

Limpeza e Transformação de Dados com Pandas: preparando para IA

Como usar a OpenAI com Python (API Atualizada, GPT-3.5)

Inteligência Artificial com Python: Fundamentos e Primeira Integração com a OpenAI

Como fazer Análise de Sentimentos com Python e IA (Passo a Passo)

Análise de Sentimentos com IA: Classificando Emoções em Textos com Python

Como Classificar Textos com IA e Python (Zero-Shot Classification)

Classificação de Texto com IA: Detectando Temas e Categorias

Como Criar Textos com Python e IA (NLP + GPT-2)

Geração de Texto com IA: Criando Respostas Inteligentes com Python

Como Criar um Chatbot com IA em Python (com DialoGPT)

Chatbot com IA em Python: Construindo um Assistente Inteligente

Como Detectar Fake News com Python e IA — Projeto Prático

Como Detectar Fake News com Python e IA

Como Criar uma Interface com IA em Python para Detectar Fake News

Como Criar uma Interface com IA em Python para Detectar Fake News

Como Avaliar a Qualidade de um Modelo de IA com Python

Como Avaliar a Qualidade de um Modelo de IA com Python — Além da Acurácia

Como Balancear Dados e Validar Modelos com Python e IA

Como Balancear Dados e Validar Modelos com Python e IA

Classificador de Fake News com Interface Web em Python (Streamlit)

Projeto Final: Criando um Classificador de Fake News com Interface Web em Python (Streamlit)

Ambiente de desenvolvimento Python organizado com árvore de arquivos, dependências conectadas e lockfile protegido

Python com uv: ambientes virtuais e dependências reproduzíveis

Fluxo de inteligência artificial transformando dados desorganizados em blocos estruturados para automação

Saídas estruturadas com IA: JSON confiável para automações em Python

Fluxo seguro de function calling conectando uma inteligência artificial a ferramentas externas validadas

Function calling em Python: conecte a IA a ferramentas com segurança

Uma automação deixa de ser confiável no instante em que precisa “adivinhar” o formato da resposta de uma inteligência artificial. Um campo que muda de nome, um valor fora do padrão ou uma frase antes do JSON pode quebrar o fluxo inteiro. Para sair do protótipo e chegar a uma rotina que toma decisões com segurança, o modelo precisa responder dentro de um contrato verificável.

Nesta aula da série Python + IA: Fundamentos e Projetos Práticos, vamos usar Structured Outputs, Pydantic e a Responses API da OpenAI para transformar uma solicitação de suporte em dados tipados. O resultado poderá alimentar uma fila, um banco de dados, um webhook ou uma automação no n8n sem depender de expressões regulares frágeis.

O objetivo não é apenas obter um JSON válido. É garantir que os campos esperados existam, que os valores respeitem o schema e que o código Python saiba o que fazer quando a resposta não puder ser processada.

Por que “responda em JSON” não basta

Pedir JSON no prompt ajuda, mas não cria um contrato. O modelo ainda pode devolver uma chave diferente, omitir um campo obrigatório ou escolher um valor que sua aplicação não reconhece. O modo JSON resolve parte do problema porque produz JSON sintaticamente válido, mas não garante aderência ao formato de negócio.

Structured Outputs acrescenta essa garantia de schema. Segundo a documentação oficial da OpenAI, a resposta segue o JSON Schema fornecido, incluindo chaves obrigatórias e enumerações compatíveis com os recursos suportados. No SDK Python, podemos declarar o formato com um modelo Pydantic e receber o objeto já analisado.

Essa distinção muda a arquitetura. Em vez de extrair texto e tentar corrigi-lo depois, definimos primeiro o que a aplicação aceita. A IA passa a preencher esse contrato. Ainda precisamos validar regras de negócio e tratar falhas operacionais, mas eliminamos uma grande classe de erros de formatação.

Prepare o projeto e proteja a chave

Crie um ambiente isolado e instale o SDK da OpenAI e o Pydantic. Se você acompanhou a aula anterior sobre ambientes reproduzíveis com uv e pyproject.toml, pode continuar no mesmo padrão:

uv init triagem-ia
cd triagem-ia
uv add openai pydantic

A introdução oficial da API orienta configurar OPENAI_API_KEY como variável de ambiente; o SDK a lê automaticamente. Não coloque a chave no arquivo Python, no repositório ou em uma captura de tela. Em produção, use o gerenciador de segredos da sua infraestrutura e conceda acesso apenas ao serviço que executa a automação.

O projeto deste tutorial terá um arquivo main.py. A entrada será uma mensagem livre enviada por um cliente. A saída deverá conter categoria, prioridade, resumo, indicação de atendimento humano e tags.

Modele o contrato com Pydantic

Comece pelos valores que não podem variar livremente. A prioridade será uma enumeração, enquanto o restante será descrito em um modelo Pydantic:

from enum import Enum
from pydantic import BaseModel, Field


class Prioridade(str, Enum):
    baixa = "baixa"
    media = "media"
    alta = "alta"


class Triagem(BaseModel):
    categoria: str = Field(
        description="Fila curta: financeiro, acesso, suporte ou comercial"
    )
    prioridade: Prioridade
    resumo: str = Field(
        description="Resumo objetivo da solicitação em até duas frases"
    )
    requer_humano: bool
    tags: list[str]

O schema é a fronteira entre o modelo e o restante do sistema. Quanto mais previsível ele for, mais simples será integrar. Uma enumeração é melhor que instruções como “use baixa, média ou alta”, pois impede variações inesperadas. Para categoria, poderíamos criar outra enumeração; deixamos como texto neste exemplo para demonstrar uma validação de negócio posterior.

Evite transformar o schema em um espelho de toda a sua base. Inclua somente os dados necessários para a próxima decisão. Campos demais aumentam complexidade, manutenção e risco de armazenar informações que não deveriam circular.

Gere a resposta estruturada com a Responses API

Agora crie o cliente e use responses.parse. A documentação atual recomenda começar novos projetos com a Responses API e mostra o parâmetro text_format para informar o modelo Pydantic:

from openai import OpenAI

client = OpenAI()

solicitacao = """
Não consigo acessar minha conta desde ontem.
Já redefini a senha duas vezes e preciso emitir uma nota hoje.
"""

response = client.responses.parse(
    model="gpt-5.6",
    input=[
        {
            "role": "system",
            "content": (
                "Classifique solicitações de suporte. "
                "Não invente dados. Marque requer_humano como verdadeiro "
                "quando houver urgência, bloqueio de acesso ou ambiguidade."
            ),
        },
        {"role": "user", "content": solicitacao},
    ],
    text_format=Triagem,
)

triagem = response.output_parsed

if triagem is None:
    raise RuntimeError("A resposta não pôde ser convertida para o schema.")

print(triagem.model_dump_json(indent=2))

O atributo output_parsed entrega uma instância de Triagem, não uma string para ser decodificada manualmente. O editor, os testes e o analisador de tipos passam a conhecer os campos disponíveis. Se o schema mudar, o ponto de integração fica explícito.

O prompt de sistema continua importante. Structured Outputs garante a forma, mas não torna verdadeira uma classificação ruim. Descreva critérios objetivos, forneça contexto suficiente e teste exemplos reais antes de automatizar uma consequência relevante.

Transforme o resultado em uma decisão de automação

Com o objeto validado, a aplicação pode decidir a fila sem interpretar linguagem natural novamente:

CATEGORIAS_PERMITIDAS = {
    "financeiro",
    "acesso",
    "suporte",
    "comercial",
}


def decidir_fila(triagem: Triagem) -> str:
    categoria = triagem.categoria.strip().lower()

    if categoria not in CATEGORIAS_PERMITIDAS:
        return "revisao-manual"

    if triagem.requer_humano or triagem.prioridade is Prioridade.alta:
        return "atendimento-humano"

    return f"fila-{categoria}"


fila = decidir_fila(triagem)
print({"fila": fila, "dados": triagem.model_dump()})

Observe que ainda validamos as categorias permitidas. O schema resolve o formato; a função protege uma regra local. Essa separação é saudável: o modelo organiza e classifica, enquanto o código controla quais ações podem acontecer.

O dicionário retornado pode ser enviado a um endpoint, gravado em uma tabela ou passado a uma ferramenta de automação. Se você estiver decidindo entre um fluxo visual e código, veja também quando usar n8n ou programação para automatizar processos. Uma arquitetura comum usa Python para a classificação tipada e n8n para orquestrar notificações, CRM e filas.

Trate recusas, falhas e validações operacionais

Uma resposta estruturada não elimina indisponibilidade de rede, limites da API, recusa do modelo ou entrada maliciosa. Em produção, trate esses casos como estados esperados, nunca como exceções impossíveis.

  • Ausência de resultado analisado: não execute a ação. Envie o item para revisão ou uma fila de retentativa.
  • Falha temporária: aplique tentativas limitadas com espera progressiva. Não crie um ciclo infinito.
  • Regra sensível: pagamentos, bloqueios, decisões legais e alterações irreversíveis exigem confirmação humana.
  • Dados pessoais: envie apenas o mínimo necessário e evite registrar a mensagem completa em logs.
  • Observabilidade: registre identificador, duração, versão do schema, fila escolhida e tipo de falha, sem expor segredos.
  • Testes: mantenha exemplos de mensagens urgentes, vagas, contraditórias e fora de escopo.

Também defina um limite de tamanho para a entrada e normalize o texto antes do envio. Em vez de aceitar qualquer categoria produzida, use enumerações sempre que o domínio for estável. Quando o objetivo for chamar funções ou ferramentas durante a resposta, use function calling; quando o objetivo for estruturar a resposta do próprio modelo, use Structured Outputs em text.format. Essa é a separação recomendada na documentação.

Checklist prático e próximo passo

  • Criei um ambiente isolado e instalei openai e pydantic.
  • Configurei OPENAI_API_KEY fora do código.
  • Defini um modelo Pydantic pequeno e orientado à próxima decisão.
  • Usei responses.parse com text_format.
  • Verifiquei se output_parsed existe antes de agir.
  • Separei aderência ao schema de validação das regras de negócio.
  • Criei uma rota segura para falhas, recusas e categorias desconhecidas.
  • Adicionei logs mínimos, testes e revisão humana para ações sensíveis.

O salto de qualidade acontece quando a IA deixa de entregar “um texto que parece certo” e passa a participar de um sistema com contratos, limites e rotas de segurança. Structured Outputs torna a integração mais previsível; Pydantic aproxima o schema do código; e a função de decisão mantém a autoridade final na aplicação.

Como exercício, adapte Triagem ao seu contexto: leads, pedidos, currículos ou tickets internos. Separe dez entradas reais, defina a saída mínima que o próximo passo exige e teste os casos ambíguos. Na próxima evolução, esse mesmo objeto poderá alimentar uma API ou um fluxo completo de automação sem perder a rastreabilidade.

Python + IA: Fundamentos e Projetos Práticos

Python com uv: ambientes virtuais e dependências reproduzíveis Function calling em Python: conecte a IA a ferramentas com segurança

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.