De todas as primitivas do Jev, Choice é a que mais parece mágica no primeiro contato — e é a mais fácil de entender. Você define uma lista de opções, o modelo escolhe uma e devolve a probabilidade de todas. É um classificador que você escreve em cinco linhas e troca de rubrica sem retreinar nada.
O formato
Uma pergunta Choice tem type: "choice", as instructions e o criteria: um
mapa em que cada chave é uma opção e cada valor, a descrição dela. O modelo vê os
nomes e as descrições — por isso a orientação oficial é escrever descrições
que separem bem as opções umas das outras.
{
"time": {
"type": "choice",
"instructions": "Qual time deve atender este ticket?",
"criteria": {
"trocas": "Trocas, reembolsos, itens errados ou danificados",
"entrega": "Status de entrega, atrasos, pacotes perdidos",
"cobranca": "Cobranças, faturas, problemas de pagamento"
}
}
}
A resposta traz três coisas por pergunta: choice (a opção vencedora),
probabilities (a probabilidade de cada opção — a soma dá 1) e confidence
(a confiança, derivada do formato da distribuição: pico concentrado, confiança
alta; distribuição espalhada, confiança baixa).
Um exemplo de resposta, do jeito que chega:
{
"time": {
"type": "choice",
"choice": "trocas",
"confidence": 0.39,
"probabilities": { "entrega": 0.02, "cobranca": 0.38, "trocas": 0.6 }
}
}
Esse caso vem da documentação e ensina o ponto central da primitiva: o ticket
menciona tamanho errado (trocas) e uma cobrança dupla (cobrança). A
distribuição mostra as duas fortes — 0,60 e 0,38 — e a confiança cai para 0,39.
Um sistema ingênuo ficaria só com choice; um sistema bem-feito lê as
probabilidades e manda uma cópia para o segundo time também.
O que fazer com as probabilidades
A documentação sugere três usos diretos:
- Agir no pico, vigiar o segundo. Se uma opção não-escolhida passa de um limiar (o exemplo oficial usa 0,25), notificar o time correspondente.
- Usar a confiança como porteira. Confiança abaixo de um limiar manda para triagem humana, em vez de apostar. A página de confiança dos docs sugere faixas: alta age sozinha, média confirma, baixa escala para uma pessoa.
- Encadear níveis. Para taxonomias profundas, uma Choice por nível da hierarquia, usando as probabilidades do nível anterior para escolher as opções do próximo.
Até 255 opções — e o truque dos dois estágios
Uma pergunta Choice aceita até 255 opções. Duas consequências práticas:
- Dê a lista completa, não uma curta. Cada opção custa poucos tokens, e a orientação oficial é enviar o catálogo inteiro (todos os times, todas as categorias) em vez de um resumo — com uma opção “outro” para o que não encaixar.
- Acima disso, encadeie. O cookbook de classificação hierárquica roda uma busca por feixe sobre as probabilidades, mantendo os K melhores caminhos por nível. E o post de lançamento revela como a própria TypeSafe lida com cardinalidade muito alta internamente: um sistema de dois estágios que pontua de forma independente e depois faz a escolha explícita — daí uma lentidão ocasional que eles próprios admitem no demo de wikiracing.
Opções parecidas: descrição estruturada
Quando duas opções se confundem (o exemplo dos docs: return_policy versus
return_status — ambas falam de reembolso), a receita oficial é descrever cada
opção com um objeto em vez de texto simples: campos para o que a opção cobre,
o que pertence à vizinha e exemplos de entrada. Os nomes dos campos são seus —
não há nomes reservados — e o modelo os lê junto com os valores. Com a descrição
estruturada, a resposta do exemplo sai return_status com confiança 1,0.
Em português, o mesmo truque resolve pares como “reclamação de produto” versus “reclamação de atendimento”: diga o que cada uma cobre, o que não cobre e um exemplo de cada.
Exemplos que cabem no seu sistema
Três perguntas Choice em português prontas para adaptar:
from typesafe_sdk import Choice, TypeSafeClient
PERGUNTAS = {
"categoria": Choice(
instructions="Qual é a categoria principal desta mensagem?",
criteria={
"duvida_tecnica": "Problema técnico, bug ou dúvida de uso",
"cobranca": "Pagamentos, faturas, reembolso, cobrança indevida",
"cancelamento": "Desejo de cancelar conta, plano ou serviço",
"elogio": "Elogio, satisfação, recomendação",
"outro": "Nenhuma das anteriores",
},
),
"idioma": Choice(
instructions="Em que idioma esta mensagem está escrita?",
criteria={"portugues": None, "ingles": None, "espanhol": None, "outro": None},
),
"setor": Choice(
instructions="De qual setor da empresa vem esta solicitação?",
criteria={
"financeiro": "Contas a pagar, a receber, orçamento",
"comercial": "Vendas, propostas, contratos",
"suporte": "Atendimento e chamados",
"juridico": "Contratos, conformidade, regulatório",
"outro": "Nenhum dos setores listados",
},
),
}
with TypeSafeClient() as client:
resposta = client.system_one(state=texto_do_cliente, questions=PERGUNTAS)
Repare no None nas descrições do idioma: a documentação permite opções sem
descrição quando o nome já basta. E lembre da regra de ouro: mande junto as
perguntas de Score e Noul que usam o
mesmo estado — o custo extra é mínimo e a chamada continua única. O
playground roda exatamente duas Choice (categoria e sentimento)
mais quatro perguntas das outras primitivas em uma chamada só.
Perguntas frequentes
Quantas opções uma pergunta Choice aceita?
Até 255 opções por pergunta, segundo a documentação oficial. Acima disso, o cookbook oficial de classificação hierárquica encadeia perguntas Choice nível a nível, mantendo os melhores caminhos pelas probabilidades.
Choice devolve só a opção escolhida?
Não. A resposta traz a opção com maior probabilidade em choice, a distribuição completa em probabilities e a confiança em confidence — um número de 0 a 1 que resume o quão concentrada está a distribuição.
Preciso de uma opção 'outro'?
A documentação recomenda incluir uma opção 'outro' ou 'nenhuma das anteriores' sempre que a lista possa não cobrir toda entrada — é o jeito do modelo dizer que nada se encaixa.
Como separo opções parecidas que o modelo confunde?
Troque a descrição de texto simples por um objeto com campos: o que a opção cobre, o que pertence à vizinha e exemplos. A documentação mostra o caso de duas políticas de reembolso confundidas resolvido assim.