Como usar o Jev para decidir quando o agente deve parar de iterar?

O Jev é o primeiro System One Model da TypeSafe AI, anunciado em 15/09/2026: ele não gera texto, recebe um estado e devolve decisões tipadas com probabilidade. Pra controle de loop isso muda tudo: em vez de pedir pro próprio LLM julgar se "já terminou?" e depois parsear a string, você declara as saídas válidas no schema e recebe um Noul (probabilidade de 0 a 1), um Choice ou um Score. A cada iteração você monta o state, faz as perguntas numa única chamada e usa a probabilidade como condição de saída do loop.
Agente que itera pra sempre e agente que para cedo demais têm a mesma causa raiz: quem responde "já terminou?" é o mesmo LLM que acabou de escrever a resposta
E ele quase sempre acha que fez um ótimo trabalho, né? 😅
A TypeSafe AI anunciou em 15/09/2026 o Jev, o primeiro System One Model deles: uma classe de modelo feita pra tomar decisão rápida e estruturada que o software consome direto. Ele não é autorregressivo, não prevê o próximo token e não te devolve uma stringzinha simpática
Tu manda um estado, ele devolve decisão tipada com probabilidade
É exatamente a peça que faltava pra tirar o "parar ou continuar" das mãos de quem tem conflito de interesse
Por que deixar o LLM julgar o próprio "já terminou?" falha
O desenho clássico é esse: o agente executa, produz um resultado, e aí você manda de volta pro mesmo modelo uma pergunta tipo "a tarefa está completa? responda SIM ou NÃO"
Dois problemas nascem juntos aí
O primeiro é o conflito: o gerador é o avaliador. O segundo é mecânico e dói mais no dia a dia: a saída é texto livre. Hoje vem SIM, amanhã vem Sim, a tarefa parece estar completa, embora... e o teu if quebra
E aí entra o gambiarrão de sempre: regex, .lower().startswith("sim"), retry quando não parseia, um JSON mode que às vezes volta com campo a mais
O Jev resolve isso por construção: as saídas válidas são declaradas no schema antes da chamada. Ele só responde dentro desse espaço declarado, sempre com probabilidade associada
Curso de Jev: Sistemas Mais Inteligentes, Rápidos e Robustos
Desenvolva sistemas mais inteligentes, rápidos e robustos com Jev
Não tem resposta fora do espaço definido, não tem erro de tipo
Que "espaço definido"? É você quem escreve: se a pergunta é sim/não, o retorno é uma probabilidade entre 0 e 1. Se é escolha, o retorno é uma das opções da tua lista. Não existe terceira via inventada no meio do caminho
E não é ideia de maluco isolado: a LangChain publicou o material Building a harness with Jev descrevendo nós de decisão dentro do loop do agente, como roteamento de modelo e gate de tool call avaliado antes da execução
Ou seja: o padrão de "decisão de controle sai do LLM e vira chamada tipada" já tá documentado por terceiro, não é só o fornecedor falando bem de si mesmo
O que você precisa antes de começar
Lista curta, beleza?
- Conta e chave de API criadas no console da TypeSafe (
console.typesafe.ai) - A chave exportada na variável de ambiente
TYPESAFE_API_KEY - SDK oficial, se você for usar:
npm install @typesafe-ai/sdkoupip install typesafe_sdk. Os dois leem aTYPESAFE_API_KEYe usamjev-latestpor padrão - Um agente com loop já existente, porque o Jev não substitui o LLM que executa a tarefa
Esse último ponto é o que mais confunde gente chegando agora: o Jev não escreve teu código, não redige teu email, não chama tua tool. Ele decide
Sobre acesso: não tem mais waitlist, a TypeSafe abriu pra todo mundo. Conta nova recebe US$ 5,00 de crédito inicial (algo em torno de 120 milhões de tokens)
O preço é US$ 0,042 por milhão de tokens de entrada, e os tokens de saída são gratuitos
Sim, tu consegue prototipar um gate de loop inteiro dentro do crédito de boas-vindas 🙂
export TYPESAFE_API_KEY="sua_chave_aqui"
Tome cuidado: chave em variável de ambiente, não hardcoded no arquivo que você vai commitar. Já viu esse filme antes
Passo a passo: transformando o "parar ou continuar" em decisão tipada
1. Desenhe o state da iteração:
O campo state aceita string, objeto JSON, array ou null. Use isso a teu favor e mande estado estruturado, não prosa
O que costuma entrar: o objetivo original, a última ação executada, o resultado da tool, quantas tentativas já rolaram e o que ainda está pendente
{
"objetivo": "Corrigir o teste que falha em auth/login_spec.ts",
"tentativas": 3,
"ultima_acao": "run_tests",
"resultado_ultima_acao": "1 failing: expected 200, got 401",
"arquivos_alterados": ["src/auth/session.ts"],
"pendencias": ["teste ainda falhando"]
}
O erro comum deste passo: jogar o histórico bruto da conversa inteira dentro do state
Funciona? Provavelmente. Mas você acabou de transformar uma decisão barata numa chamada gorda, e enterrou o sinal relevante (tentativas, resultado da última ação) embaixo de dez mil tokens de "claro! vou analisar isso pra você"
Estado é estado. Transcrição é transcrição
2. Escolha o tipo de pergunta certo:
O Jev aceita exatamente três tipos, e é aqui que a maioria erra o desenho
| Tipo | O que você pergunta | O que volta |
|---|---|---|
Choice |
Uma opção entre até 255 alternativas | A opção de maior probabilidade + a probabilidade de cada uma (somam 1) + confiança |
Score |
Uma rubrica ordenada de 2 a 10 níveis | Um valor fracionário no espectro + a distribuição completa + confiança |
Noul |
Uma afirmação sim/não | Probabilidade de 0 (não) a 1 (sim) |
Noul é o nome que a TypeSafe dá pra pergunta sim/não, e é o tipo natural pro "já terminou?"
O erro comum deste passo: usar Choice com as opções ["parar", "continuar"] quando a pergunta é binária. Dá certo, mas você joga fora a graduação: com Noul você recebe o quanto o modelo acha que terminou, não só o lado vencedor
3. Monte a requisição:
O endpoint do Jev é próprio, não é /chat/completions. É POST https://api.typesafe.ai/v1/systemone
Curso RecomendadoDesenvolva sistemas mais inteligentes, rápidos e robustos com JevConhecer cursoO corpo exige três campos: model, state e questions. O questions é um mapa do nome da pergunta pra um objeto com type e instructions
curl -X POST https://api.typesafe.ai/v1/systemone \
-H "Authorization: Bearer $TYPESAFE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "jev-latest",
"state": {
"objetivo": "Corrigir o teste que falha em auth/login_spec.ts",
"tentativas": 3,
"ultima_acao": "run_tests",
"resultado_ultima_acao": "1 failing: expected 200, got 401",
"pendencias": ["teste ainda falhando"]
},
"questions": {
"esta_completo": {
"type": "Noul",
"instructions": "O objetivo foi totalmente atingido e não há pendência aberta no estado?"
}
}
}'
A resposta traz model, answers e usage
O erro comum deste passo: escrever instructions vago tipo "está bom?". Afirmação vaga gera distribuição espalhada, e distribuição espalhada é confiança baixa. Escreva a afirmação como uma frase que dá pra julgar olhando só o state
4. Faça várias perguntas de uma vez só:
As perguntas são avaliadas numa única ida e volta. Então não faz sentido chamar três vezes pra saber completude, qualidade e próxima ação
{
"model": "jev-latest",
"state": { "...": "..." },
"questions": {
"esta_completo": {
"type": "Noul",
"instructions": "O objetivo foi totalmente atingido e não há pendência aberta?"
},
"qualidade": {
"type": "Score",
"instructions": "Qualidade do resultado atual: 1 inutilizável, 5 pronto pra entregar"
},
"proxima_acao": {
"type": "Choice",
"instructions": "Qual a próxima ação mais útil dado o estado?",
"options": ["rodar_testes", "editar_codigo", "ler_arquivo", "encerrar"]
}
}
}
O erro comum deste passo: adicionar uma pergunta pedindo pro Jev "explicar por que decidiu isso"
Ele não gera texto. Ponto. Se você precisa de justificativa legível pra humano, isso é trabalho de outro modelo, ou do teu log mostrando o state que entrou e a distribuição que saiu
5. Ligue a resposta ao controle do loop:
Agora a parte que importa: a condição de saída deixa de ser um parse de string e vira comparação numérica
const TYPESAFE_URL = "https://api.typesafe.ai/v1/systemone"
// valores arbitrários deste projeto: calibre com os seus próprios dados,
// não existe limiar oficial recomendado pela TypeSafe
const PARAR_ACIMA_DE = 0.9
const DESISTIR_ABAIXO_DE = 0.2
const MAX_ITERACOES = 12
async function decidir(state) {
const res = await fetch(TYPESAFE_URL, {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.TYPESAFE_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "jev-latest",
state,
questions: {
esta_completo: {
type: "Noul",
instructions: "O objetivo foi totalmente atingido e não há pendência aberta?"
}
}
})
})
return res.json()
}
async function rodarAgente(objetivo) {
let state = { objetivo, tentativas: 0, pendencias: ["concluir o objetivo"] }
for (let i = 0; i < MAX_ITERACOES; i++) {
state = await executarUmaIteracao(state) // aqui roda o teu LLM de sempre
const { answers, usage } = await decidir(state)
const p = answers.esta_completo
console.log({ iteracao: i, completude: p, usage })
if (p >= PARAR_ACIMA_DE) return { status: "concluido", state }
if (p <= DESISTIR_ABAIXO_DE && state.tentativas >= 3) {
return { status: "escalar_humano", state }
}
}
return { status: "limite_de_iteracoes", state }
}
O erro comum deste passo: remover o MAX_ITERACOES porque "agora o Jev decide". Não. O gate é semântico, o contador é mecânico, e os dois protegem coisas diferentes
6. Pine a versão do modelo quando precisar de estabilidade:
jev-latest é ótimo pra prototipar e péssimo pra reprodutibilidade, porque o que está por trás dele pode mudar
O jev-latest já foi observado resolvendo para jev-1.13.0, e o identificador typesafe/jev-1.13 aparece listado em provedores
{ "model": "jev-1.13.0" }
O erro comum deste passo: pinar e esquecer. Se tu pinou, anota no README por que pinou e quando revisar, senão daqui a seis meses ninguém lembra
Usando o score de confiança como trava de segurança
Aqui mora a parte mais bonita do desenho, e a mais ignorada

Crie sistemas com IA para vender
Prompts, modelos e checklists para criar e publicar seu sistema com IA e preparar a oferta para o primeiro cliente.
Quero o e-book gratuito Receba o livro e os bônus no seu e-mail.Respostas de Choice e Score carregam um campo de confiança separado, de 0 a 1, derivado do formato da distribuição de probabilidades
Probabilidade concentrada numa opção significa confiança alta. Distribuição espalhada entre as opções significa confiança baixa
A regra prática que a própria documentação resume é linda de simples: a resposta diz o quê, a confiança diz se você deve agir
1. Separe três faixas de tratamento:
- Confiança alta e decisão "completo": para o loop e entrega
- Confiança alta e decisão "incompleto": continua iterando, com a próxima ação que o
Choiceapontou - Confiança baixa: não é pra parar nem pra insistir cegamente. É pra escalar, seja pra um humano, seja pra um modelo maior fazer uma passada de revisão
Distribuição espalhada quase sempre quer dizer que o state que você mandou não tem informação suficiente pra decidir. O modelo tá te avisando que a pergunta tá mal servida, não que a tarefa tá mais ou menos
Essa faixa do meio é a mesma discussão de autonomia do agente no Claude Code: o ponto não é dar autonomia total nem zero, é ter um sinal confiável pra saber em qual dos dois modos você está agora
2. Trate o Noul diferente:
Noul não tem campo de confiança separado. A própria probabilidade é o sinal que a aplicação usa
Ou seja: ali você não tem uma trava, você tem duas fronteiras
Perto de 1 é sim com força. Perto de 0 é não com força. E a região do meio, aquele território morno onde o modelo não se compromete, é justamente o teu gatilho de escalação
function faixaNoul(p) {
if (p >= PARAR_ACIMA_DE) return "parar"
if (p <= DESISTIR_ABAIXO_DE) return "continuar_iterando"
return "escalar" // zona morna: ninguém decide por palpite
}
3. Entenda por que dá pra confiar nesse número:
O Jev é treinado com um método de calibração próprio da TypeSafe, o RLCD (Reinforcement Learning for Calibrated Decisions)
A propriedade buscada é essa: grupos de previsões com probabilidade mais alta devem acertar com mais frequência que grupos de probabilidade mais baixa
Parece óbvio, mas não é o comportamento padrão de um LLM cuspindo "tenho certeza absoluta" no meio de um parágrafo. Ali o número é texto. Aqui ele é a saída do modelo
Importante ser honesto: não existe limiar oficial recomendado pela TypeSafe do tipo "abaixo de tanto, continue". Os valores de corte são decisão sua, e a forma certa de achar é logar as probabilidades junto com o desfecho real de cada rodada e olhar os dados depois
Outras decisões de loop que valem tirar do LLM
Uma vez que o padrão entra na cabeça, você começa a ver decisão tipada em todo canto do harness
- Gate de tool call: antes de executar a ferramenta, uma pergunta avalia se aquela chamada faz sentido no estado atual. A LangChain descreve exatamente esse nó avaliado antes da execução.
Noulresolve, e é o seu escudo contra osrm -rfda vida - Roteamento de modelo:
Choiceentre o modelo rápido e o modelo caro, decidido pela dificuldade que aparece nostate, não por umifcom contagem de caracteres do prompt - Próxima ação:
Choicedentro de um conjunto fechado de ferramentas. Como as opções são declaradas no schema, é impossível o agente inventar uma tool que não existe - Qualidade do rascunho antes de entregar:
Scorecom rubrica ordenada, de 2 a 10 níveis. Muito melhor que "o texto está bom? sim/não" - Detecção de loop improdutivo:
Noulperguntando se o agente está repetindo a mesma tentativa com o mesmo resultado. É o gate que salva você da conta de API surpresa no domingo de manhã 😅
Se você quer ver o modelo aplicado fora do contexto de agente, os casos de uso do Jev dentro do software seguem exatamente a mesma lógica: decisão que o código consome direto, sem parse no meio
Custo e latência: por que essa camada extra compensa
O argumento contra é previsível: "você adicionou mais uma chamada de modelo por iteração"
Verdade. Então vamos olhar os dois eixos
No custo, o preço é US$ 0,042 por milhão de tokens de entrada e os tokens de saída são gratuitos. Como o state estruturado que você manda é pequeno (lembra do passo 1?), o gate custa uma fração do que custa a própria iteração do agente
Na velocidade, a TypeSafe afirma que o Jev é de 40x a 200x mais rápido que LLMs de fronteira em tarefas System One
E aqui eu preciso ser chato: isso é claim do fornecedor, não benchmark independente. Não vou vender esse número como verdade medida por terceiro, porque não é
A boa notícia é que você não depende de acreditar: a resposta traz o campo usage. Loga ele a cada gate, soma no fim do dia e compara com o custo das iterações que o gate evitou
Um agente que parava na iteração 12 por timeout e agora para na 4 porque alguém perguntou direito "já terminou?" se paga sozinho
Conclusão
A ideia central cabe em uma frase: quem decide parar não deve ser quem escreveu a resposta
O Jev encaixa exatamente aí, porque ele não compete com o teu LLM executor. Ele ocupa o espaço que hoje é preenchido por regex, retry e torcida
Próximo passo concreto, sem firula: cria a chave no console, exporta a TYPESAFE_API_KEY e coloca um único Noul de completude no loop que mais te dá dor de cabeça hoje
Roda uma semana logando probabilidade e desfecho
Só depois disso você adiciona o Score de qualidade e o Choice de próxima ação, já com número na mão pra calibrar as faixas em vez de chutar
Começa pequeno, mede, expande
Até o próximo post! 🙂
Perguntas frequentes
Quanto custa usar o Jev pra decidir quando um agente deve parar de iterar?
O Jev cobra US$ 0,042 por milhão de tokens de entrada, e os tokens de saída são gratuitos. Conta nova ganha US$ 5,00 de crédito inicial, o que dá pra rodar bastante gate de decisão antes de gastar nada do bolso.
Qual a diferença entre Noul e Score pra saber se o agente já terminou?
Noul é a pergunta sim/não: devolve só uma probabilidade de 0 a 1, sem campo separado de confiança, porque a própria probabilidade já carrega esse sinal. Score é pra quando ‘terminou’ não é binário: retorna um valor fracionário numa rubrica de 2 a 10 níveis, mais a distribuição completa e um campo de confiança à parte.
Ainda existe lista de espera pra acessar o Jev?
Não. A TypeSafe removeu a waitlist e anunciou que o Jev está disponível pra qualquer pessoa, sem espera. O blog de lançamento de 15/09/2026 ainda menciona ‘early access’, mas esse trecho ficou desatualizado.
O Jev substitui o LLM que executa as tarefas do meu agente?
Não. O Jev só decide, ele não gera texto nem chama tool. Você precisa de um loop de agente já existente, com o LLM de execução separado, e usa o Jev como a camada que julga se continua ou para.
Dá pra fixar uma versão específica do Jev em vez de usar jev-latest?
Dá sim. O identificador jev-latest resolvia para jev-1.13.0 no momento deste post, e o id typesafe/jev-1.13 aparece listado em provedores pra quem quer pinar a versão manualmente.
O endpoint do Jev funciona igual ao /chat/completions de outros LLMs?
Não, o Jev tem endpoint próprio: POST https://api.typesafe.ai/v1/systemone. O corpo da requisição pede model, state e questions, e a resposta vem com model, answers e usage, num formato bem diferente do padrão de chat.
Formações
Formação Claude Code
Domine Claude Code do absoluto zero até o avançado
- 120 aulas
- 4 projetos
- 9h 48min
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.

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.

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.
