Como monitorar as decisões do Jev em produção sem virar caixa-preta?

Monitorar decisões do Jev em produção é diferente de logar resposta de modelo de texto: o retorno vem tipado, com distribuição de probabilidades. Grave sempre o campo model, os answers, o usage, a confiança (0 a 1), o campo probabilities e a faixa de roteamento que disparou a ação. Com isso você monta quatro gráficos: opções escolhidas por pergunta, histograma de confiança, proporção por faixa e volume por ID de modelo. E sai barato: a saída não é cobrada e a entrada custa US$ 0,042 por milhão de tokens
Decisão automatizada que ninguém consegue auditar depois não é automação, é aposta
Fala aí, beleza? O Jev é o primeiro modelo System One da TypeSafe AI, e ele não gera texto: recebe um estado e uma lista de perguntas tipadas, devolve respostas tipadas com probabilidades
Isso muda TUDO no que você precisa logar
Não tem mais "a resposta do modelo" pra colar num log e ler depois com calma
Tem uma opção escolhida, uma confiança entre 0 e 1, uma distribuição sobre as alternativas e um caminho que o seu código tomou por causa disso
E aqui vai o problema real: quando o comportamento muda, quem costuma te avisar é o usuário reclamando
Alias de modelo se move, entrada muda de formato, uma categoria nova aparece e não tem opção pra ela
Se o seu log guarda só o valor escolhido, você fica sabendo que a decisão mudou, mas não POR QUE mudou
O que você precisa antes de instrumentar:
Antes de sair plugando painel, o básico
- Acesso ao Jev: o acesso direto pela TypeSafe está em early access, com waitlist, e a empresa vai tirando gente da lista aos poucos. Quando a sua vez chega, as chaves de API ficam no console em
console.typesafe.ai. E se você ainda está na fila, calma: dá pra chegar no Jev pelas rotas alternativas logo abaixo, e todo o desenho de log deste post vale igual nos dois casos - O endpoint de avaliação: as chamadas vão em
POST https://api.typesafe.ai/v1/systemone, comAuthorization: Bearer <API_KEY>eContent-Type: application/json. O corpo levastate,modele um mapa nomeado dequestions - Ou uma rota alternativa: o Jev também está no Vercel AI Gateway (model ID
typesafe-ai/jev, pela API experimentalexperimental_evaluate, que exige AI SDK 7 ou superior), na Cloudflare via binding do Workers AI comenv.AI.run('typesafe/jev', {...})e no OpenRouter com o IDtypesafe/jev-1.13. Cada plataforma nomeia do seu jeito, e nenhum desses formatos é igual ao ID versionado que volta no campomodelda API direta (jev-1.13.0, que você vai ver mais pra frente): não confunda o que você MANDA com o que você LOGA - Atenção no OpenRouter: ele não aparece na lista padrão de modelos porque aquela lista cobre modelos que produzem texto. E não é pra chamar em
/api/v1/chat/completions, e sim na rota de decisões - Pra quem vai usar auto instrumentação: existe o pacote openinference-instrumentation-typesafe, que pede
typesafe-sdk >= 0.6.0
Uma nota de dimensionamento: o Jev 1.13 está listado com janela de contexto de 32.000 tokens
Se o seu state é um documento gordo, isso entra na conta antes de qualquer discussão sobre log 🙂
Formação Claude Code
Domine Claude Code do absoluto zero até o avançado
- 120 aulas
- 4 projetos
- 9h 45min
Como montar o log de decisões do Jev passo a passo:
A regra que eu seguiria é simples: o log tem que permitir reconstruir a decisão sem precisar chamar a API de novo
- Mapeie os campos que a resposta realmente entrega
A resposta traz três coisas que você vai querer pra sempre: o campo model (o ID versionado que de fato respondeu), os answers nomeados e um usage com input_tokens e output_tokens
Com a chave do console na mão, ou seja, depois que você saiu da waitlist, a chamada direta fica assim:
curl -X POST https://api.typesafe.ai/v1/systemone \
-H "Authorization: Bearer $TYPESAFE_API_KEY" \
-H "Content-Type: application/json" \
-d @payload.json
O payload.json é o seu state, o model e o mapa de questions
O que sai de lá é o que vira log
O erro comum deste passo: tratar o retorno como se fosse texto e serializar tudo num campo só de string. Aí ninguém agrega nada depois, porque agregação precisa de coluna, não de parágrafo
- Grave a confiança E a distribuição, não só a opção vencedora
Respostas de Choice e Score carregam uma confiança entre 0 e 1, derivada da distribuição de probabilidades da própria resposta. A Noul devolve um valor de 0 (não) a 1 (sim)
E toda resposta de Choice e Score inclui a propriedade probabilities, com a distribuição completa sobre as opções ou níveis (floats que somam 1)
Essa distribuição é o ouro do seu log
Distribuição concentrada significa resposta certa
Distribuição espalhada significa incerteza
É a diferença entre "ele escolheu A" e "ele escolheu A com 0,34 contra 0,31 de B", que é praticamente um cara ou coroa disfarçado de decisão
O erro comum deste passo: logar só a opção escolhida. Você perde justamente o sinal que antecipa a degradação, porque a opção vencedora pode continuar a mesma enquanto a distribuição vai achatando semana após semana
- Registre a faixa de confiança e a ação que o sistema tomou depois
A documentação recomenda dividir a confiança em três faixas com comportamentos diferentes: alta segue automático, média pede confirmação ou revisão, baixa vai pra humano, pede esclarecimento ou cai em outro sistema
Seu log precisa dizer em qual faixa aquela decisão caiu e o que aconteceu em seguida
Sem isso você tem a decisão do modelo, mas não tem a decisão do SISTEMA, que é a que o usuário sentiu
{
"request_id": "tkt-88213",
"question": "categoria_ticket",
"input_digest": "ticket:88213 len:412 lang:pt",
"model": "jev-1.13.0",
"choice": "faturamento",
"confidence": 0.91,
"probabilities": {"faturamento": 0.91, "tecnico": 0.05, "outro": 0.04},
"band": "alta",
"action": "auto_route",
"input_tokens": 613,
"output_tokens": 0
}
Repare no input_digest: um resumo curto da entrada (tamanho, idioma, tipo, um hash), não o conteúdo inteiro
Dá pra correlacionar mudança de comportamento com mudança de entrada sem transformar o log numa cópia da sua base
O erro comum deste passo: usar um limiar único pro sistema todo. A própria documentação afirma que o limiar não é um número único: ações diferentes dentro do mesmo sistema devem ser liberadas em níveis diferentes conforme a consequência do erro, e os limiares devem ser escolhidos com exemplos rotulados
- Logue o campo
modelem TODA resposta, sempre
Esse é o passo que mais gente pula e mais dói depois
Aliases como jev-latest se movem quando sai uma versão nova
Ou seja: as respostas podem mudar sem nenhuma alteração no seu código
A orientação é logar o campo model da resposta e, se os seus limiares foram ajustados numa versão específica, fixar o ID versionado, tipo jev-1.13.0
Quer saber o que a sua conta pode mandar no campo model? Tem o GET /v1/models, que lista os nomes com descrição e data de lançamento de cada um. IDs versionados são aceitos mesmo sem aparecer na lista
O erro comum deste passo: chamar com alias e gravar no log o alias que você mandou, em vez do model que voltou. Você acha que tem rastreabilidade, mas na prática todo o histórico diz "jev-latest" e não dá pra separar antes e depois da troca de versão
- Plugue a auto instrumentação e pare de reescrever log na mão
Quem está em Python tem o pacote openinference-instrumentation-typesafe
pip install openinference-instrumentation-typesafe
Ele aplica patch direto em TypeSafeClient.system_one e AsyncTypeSafeClient.system_one, sem wrapper de cliente, e traça as chamadas como spans LLM do OpenInference. No Langfuse os spans chegam por OpenTelemetry
No span gerado, o input.value guarda o corpo da requisição (state, model e questions) e o output.value guarda o corpo da resposta (model, answers e usage)
Vem junto llm.request.model_name, llm.response.model_name e as contagens llm.token_count.prompt, llm.token_count.completion e llm.token_count.total
A lógica é a mesma de monitorar o GPT-6 Astra em produção: trace pra investigar caso a caso, log estruturado pra agregar
O erro comum deste passo: achar que o trace substitui o log de negócio. O span te dá requisição e resposta, mas a faixa de roteamento e a ação tomada depois são decisão do SEU código, e só o seu código pode registrar
O painel mínimo: quais quatro gráficos revelam mudança de comportamento?
Não precisa de painel bonito
Precisa de quatro gráficos que quebram quando a realidade muda
- Distribuição das opções escolhidas, por pergunta, ao longo do tempo
Um gráfico de área por opção, quebrado pelo nome da pergunta
É o seu detector de mudança de mundo: quando uma categoria que era marginal vira maioria em dois dias, algo mudou na entrada, não no modelo
- Histograma de confiança
Empilhe a confiança em buckets e compare a semana atual com a anterior
Uma barra que era concentrada perto do topo e começa a inchar no meio é o aviso mais precoce que existe, porque a opção escolhida ainda nem mudou
- Proporção de decisões por faixa de roteamento
Alta, média e baixa, em percentual do volume
Esse é o gráfico que o time de suporte entende: se a faixa média pula, mais gente vai ser incomodada com confirmação, e a fila de revisão humana cresce antes de qualquer reclamação chegar
- Volume por ID de modelo
Uma série por valor do campo model
Dois IDs diferentes aparecendo no mesmo dia? O alias virou
Esse gráfico transforma "mudou do nada" em "mudou às 14h de terça, quando a versão trocou", que é exatamente o tipo de correlação que você já persegue quando vai monitorar performance de workflows n8n em produção
Quem está chamando via Vercel AI Gateway ganha um pedaço disso de graça no lado de custo e volume: as chamadas de avaliação do Jev aparecem nos logs e no custom reporting, contam pros budgets e aceitam as demais opções de provider em providerOptions.gateway
Sinais de que a decisão degradou (e o que cada um significa):
Sintoma: a confiança caiu em bloco, do dia pra noite
Causa provável: troca de versão por baixo do alias. Se você chama jev-latest, a resposta muda quando sai versão nova, sem você mexer em nada
Solução: abre o gráfico de volume por ID de modelo e confirma se tem dois valores no mesmo dia. Se tem, fixa o ID versionado (jev-1.13.0) e revalida os limiares antes de voltar pro alias
Como prevenir: nunca deixe o campo model da resposta fora do log, e trate mudança de versão como deploy, não como detalhe de infra
Sintoma: massa enorme numa opção genérica, ou nenhuma opção sobrando pro que é novo
Causa provável: a sua lista de Choice não cobre a entrada real. A documentação recomenda incluir uma opção de escape do tipo "outro" ou "nenhuma das anteriores" quando a lista pode não cobrir tudo, justamente pro modelo poder dizer que nenhuma opção serve
Solução: adiciona o escape e acompanha ele como métrica de primeira classe. Crescimento de "outro" é sinal de categoria faltando, não é lixo
Como prevenir: Choice aceita até 255 opções e Score precisa de 2 a 10 níveis, então espaço pra granularidade existe. O que não existe é adivinhação: sem escape, a resposta vai cair em alguma opção de qualquer jeito
Sintoma: pergunta binária SEMPRE respondida, mesmo em entrada claramente ambígua
Causa provável: o Jev não consegue se abster. O Langfuse aponta isso direto: num binário forçado, sem opção de desconhecido ou needs_review, ele escolhe a resposta menos errada em vez de dizer que não sabe
Solução: se a sua regra de negócio precisa de "não sei", isso tem que ser uma opção explícita na pergunta. Não é um comportamento que aparece sozinho
Como prevenir: toda pergunta em que a ambiguidade é possível nasce com a saída de abstenção desenhada junto com as outras opções
Sintoma: buracos no log e picos de latência
Causa provável: 429 Too Many Requests ou 529 Overloaded. Nesses casos a orientação é repetir com backoff exponencial, e os SDKs clientes já fazem isso na política padrão de retry. Chamando o endpoint HTTP na mão, o backoff é problema seu
Solução: instrumente a tentativa, não só o sucesso. Se você só loga resposta 200, o retry fica invisível e a latência aparece como mistério
Como prevenir: contador de erro por código e por pergunta no mesmo painel, ao lado do volume. Buraco no gráfico de decisões quase nunca é "ninguém usou", é "alguém falhou calado"
Onde esse log te salva na prática:
Moderação com rubrica: várias perguntas independentes sobre o mesmo estado podem ir numa única requisição, avaliadas em paralelo e isoladas umas das outras. O cookbook de autoconsistência da TypeSafe usa uma rubrica de 8 perguntas Choice pra ilustrar isso
Com log por pergunta, você descobre que a rubrica não degradou inteira: degradou UMA pergunta, que é um problema mil vezes mais fácil de resolver
Roteamento de tickets: aqui o valor do log é a faixa. Se a faixa média cresce, o custo não aparece na fatura da API, aparece na fila da equipe que revisa
Jev como avaliador de traces: o Langfuse documenta um fluxo pra pontuar traces com o Jev, puxando observações pela API, decidindo com o modelo e gravando o resultado de volta como score
Bonito porque fecha o ciclo: o log de produção alimenta a avaliação, e a avaliação volta como score no mesmo lugar onde você já olha
Checagem de estabilidade: no estilo do cookbook de autoconsistência, que roda a mesma rubrica 15 vezes sobre o mesmo post pra medir se o rótulo se mantém entre repetições
Vale guardar um punhado de entradas fixas e repetir o exercício de vez em quando
Se o rótulo começa a oscilar num caso que era estável, você tem evidência antes de ter reclamação 😀
Vídeo: automações que rodam sozinhas
Pra começar do zero com processos que rodam sem ninguém olhando, este vídeo do canal mostra prompts virando automações agendadas no Antigravity 2.0
Conclusão:
Observabilidade aqui é barata, e isso é raro
O Jev cobra por token de entrada, US$ 0,042 por milhão, e a saída sai por US$ 0,00 por milhão de tokens
O que você paga mesmo é o trabalho de desenhar o log uma vez: model, answers, usage, confiança, probabilities, faixa e ação tomada
Próximo passo é escolher os limiares POR AÇÃO, com exemplos rotulados, porque consequência de erro diferente pede liberação diferente
E antes de confiar demais em Score numérico, em datas ou em contagem, dá uma passada na página de limitações conhecidas do jev-1.13: ela lista calibração numérica fraca nos níveis de Score, datas lidas como texto e não como quantidades ordenadas, e contagem pouco confiável, com o erro crescendo conforme o tamanho do que se conta
Saber onde o modelo é esquisito é metade do painel…
Até o próximo post!
Perguntas frequentes
Como saber se o alias jev-latest mudou de versão sem eu perceber?
Só olhando o campo model que vem em toda resposta da API. Como o alias se move sozinho quando sai versão nova, o jeito de flagrar a mudança é logar esse campo em cada chamada e comparar ao longo do tempo. Se os seus limiares de confiança foram calibrados numa versão específica, o caminho é fixar o ID versionado, tipo jev-1.13.0, em vez de usar o alias.
Dá pra confiar só na opção escolhida pelo Jev sem olhar a distribuição de probabilidades?
Dá, mas você perde o sinal mais cedo de degradação. A opção vencedora pode continuar igual semana após semana enquanto o campo probabilities vai ficando mais espalhado, indicando que o modelo está cada vez mais em cima do muro. Distribuição concentrada é resposta certa, distribuição espalhada é incerteza, e isso não aparece se você loga só o choice.
Quantas vezes o Jev deveria responder a mesma pergunta pra eu confiar que o resultado é estável?
A TypeSafe publica um cookbook de autoconsistência que roda a mesma rubrica de moderação 15 vezes sobre o mesmo post pra medir se o rótulo se mantém entre repetições. A rubrica usada nesse cookbook tem 8 perguntas Choice. É um jeito de testar estabilidade antes de confiar num limiar de confiança em produção.
O que fazer quando a API do Jev retorna 429 ou 529?
A orientação da documentação da API é repetir a chamada com backoff exponencial, e os SDKs clientes já fazem isso na política padrão de retry. Se você fala direto com o endpoint HTTP, o backoff fica por sua conta, e vale instrumentar a tentativa e não só o sucesso, senão o retry some do log e a latência vira mistério.
O Jev consegue dizer que não sabe responder uma decisão incerta?
Não de forma nativa. O próprio Langfuse documenta que, num binário forçado sem opção de desconhecido ou needs_review, o Jev escolhe a resposta menos errada em vez de admitir incerteza. Pra ter esse comportamento você precisa incluir explicitamente uma opção tipo none ou outro na pergunta Choice.
Quanto custa manter o log de decisões do Jev rodando em produção?
O preço é só por token de entrada: US$ 0,042 por milhão de tokens, com a saída sem cobrança nenhuma. Isso ajuda a decidir o que entra no state, já que o Jev 1.13 tem janela de contexto de 32.000 tokens e cada campo extra no estado pesa na conta de entrada.
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 montar um workflow de automação combinando decisões do Jev em código
Aprenda a montar um workflow com Jev: decisões tipadas encadeadas em código, alta confiança agindo sozinha e casos incertos escalando para revisão.

Para quem o Jev serve (e para quem não serve)?
Jev serve pra roteamento, scoring e guardrails em IA, não pra texto ou código. Veja pra quem o Jev serve e quando evitar.

Jev decide, LLM escreve: como dividir os papéis dentro de um agente de IA
Jev é o modelo que decide, não escreve: entenda como dividir papéis entre Jev e LLM dentro de um agente de IA e quando usar cada um.
