Como usar o Jev para decidir se um pedido de reembolso pode ser aprovado sozinho?

fluxo do Jev reembolso mostrando state, perguntas tipadas e probabilidade calibrada
Resposta rápida

O Jev é o primeiro modelo da classe System One da TypeSafe AI: você manda um bloco de estado mais perguntas tipadas e ele devolve decisões com probabilidade calibrada, sem gerar texto. Num fluxo de reembolso isso significa montar o state com histórico do cliente, valor e motivo, escrever a política como perguntas (noul, choice e score) e ler a probabilidade de volta. Em cima dela você decide: aprovar automático na faixa alta, revisar no meio, escalar embaixo. Sem parsing de texto de LLM, sem regex em resposta de chat, e com os limiares calibrados nos seus próprios dados rotulados

Fila de reembolso crescendo, suporte afogado, e alguém do time resolve "automatizar"

Aí vem a gambiarra clássica: manda o pedido pra uma LLM, pede pra ela responder "APROVADO" ou "NEGADO", e escreve um if resposta.strip().upper() == "APROVADO" em cima disso 😅

Funciona até o dia em que o modelo responde "Aprovado, mas com ressalvas" e o seu parser explode

O Jev ataca exatamente esse ponto

Ele é o primeiro modelo da classe System One da TypeSafe AI, empresa sediada em São Francisco e fundada em 2024

A ideia é simples de entender e meio libertadora: você manda um bloco de estado mais perguntas tipadas, e ele devolve decisões tipadas com probabilidade calibrada

Ele não escreve texto

Não redige a resposta pro cliente, não resume o chamado, não explica o porquê da decisão

Ele só decide, com número junto

E olha que curioso: o Noul é uma das três primitivas de pergunta do Jev (já volto nelas com calma), e a documentação dessa primitiva usa como exemplo justamente perguntar se uma mensagem pede reembolso ("does this message ask for a refund"), então tu tá num terreno que o modelo foi feito pra pisar

O que você precisa antes de começar

Boa notícia pra quem tentou entrar lá em setembro e caiu em lista de espera: a lista acabou

Desde 20 de setembro de 2026 o acesso está aberto, qualquer pessoa cria conta no console.typesafe.ai e recebe US$ 5 em crédito gratuito pra brincar

O Jev tinha sido lançado em acesso antecipado limitado em 15 de setembro de 2026, então é coisa bem nova

O checklist é curto:

  • conta criada no console da TypeSafe e a chave de API gerada por lá
  • a chave exportada na variável de ambiente TYPESAFE_API_KEY (é ela que o cliente do SDK lê sozinho)
  • SDK instalado, Python ou JS, tanto faz
  • modelo: dá pra usar o alias jev-latest, que é o padrão do cliente

No Python:

pip install typesafe-sdk
# ou, se tu usa uv:
uv add typesafe-sdk

Requer Python 3.10 ou superior

No JavaScript/TypeScript:

npm install @typesafe-ai/sdk

Requer Node.js 20 ou superior

E a chave:

export TYPESAFE_API_KEY="sua_chave_do_console"

Sobre versão: jev-1.13.0 é a única versão publicada até agora, e existem os aliases jev-latest e jev-preview

O jev-latest resolve pra jev-1.13.0 hoje, e vai mudar quando sair versão nova

Tome cuidado! Se o seu fluxo de reembolso é crítico, fixar a versão exata te protege de mudança silenciosa de comportamento

E o custo? US$ 0,042 por milhão de tokens de entrada, com tokens de saída gratuitos

A latência declarada pela TypeSafe fica entre 70ms e 500ms, o que muda bastante o desenho: dá pra chamar no meio do request, não só em fila assíncrona

Os limites de taxa atuais do jev-1.13 são 250.000 tokens por segundo e 1.200 requisições por minuto, sujeitos a mudança sem aviso (planos custom e enterprise têm limites maiores)

Passo a passo: transformar a política de reembolso em decisão tipada

Aqui vale a regra de ouro antes do código: o Jev não adivinha a sua política

Ele avalia o que tu descreve

Então o trabalho pesado é de escrita, não de programação =)

  1. Escreva a política como critérios explícitos

Antes de tocar em qualquer SDK, pega a política de reembolso da empresa e transforma cada regra em uma frase que dá pra responder olhando os dados do pedido

Algo do tipo: "produto devolvido dentro do prazo de arrependimento", "cliente sem histórico de pedidos repetidos de reembolso", "motivo compatível com defeito de fabricação"

Se você não consegue escrever o critério em uma frase clara, o modelo também não vai conseguir julgar ele

O erro comum deste passo: escrever critério que depende de opinião interna não documentada ("caso a caso com o gerente")

Isso não vira pergunta, vira revisão humana, e tá tudo bem que seja assim

  1. Monte o state com o caso inteiro

O state enviado ao Jev pode ser uma string, um objeto JSON ou um array de texto

Pra reembolso, objeto JSON é o formato mais confortável, porque tu já tem esses dados no banco:

{
  "pedido": {
    "id": "PED-88412",
    "valor_centavos": 24990,
    "moeda": "BRL",
    "categoria": "eletronicos",
    "dias_desde_a_compra": 9
  },
  "solicitacao": {
    "motivo_declarado": "produto chegou com a tela trincada",
    "canal": "chat",
    "mensagem_do_cliente": "abri a caixa e a tela ja estava rachada, quero o dinheiro de volta"
  },
  "cliente": {
    "conta_criada_em": "2023-02-11",
    "pedidos_concluidos": 14,
    "reembolsos_aprovados_12m": 1,
    "reembolsos_negados_12m": 0,
    "chargebacks": 0
  },
  "politica": {
    "prazo_arrependimento_dias": 7,
    "prazo_defeito_dias": 30,
    "teto_aprovacao_automatica_centavos": 30000
  }
}

Repara no dias_desde_a_compra

Ele já vem calculado

Isso é de propósito

O erro comum deste passo: mandar as datas cruas e esperar que o Jev calcule o prazo

A documentação é explícita em não usar o modelo pra aritmética, contagem ou cálculo de datas

Conta é trabalho do seu código, decisão é trabalho do Jev

Mesma coisa vale pro valor: soma, imposto, frete, tudo calculado antes e mandado pronto

  1. Escreva as perguntas usando a primitiva certa

O Jev tem três primitivas de pergunta, e escolher errado aqui estraga o resultado:

Primitiva O que ela responde O que volta
noul probabilidade de uma proposição ser verdadeira um único número entre 0 e 1, sem campo de confiança separado
choice uma opção entre até 255 a opção escolhida, a probabilidade de cada opção e uma confiança derivada
score posição ponderada por probabilidade em até 10 níveis descritos uma posição que pode cair entre dois níveis, mais as probabilidades por nível e confiança

Pro nosso caso de reembolso, um desenho que cobre bem:

  • um noul pra "o pedido se enquadra na política de reembolso descrita no state"
  • um choice com as opções aprovar, recusar e revisar
  • um score pro risco de abuso, com os níveis ordenados do mais baixo pro mais alto

No Score, cada pergunta tem criteria, um array ordenado de descrições de nível indo do extremo baixo ao alto

E a resposta pode cair entre dois níveis, porque é média ponderada das probabilidades deles

A própria documentação recomenda descrever cada nível de forma distinta e manter cada Score em uma única dimensão

O erro comum deste passo (são dois, e os dois doem):

Primeiro: criar níveis de Score que você não sabe descrever

Se o nível 3 e o nível 4 ficam "meio parecidos", junta os dois

Segundo: misturar duas dimensões na mesma pergunta, tipo "risco de abuso e urgência do caso"

São dois Scores, não um

Misturar dimensão é a receita pra um número que não quer dizer nada

  1. Chame o endpoint único com todas as perguntas juntas

Toda a API do Jev vive em um único endpoint: POST https://api.typesafe.ai/v1/systemone, com corpo contendo state, model e questions

O questions é um mapa de nome da pergunta pra objeto de pergunta

E aqui vem a parte massa: todas as perguntas são avaliadas em paralelo e em isolamento contra o mesmo state, em uma única ida e volta

Na prática, adicionar mais perguntas quase não muda o tempo de resposta

Ou seja: não economiza pergunta

Se existe um critério que te ajuda a decidir, manda ele junto

O esboço do corpo fica assim:

{
  "model": "jev-latest",
  "state": { "...o objeto do passo 2...": true },
  "questions": {
    "dentro_da_politica": { "...pergunta noul...": true },
    "decisao": { "...pergunta choice com aprovar / recusar / revisar...": true },
    "risco_de_abuso": { "...pergunta score com criteria ordenado...": true }
  }
}

O formato exato de cada objeto de pergunta tu confere na documentação da API antes de rodar, porque chutar nome de campo é perder tarde inteira

E não precisa montar header de autenticação na mão: o cliente do SDK lê a TYPESAFE_API_KEY do ambiente e usa jev-latest por padrão

O erro comum deste passo: quebrar a avaliação em várias chamadas, uma por critério

Não faz sentido

As perguntas já rodam isoladas entre si contra o mesmo state, então uma chamada só resolve

Uma requisição, todas as perguntas juntas, e o tempo de resposta praticamente igual

  1. Leia a saída sem inventar parser

A sacada do Jev é que as respostas válidas são declaradas de antemão

Como o modelo não consegue devolver valor fora do schema informado, some a etapa de "limpar a resposta do modelo"

O que tu recebe:

  • do noul: um número entre 0 e 1 representando a probabilidade de a resposta ser sim (0,5 significa indeciso, e não existe campo de confiança separado aqui)
  • do choice: a opção escolhida, a probabilidade de cada opção e uma confiança derivada dessa distribuição
  • do score: a posição (que pode ficar entre dois níveis), as probabilidades por nível e a confiança

Esses números não são enfeite

O Jev é treinado com RLCD (Reinforcement Learning for Calibrated Decisions), método criado pela TypeSafe pra calibrar as probabilidades de saída

A ideia do RLCD é que confiança maior signifique acerto maior de verdade, e é justamente isso que permite o próximo passo

O erro comum deste passo: olhar só a opção escolhida do Choice e ignorar a distribuição

Um aprovar escolhido com probabilidades quase empatadas entre aprovar e revisar é um caso duvidoso disfarçado de decisão firme

Como definir os limiares de aprovar, revisar e escalar

A documentação sugere um desenho de três caminhos em cima da probabilidade devolvida:

  1. confiança alta: age automaticamente
  2. faixa do meio: marca pra revisão
  3. faixa baixa: escala pra uma pessoa

E aqui tem uma coisa que muita gente entende errado, então vou parar pra explicar

Essa escalada é lógica da SUA aplicação em cima da probabilidade

Não existe segunda pergunta, não existe segunda chamada de API, não existe "pedir pro modelo confirmar"

É um if no seu código lendo o número que já veio

APROVACAO_AUTOMATICA = ...   # você define com os seus dados
REVISAO_HUMANA = ...         # idem

if p_dentro_da_politica >= APROVACAO_AUTOMATICA and valor <= teto_automatico:
    aprovar_reembolso()
elif p_dentro_da_politica >= REVISAO_HUMANA:
    enviar_para_fila_de_revisao()
else:
    escalar_para_analista_senior()

Deixei os limiares vazios de propósito, e não é preguiça 😀

A orientação é definir esses valores com dados rotulados próprios e com o custo do erro versus o custo da revisão

Pensa no seu negócio: aprovar sozinho um reembolso baratinho indevido custa pouco, às vezes menos que o tempo de alguém parar pra olhar

Já um pedido de valor alto aprovado errado custa MUITO mais que uma revisão humana de dois minutos

Por isso a regra prática é exigir evidência mais forte pra ações de risco alto

Na prática isso vira limiar variável por faixa de valor: quanto maior o pedido, maior a probabilidade exigida pra liberar sem gente olhando

E dá pra combinar os sinais

Aprovação automática só quando o noul da política está alto e o score de risco de abuso está baixo, por exemplo

Esse mesmo raciocínio de três faixas se repete em outros fluxos, é o mesmo esqueleto que aparece quando você usa Jev para qualificar leads no funil: muda a pergunta, não muda o desenho

Quando essa decisão automática vale a pena (e quando não vale)

Onde encaixa bem:

  • triagem da fila: separar na entrada o que é claramente dentro da política do que precisa de olho humano, em vez de tratar tudo na mesma ordem de chegada
  • roteamento por valor: pedidos pequenos e de baixo risco seguem sozinhos, pedidos grandes vão pro analista com o score já anexado
  • pré-classificação de motivo: defeito, arrependimento, não recebido, cobrança duplicada, cada um caindo na esteira certa
  • detecção de padrão repetido: o histórico já vai no state, então o modelo julga o caso com o contexto do cliente junto

A lógica é parecida com a de moderar conteúdo enviado por usuários: fila grande, critério escrito, decisão tipada na entrada

Agora, onde a própria documentação orienta NÃO usar o Jev:

  • gerar qualquer conteúdo (ele não escreve o email de resposta pro cliente, ponto)
  • aritmética, contagem ou cálculo de datas
  • decisões que exigem justificativa escrita pra auditor
  • raciocínio complexo pontual
  • espaços de resposta genuinamente abertos

Essa terceira é a que mais pega gente desprevenida em reembolso

O Jev não explica o porquê da decisão

Ele devolve probabilidade, não redação

Se o seu processo exige um parecer escrito pra órgão regulador ou pra disputa de cartão, a decisão automática pode até entrar como triagem, mas a justificativa continua sendo trabalho de gente (ou de outro modelo, que aí é gerador de texto mesmo)

E se o seu caso tá numa zona cinzenta que a política não cobre, não force pergunta

Manda pra revisão

Decisão estruturada é boa justamente porque ela sabe dizer "não tenho confiança suficiente", e você trata isso no código

Próximo passo

A troca central aqui é essa: sai o parsing frágil de texto de LLM, entra decisão estruturada com probabilidade calibrada

Em vez de ficar escrevendo if em cima de string que o modelo resolveu escrever diferente hoje, tu lê um número entre 0 e 1 e aplica a sua regra de negócio em cima dele

O caminho concreto pra começar:

  1. cria a conta no console e pega os US$ 5 de crédito inicial
  2. escolhe uma amostra de pedidos de reembolso ANTIGOS, que já têm decisão humana registrada
  3. roda a mesma amostra pelo Jev e compara com o que o time decidiu na época
  4. só depois disso escolhe os limiares e liga a aprovação automática, começando pelas faixas de valor mais baixas

Calibrar com dado próprio antes de ligar o automático não é preciosismo, é o que separa a automação que economiza tempo da que gera chargeback

E se você não quer bater direto na API da TypeSafe, o Jev também está disponível no Cloudflare Workers AI e no Vercel AI Gateway, então dá pra encaixar no stack que tu já usa

Bora testar com os seus pedidos antigos e ver no que dá?

Até o próximo post!

Perguntas frequentes

O Jev consegue calcular o prazo de reembolso a partir da data da compra?

Não, e a documentação é explícita nisso: aritmética, contagem e cálculo de datas ficam fora do que o Jev deve fazer. O certo é o seu código calcular dias_desde_a_compra e mandar esse valor pronto dentro do state. O Jev entra depois, só pra julgar se aquele número se enquadra na política.

Dá pra usar o Jev pra aprovar reembolso sem nenhuma revisão humana?

Dá, mas a própria documentação sugere um desenho de três faixas em cima da probabilidade: agir automaticamente na confiança alta, marcar a faixa do meio pra revisão e escalar a faixa baixa pra uma pessoa. Essa escalada é lógica da sua aplicação sobre o número devolvido, não uma nova pergunta nem uma segunda chamada de API. Os limiares de cada faixa quem define é você, com dados rotulados próprios e olhando o custo do erro.

O Jev explica o porquê de ter aprovado ou negado um reembolso?

Não, o Jev não escreve texto de forma alguma. Ele não redige resposta pro cliente, não resume o chamado e não gera justificativa nenhuma para auditor. Se o seu processo de reembolso exige explicação escrita, essa parte precisa vir de outro lugar, não do Jev.

Quanto custa rodar reembolsos pelo Jev em volume?

O preço é US$ 0,042 por milhão de tokens de entrada, e os tokens de saída saem de graça. Como o state de um pedido de reembolso costuma ser pequeno (poucos campos de JSON), o custo por decisão tende a ficar bem baixo. Vale simular com o seu volume real de tickets antes de bater o martelo.

Preciso usar jev-latest ou é melhor fixar a versão no fluxo de reembolso?

O jev-latest é o padrão do cliente e hoje resolve pra jev-1.13.0, que é a única versão publicada. Mas se o fluxo de reembolso for crítico pra sua operação, fixar jev-1.13.0 direto evita que uma troca futura de versão mude o comportamento sem aviso. É basicamente trocar conveniência por previsibilidade.

O Jev serve pra decidir reembolso em qualquer valor, mesmo os mais caros?

Serve tecnicamente, mas o desenho de três faixas existe justamente pra separar risco. A ideia é exigir evidência mais forte, ou seja, probabilidade mais alta, pra ações de risco alto, como reembolsos de valor elevado. Pedidos baratos podem ter um limiar mais frouxo pra aprovação automática, e os caros sobem pra revisão com mais facilidade.



Escrito por | Matheus Battisti

Matheus Battisti
Fundador da Hora de Codar

Programador apaixonado pelo mundo das tecnologias, sempre buscando em aprender e se aprofundar em linguagens, frameworks e o que mais for necessário para executar um bom trabalho. Agora tem uma nova missão que é de passar seu conhecimento adiante para formar novos programadores e especializar mais os que já são.

Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Claude Code

Formação Claude Code

Domine Claude Code do absoluto zero até o avançado

  • 120 aulas
  • 4 projetos
  • 9h 48min

Blog | Mais populares