26 de set. de 2026

Jev vs pedir um JSON a um LLM

Por que um modelo de decisões e um modelo de linguagem não são intercambiáveis — e como estruturar uma base de código que usa os dois.

Dois contratos diferentes

Um modelo de chat escreve texto. Mesmo com JSON mode ou structured outputs estritos, ele ainda está amostrando tokens rumo a um schema — a forma é garantida, o conteúdo é gerado. O Jev funciona ao contrário: o conteúdo é garantido (ele só pode retornar uma opção que você declarou) e o que o modelo agrega é a distribuição de probabilidade sobre as suas opções declaradas. São contratos diferentes, e quebram de maneiras diferentes.

  • Modelo de chat com JSON mode: a forma sai certa, mas pode aparecer um rótulo que você não declarou ("billingx" em vez de "billing"), canonização inconsistente, ou o payload embrulhado em prosa. Você escreve um parser, uma checagem de allowlist e um loop de retry.
  • Modelo de decisões: o espaço de respostas são os criteria que você enviou. Uma pergunta choice com três opções retorna exatamente uma das três mais uma probabilidade para cada. Não há nada para interpretar, porque nada foi gerado.

Onde o LLM realmente ganha

Tarefas de geração — escrever o e-mail, resumir o ticket, rascunhar o SQL — pertencem ao modelo de chat. Nada mais estreito os substitui. Structured outputs também servem quando o que você precisa é de um objeto customizado (campos extraídos de um documento) em vez de uma decisão de ramificação. Mantenha esse pipeline como está.

A costura é a linha de código que hoje diz: if (await classify(text) === "billing"). Essa linha precisa de uma resposta limitada com probabilidade calibrada, não de texto fluente.

O problema da confiança

Peça um número de confiança a um modelo de chat e você o recebe — mas é um autorrelato sobre a própria fluência dele, não uma probabilidade calibrada sobre as opções que você declarou. Duas chamadas que reportam "85% de certeza" podem estar em regimes completamente diferentes. As probabilidades de um modelo de decisões são comparáveis entre entradas, e é isso que permite definir um único threshold ("encaminhar a um humano abaixo de 0.8") e confiar nele em centenas de milhares de chamadas.

Uma comparação com exemplo

Pegue a classificação de intenção em três filas — billing, technical, sales.

  • Abordagem com modelo de chat: um prompt com os rótulos, rodando em JSON mode. O custo escala com um system prompt e o contexto completo reenviado a cada chamada. Você se defende de rótulos indesejados com uma allowlist, e os erros de rota ficam silenciosos até um cliente reclamar.
  • Abordagem de decisão tipada: uma pergunta choice com as três descrições de criteria. Um ticket curto pesa 300–500 tokens de entrada — mínimo de 1 crédito, $0.0001 no Starter. Erros de rota aparecem como distribuições de probabilidade de alta entropia que você pode usar de threshold, em vez de o código aceitar silenciosamente um rótulo errado.

Usando os dois no mesmo processo

  • Deixe o LLM gerar ou extrair livremente onde criatividade ou compreensão forem o objetivo.
  • Coloque o Jev nas perguntas estreitas antes de o código agir: qual fila, qual tier de modelo, seguir ou bloquear.
  • Não trate nenhuma das saídas como decisão legal, médica ou financeira — defina um threshold e mantenha um humano no caminho de alto risco.

A maioria dos sistemas de produção acaba com os dois: o Jev para a ramificação repetida, o modelo de chat para aquilo em que é singularmente bom.

Modos de falha, lado a lado

  • Deriva de rótulos em texto livre: o LLM retorna "billing-related" onde seu switch quer "billing". A chamada tipada indexa probabilidades pelas chaves exatas que você declarou, então a deriva é estruturalmente impossível.
  • Campos alucinados: o JSON mode pode adicionar chaves que você não pediu. Um modelo de decisões não pode — o schema da resposta é fixado pelos tipos de pergunta.
  • Erros de rota silenciosos: o caso de deriva que passa porque o código downstream caiu em um default. Com uma decisão tipada, você registra a distribuição completa de probabilidade por chamada e revisa as bimodais.
  • Teatro de confiança: parse-then-assert ("tenho certeza de que é X") — impreciso, não calibrado. O confidence do Jev acompanha toda resposta de choice e score e alimenta o seu caminho de revisão humana.

Migrando um classificador baseado em parser

A migração é mecânica: pare de pedir um rótulo ao modelo de chat e coloque a mesma taxonomia nos criteria de uma pergunta choice, com o mesmo wording que o prompt usava. Resista à vontade de redescrever os rótulos; o wording do seu prompt existente já codifica as distinções da equipe. Rode duas semanas perguntando aos dois, registre a concordância — quando as divergências forem de 2% ou menos, olhe uma amostra de casos, e o final é sempre o mesmo: ou o wording dos criteria é ambíguo, ou o caso era genuinamente ambíguo e o sistema antigo já fazia roteamento errado em silêncio de qualquer forma.

A mesma requisição, de duas formas

Eis o que os dois contratos fazem sobre o mesmo ticket:

system: Classify the support message into billing, technical
or sales. Reply with {"queue": "..."}. Do not invent labels.
user: Charged twice for order A-104, please refund the duplicate.
Prompt de modelo de chat (rótulo forçado em JSON)
{
  "state": "Charged twice for order A-104, please refund the duplicate.",
  "questions": {
    "queue": {
      "type": "choice",
      "instructions": "Which team handles this?",
      "criteria": {
        "billing":  "Payments, payouts, invoicing, refunds",
        "technical": "Bugs, outages, integrations",
        "sales":    "Pricing, upgrades, new accounts"
      }
    }
  }
}
Requisição de decisão tipada

A primeira retorna {"queue": "billing"} quando vai bem, e qualquer coisa quando vai mal. A segunda retorna billing com uma probabilidade como 0.97, distribuições sobre as três opções e um valor de confiança — mais o mesmo contrato de falha a cada vez (uma forma de erro com error.code, nunca uma resposta errada que soe plausível). Projete o código downstream em torno da falha que você preferir depurar.

Um modelo de decisões é só um LLM com um prompt?

Não. O próprio espaço de respostas é limitado — as probabilidades vêm sobre as opções que você declarou — e o modelo é construído para esse trabalho, não para fluência. É por isso que as probabilidades são calibradas o bastante para aplicar thresholds.

Qual é mais barato para classificação?

Por decisão, o caminho tipado é difícil de superar: 1 crédito (o mínimo) para uma classificação curta — $0.0001 no Starter — contra uma chamada de modelo de chat que reenvia um system prompt a cada requisição e depois ainda precisa de código de validação e retries.

E a latência para classificação?

Medições contra o gateway em produção se concentram em 400–560 ms de latência por chamada. Uma chamada de chat fazendo a mesma classificação costuma ser igual ou mais lenta, porque gera texto que você depois precisa interpretar, validar e possivelmente tentar de novo.

Teste o playground do Jev AI para enviar sua primeira decisão gratuita depois de terminar este guia.