Como saber se a Decisions API acerta no seu caso: montando um conjunto de casos rotulados antes de ir pra produção

Pra saber se a Decisions API acerta no seu caso, monte um conjunto de casos rotulados antes de ir pra produção: separe decisões reais já tomadas por humanos, inclua casos de borda etiquetados por tipo, rode tudo via POST /v1/decisions com o gpt-6-luna guardando a resposta inteira e compare com o gabarito, total e por tipo de caso, com uma tabela de confusão. Quando o erro se repete num grupo, revise as opções, a pergunta e o próprio gabarito, e mande os casos ambíguos pra revisão humana usando confidence ou probabilities
Fala aí, beleza? Uma demo bonita no Playground não prova que a Decisions API acerta nos SEUS casos
E é exatamente isso que tu precisa descobrir antes de plugar ela no sistema 🙂
A Decisions API é da OpenAI e entrou em beta pública pra todos os desenvolvedores em 6 de outubro de 2026, depois de um preview no DevDay de 29 de setembro
A OpenAI diz que a versão estável (GA) sai nas próximas semanas, mas ainda sem data
Ou seja: é beta. E beta é justamente o momento em que validar antes de produção pesa MUITO mais
Se liga num detalhe que facilita a vida: ela não gera texto livre
Você manda uma entrada (texto ou imagem) e perguntas, e ela devolve respostas tipadas
Isso deixa a comparação com um gabarito humano direta, sem ficar interpretando parágrafo de resposta, legal né? 😀
Então bora pro passo a passo: montar casos rotulados, incluir bordas de propósito, comparar com o gabarito e agir quando o erro aparece sempre no mesmo lugar
O que você precisa antes de começar
Nada de PC da Nasa aqui, a lista é curta:
- Acesso à API da OpenAI: ela está em beta pública pra todos os desenvolvedores
- O modelo gpt-6-luna: hoje é o único modelo disponível nela
- Uma fonte de decisões humanas já tomadas: tickets classificados, pedidos roteados ou filas priorizadas, que batem com os casos de uso que a própria OpenAI indica (classificar conteúdo, rotear pedidos e priorizar trabalho)
- Uma planilha ou CSV pra guardar o gabarito
- A documentação oficial da Decisions API aberta do lado, porque o formato da requisição vem de lá
Sobre custo: com o gpt-6-luna a API cobra US$ 0,10 por 1 milhão de tokens de entrada, sem cobrança de tokens de saída nem de leitura ou escrita de cache
Na prática isso deixa barato rodar o conjunto inteiro várias vezes, e tu VAI rodar várias vezes haha
Formação Claude Code
Domine Claude Code do absoluto zero até o avançado
- 120 aulas
- 4 projetos
- 9h 45min
Passo a passo: montando e rodando seu conjunto de casos rotulados
1. Defina a decisão e escolha o tipo de pergunta
Antes de juntar qualquer exemplo, escreve numa frase qual decisão a API vai tomar
Aí escolhe o tipo de pergunta que encaixa nela, porque são três:
- predicate: devolve uma estimativa de 0 a 1 de que uma condição é verdadeira (ex: "este ticket é reclamação de cobrança?")
- choice: escolhe uma das opções que você forneceu (ex: rotear pra "financeiro", "suporte técnico" ou "comercial")
- score: avalia a entrada em níveis ordenados e devolve a média ponderada por probabilidade dos índices desses níveis (ex: prioridade baixa, média, alta)
E o que é essa tal média ponderada? É um número entre os índices dos níveis, não o nome do nível
Então no score tu vai precisar converter esse número de volta pra um nível na hora de comparar (a gente faz isso no passo 6)
O erro comum deste passo: criar opções de choice diferentes dos rótulos que os humanos usaram
Se o time marcava "Financeiro" e tu passa "cobrança" como opção, a comparação quebra logo de cara
Usa exatamente o vocabulário do gabarito, beleza?
2. Separe exemplos reais já decididos por humanos
Aqui mora o coração do método: casos que alguém do time já decidiu, com a decisão anotada
Monta um CSV com uma coluna de id, a entrada e uma coluna rotulo_esperado, algo assim:
| id | entrada | rotulo_esperado | tipo_de_caso |
|---|---|---|---|
| 1 | Fui cobrado duas vezes no cartão | financeiro | normal |
| 2 | O app fecha quando abro o relatório | suporte técnico | normal |
| 3 | Quero mudar de plano e o botão não funciona | comercial | duas categorias |
| 4 | ajuda | suporte técnico | curto demais |
A coluna tipo_de_caso já fica preparada pro próximo passo
O erro comum deste passo: pegar só os casos fáceis ou só os mais recentes
Caso fácil todo mundo acerta, inclusive a API
E os mais recentes podem esconder sazonalidade, então espalha a amostra no tempo e entre as categorias
3. Inclua casos de borda de propósito
Caso de borda é onde a classificação costuma escorregar, então tu vai CAÇAR esses casos:
- ambíguos, que até o time discutiria
- curtos demais, tipo "ajuda" ou "???"
- com imagem, já que a API aceita texto ou imagem como entrada
- que caberiam em duas categorias
Cada um ganha uma etiqueta na coluna tipo_de_caso ("ambíguo", "curto demais", "com imagem", "duas categorias")
Os casos comuns ficam como "normal"
O erro comum deste passo: misturar as bordas no meio do conjunto sem etiqueta
Sem a etiqueta, depois tu não consegue separar o erro por grupo e a análise vira um chute
Já vi muita planilha morrer por causa disso 😛
4. Teste algumas entradas no Playground antes de escrever código
A API está disponível no Playground da OpenAI, com perguntas e entradas, sem precisar de uma linha de código
Usa isso pra ajustar a pergunta e as opções com uns exemplos do gabarito antes de automatizar
É aqui que tu pega o problema bobo, tipo opção com nome confuso, sem gastar tempo montando script
O erro comum deste passo: tirar conclusão com meia dúzia de exemplos
O Playground serve pra calibrar a pergunta, não pra dizer se a API acerta
Quem diz isso é o conjunto inteiro rodando no passo seguinte
5. Rode o conjunto via POST /v1/decisions e guarde a resposta inteira
Agora sim, código! A chamada vai pro endpoint POST /v1/decisions
O script abaixo lê o CSV, chama a API caso a caso e grava a resposta COMPLETA de cada um num arquivo respostas.jsonl
Se liga: o corpo da requisição e a autenticação tu monta seguindo a documentação oficial, por isso eles aparecem como pontos a preencher
import csv
import json
import requests
# Base da API e autenticação: preencha conforme a documentação oficial
BASE_URL = "PREENCHA_CONFORME_A_DOCUMENTACAO"
HEADERS = {}
def montar_payload(linha):
# Monte aqui o corpo da requisição seguindo a documentação oficial
# da API: modelo gpt-6-luna, a entrada (texto ou imagem)
# e a pergunta definida no passo 1
raise NotImplementedError("preencha conforme a documentação")
with open("gabarito.csv", newline="", encoding="utf-8") as f, \
open("respostas.jsonl", "w", encoding="utf-8") as saida:
for linha in csv.DictReader(f):
resp = requests.post(
f"{BASE_URL}/v1/decisions",
json=montar_payload(linha),
headers=HEADERS,
timeout=60,
)
corpo = resp.json() if resp.ok else resp.text
registro = {"id": linha["id"], "status": resp.status_code, "resposta": corpo}
saida.write(json.dumps(registro, ensure_ascii=False) + "\n")
No tipo choice, a resposta traz o valor escolhido (sempre um dos que você forneceu), um array probabilities com as probabilidades por opção e um campo confidence separado
Guarda tudo, porque é esse material que salva tua vida na hora de investigar erro
E pra testar o próprio script sem gastar chamada de verdade, vale aplicar a ideia de mocks, fixtures e casos de borda no teste do código
O erro comum deste passo: salvar só o valor final e jogar fora probabilities e confidence
Sem eles tu não consegue ver se o erro foi uma escolha apertada ou uma escolha errada "com convicção", e são problemas bem diferentes
6. Compare as decisões com o gabarito, no total e por tipo de caso
Último passo do ciclo: cruzar esperado com obtido
O script abaixo calcula acertos no total, acertos por tipo_de_caso e monta uma tabela de confusão simples (quantas vezes o rótulo X virou Y)
Pra predicate e score, o corte é decisão SUA: o predicate vira sim/não comparando a estimativa com um limite que tu escolhe, e o score é arredondado pro índice de nível mais próximo
import csv
import json
from collections import Counter
TIPO = "choice" # "choice", "predicate" ou "score"
CORTE = 0.5 # só pra predicate: ajuste ao seu caso
NIVEIS = ["baixa", "media", "alta"] # só pra score: os níveis na ordem que você definiu
def extrair_valor(resposta):
# Ajuste os caminhos dos campos ao formato de resposta da documentação oficial
if TIPO == "choice":
return resposta["choice"]
if TIPO == "predicate":
estimativa = resposta["CAMPO_DA_ESTIMATIVA"]
return "sim" if estimativa >= CORTE else "nao"
if TIPO == "score":
media = resposta["CAMPO_DA_MEDIA"]
return NIVEIS[round(media)]
esperado, grupo_de = {}, {}
with open("gabarito.csv", newline="", encoding="utf-8") as f:
for linha in csv.DictReader(f):
esperado[linha["id"]] = linha["rotulo_esperado"]
grupo_de[linha["id"]] = linha["tipo_de_caso"] or "normal"
total, acertos, falhas_api, confusao = Counter(), Counter(), 0, Counter()
with open("respostas.jsonl", encoding="utf-8") as f:
for linha in f:
r = json.loads(linha)
if r["status"] != 200:
falhas_api += 1
continue
obtido = extrair_valor(r["resposta"])
esp = esperado[r["id"]]
for grupo in ("TOTAL", grupo_de[r["id"]]):
total.update((grupo,))
if obtido == esp:
acertos.update((grupo,))
if obtido != esp:
confusao[(esp, obtido)] += 1
print(f"Chamadas com erro: {falhas_api}")
for grupo, n in sorted(total.items(), key=lambda par: par[0] != "TOTAL"):
ok = acertos.get(grupo, 0)
print(f"{grupo}: {ok}/{n} ({ok / n:.0%})")
print("\nConfusões (esperado -> obtido):")
for (esp, obt), n in confusao.most_common():
print(f"{esp} -> {obt}: {n}")
Repara que a saída lista cada grupo separado do TOTAL
É isso que mostra se a API vai bem nos casos normais e tropeça, por exemplo, nos curtos demais
O erro comum deste passo: olhar só a média geral
Um número geral bonito pode esconder um grupo inteiro errando, e se esse grupo é justamente o que importa pro teu negócio… já era
O que fazer quando a Decisions API erra sempre no mesmo tipo de caso
O sintoma clássico: os erros se concentram num grupo só
Uma categoria que vira sempre outra na tabela de confusão, ou o grupo "com imagem" bem abaixo do resto
Antes de sair trocando tudo, se liga nas causas mais prováveis e no que fazer com cada uma:
- Opções do choice sobrepostas ou mal nomeadas. Se "suporte" e "suporte técnico" convivem, a confusão vem do teu enunciado, não da API. Reescreve as opções pra que cada uma tenha uma fronteira clara
- A pergunta mistura duas decisões. "É urgente e de cobrança?" são duas perguntas disfarçadas de uma. Quebra em perguntas separadas ou troca o tipo: de choice pra predicate quando a decisão é sim/não, ou pra score quando existe ordem entre os níveis
- O gabarito humano é inconsistente nesse grupo. Às vezes o time rotulou casos parecidos de jeitos diferentes. Revisa os rótulos daquele grupo antes de culpar a API, porque gabarito zoado gera erro que não existe
- O caso é genuinamente ambíguo. Tem coisa que nem gente concorda. Aqui o caminho é usar o
confidenceou asprobabilitiespra mandar esses casos pra revisão humana em vez de automatizar tudo
No item 4, tome cuidado: a documentação oficial não detalha como interpretar o campo confidence
Então o limite que separa "automatiza" de "manda pra humano" tu define olhando os teus próprios resultados no conjunto rotulado, não por achismo
E a regra de ouro: depois de CADA mudança, roda o conjunto inteiro de novo
Ajeitar um grupo e quebrar outro sem perceber é mais comum do que parece haha
Como prevenir que o erro volte
Mantém o conjunto rotulado vivo
Toda vez que aparecer um erro em produção, ele entra no CSV como caso novo, com rótulo e tipo de caso
Assim o gabarito vai ficando cada vez mais parecido com a vida real do teu sistema 🙂
E revalida quando a API sair da beta pra versão estável, já que a GA ainda não tem data e o comportamento pode mudar
Esse é o mesmo raciocínio de montar um eval de regressão a cada atualização: o conjunto que tu montou hoje vira teu alarme amanhã
Próximo passo: comece com 50 casos reais antes de qualquer integração
Recapitulando o caminho:
- gabarito com decisões que humanos já tomaram
- casos de borda incluídos de propósito e etiquetados
- comparação no total E por tipo de caso, com tabela de confusão
- ação focada no grupo que erra, rodando tudo de novo a cada ajuste
O próximo passo concreto é simples: separa hoje um lote pequeno de decisões reais (uns 50 é um bom ponto de partida pra começar, não uma regra da API), joga alguns no Playground e só depois escreve a integração
A OpenAI afirma que a Decisions API decide até 10x mais rápido que o GPT-6 Luna chamado pela Responses API
Mas velocidade e acerto no TEU caso só o teu conjunto rotulado responde, e é por isso que ele vem antes de qualquer linha de integração
Faça o teste e me conta onde ela tropeçou! 😀
Até o próximo post!
Perguntas frequentes
Quanto custa usar a Decisions API em produção?
Com o gpt-6-luna, a API cobra US$ 0,10 por 1 milhão de tokens de entrada. Não tem cobrança de tokens de saída nem de leitura ou escrita de cache. Isso torna barato rodar um conjunto de testes inteiro várias vezes antes de ir pra produção.
Quando a Decisions API deixa de ser beta e vira GA?
A OpenAI diz que espera lançar a versão estável (GA) nas próximas semanas, mas ainda sem data confirmada. Hoje ela está em beta pública, que começou em 6 de outubro de 2026 depois de um preview no DevDay de 29 de setembro. Enquanto não vira GA, vale mais ainda validar com casos rotulados antes de confiar em produção.
Dá pra usar outro modelo além do gpt-6-luna na Decisions API?
Não, hoje o gpt-6-luna é o único modelo disponível nela. Então todo o conjunto de casos rotulados que você montar vai ser testado com ele.
Qual a diferença entre os tipos predicate, choice e score na Decisions API?
O predicate devolve uma estimativa de 0 a 1 de que uma condição é verdadeira. O choice escolhe uma das opções que você forneceu e ainda devolve probabilidades por opção e um confidence separado. Já o score avalia a entrada em níveis ordenados e devolve a média ponderada por probabilidade dos índices desses níveis, por isso precisa converter de volta pra um nível na hora de comparar com o gabarito.
A Decisions API é mais rápida que chamar o GPT-6 Luna direto?
Segundo a OpenAI, sim: ela decide até 10x mais rápido que o GPT-6 Luna chamado pela Responses API, como a gente cita no fechamento do post. Mas velocidade não diz se ela acerta no teu caso: isso só o conjunto de casos rotulados responde.
Preciso escrever código pra começar a testar a Decisions API?
Não necessariamente no começo. Dá pra testar a API no Playground da OpenAI, com perguntas e entradas, antes de escrever qualquer código. Isso ajuda a calibrar a pergunta e as opções com uns exemplos do gabarito, mas o conjunto completo de casos só valida de fato rodando via POST /v1/decisions.
Formações
Formação Vibe Coding
Do Prompt ao Produto: Crie Software Real com IA
- 474 aulas
- 20 projetos
- 39h 27min
Blog | Mais populares
Como classificar ticket, e-mail e mensagem com lista fechada de opções na Decisions API da OpenAI
Decisions API classifica ticket, e-mail e mensagem só com opções fixas que você define, sem categoria inventada. Veja como configurar.
Quando não usar a Decisions API da OpenAI: os casos em que uma regra simples em código resolve melhor
Decisions API resolve tudo? Veja quando um if em código ganha da IA da OpenAI em custo, consistência e auditoria.

Como escrever uma rubrica que a Decisions API aplique sempre do mesmo jeito
Entenda como montar uma rubrica Decisions API com níveis testáveis, fronteiras claras e sem rótulos vagos para a OpenAI aplicar sempre igual.
