Como usar o Jev para o agente escolher o próximo link a visitar na web?

Agente que navega sozinho na web vive inventando URL que não existe na página. A saída é trocar prompt por schema: usar o Jev escolher próximo link como uma pergunta Choice, onde a resposta é sempre uma das opções que você declarou, com probabilidade por opção e um valor de confiança de 0 a 1. Você monta o state (objetivo, página atual, histórico e os links candidatos), envia o mapa criteria e recebe a escolha tipada. Quando a página passa das 255 opções do Choice, a TypeSafe usa 2 estágios: pontuar com Score e fazer um Choice final entre as finalistas.
Agente que navega na web tem um vício clássico: ele inventa link que não existe na página
Você pede pro modelo escolher o próximo passo, ele devolve uma URL linda, plausível, bem formatada… e 404
O Jev ataca isso por outro ângulo. Ele é o modelo "System One" da TypeSafe AI: não gera texto livre, devolve valores tipados com probabilidades e confiança, feitos pra serem consumidos por software
Ou seja: se você declara 40 links como opções, a resposta é um desses 40, sempre
Neste post a gente monta exatamente isso, a escolha do próximo link como uma pergunta Choice, no espírito da demo oficial de Wikiracing que a TypeSafe mostrou no lançamento (sair de uma página da Wikipédia e chegar em outra usando só os links encontrados no caminho)
Bora ver na prática?
O que você precisa antes de começar
A lista é curtinha, beleza?
- Conta em
console.typesafe.ai: desde 20 de setembro de 2026 não tem mais lista de espera, e a conta nova vem com US$ 5 de crédito inicial (a TypeSafe estima isso em cerca de 120 milhões de tokens de entrada) - A chave exportada na variável de ambiente
TYPESAFE_API_KEY - O SDK de Python, com
pip install typesafe-sdkouuv add typesafe-sdk - Ou o SDK de JavaScript, com
npm install @typesafe-ai/sdk - Ou nada disso e chamada direta em
POST https://api.typesafe.ai/v1/systemone, se você quer controle total de retries e transporte
O cliente chama jev-latest por padrão, e a versão do modelo documentada hoje é a jev-1.13
E tem uma parte que não é do Jev: buscar a página e extrair a lista de links
Isso é código seu, do jeito que você já faz (requests + parser de HTML, Playwright, o que for)
O Jev não navega, não abre página, não faz fetch. Ele só decide
Se você já usou LLM pra isso, a analogia de aproximação é essa: em vez de mandar a página inteira e rezar pra vir um JSON válido, você manda um estado enxuto e recebe uma opção do conjunto que VOCÊ declarou
Curso de Jev: Sistemas Mais Inteligentes, Rápidos e Robustos
Desenvolva sistemas mais inteligentes, rápidos e robustos com Jev
Passo a passo: modelando a escolha do próximo link como um Choice
A API System One tem três primitivas, e vale ter elas na cabeça antes de escrever a primeira linha:
| Primitiva | O que ela responde | Limite documentado |
|---|---|---|
| Choice | escolhe uma opção de um conjunto definido | até 255 opções |
| Score | nota em níveis ordenados | de 2 a 10 níveis |
| Noul | probabilidade de sim, de 0 a 1 | resposta numérica |
Pra escolher link, a primitiva certa é o Choice
- Extraia os links candidatos e normalize em identificadores curtos e únicos
Nada de jogar URL crua como nome de opção. Gere um id seu (link_01, link_02) e guarde o mapa id para URL do lado do seu código
Assim a resposta do modelo já volta como chave de um dicionário que você controla, e o link final nunca passa pela "mão" do modelo
O erro comum deste passo: usar o texto do link como identificador e acabar com dois candidatos iguais na mesma página (muita Wikipédia tem link repetido), aí você não sabe qual foi escolhido
- Monte o state com objetivo, página atual, histórico e os candidatos
O state pode ser string simples ou dado estruturado (objeto ou array), tipo o estado atual da sua aplicação. Pra navegação, estruturado é muito melhor
from typesafe_sdk import Choice, TypeSafeClient
client = TypeSafeClient() # lê a chave de TYPESAFE_API_KEY
candidatos = {
"link_01": "Sete pontes de Königsberg",
"link_02": "Basileia",
"link_03": "Cálculo diferencial",
"link_04": "Topologia",
}
state = {
"objetivo": "chegar na página 'Teoria dos grafos'",
"pagina_atual": "Leonhard Euler",
"resumo_pagina": "Matemático suíço do século 18, trabalhos em análise, topologia e o problema das pontes de Königsberg",
"caminho_percorrido": ["Matemática", "Leonhard Euler"],
"links_candidatos": candidatos,
}
O erro comum deste passo: despejar o HTML inteiro no state. A página de jaggedness do jev-1.13 documenta "Large state with irrelevant detail" como modo de falha conhecido: a acurácia cai quando o state cresce com conteúdo que não importa pra decisão
Título do link + um resumo curto da página já entrega o recado
- Monte a pergunta Choice com instructions e criteria
No Choice, cada opção vive num mapa criteria, com uma descrição de rubrica por opção (ou null quando aquela opção não precisa de detalhe extra), além do campo instructions
criteria = {
"link_01": "Problema histórico que deu origem ao estudo de grafos",
"link_02": None,
"link_03": None,
"link_04": "Área próxima de grafos, pode ser um atalho razoável",
}
pergunta = Choice(
instructions=(
"Escolha o link que mais aproxima a navegação do objetivo. "
"Prefira links que levem a páginas com muitas conexões para o tema alvo. "
"Ignore links já visitados no caminho percorrido."
),
criteria=criteria,
)
O erro comum deste passo: criteria vazio ou com opção que não existe de verdade na página. O modelo vai responder uma das opções que você declarou, então uma opção fantasma vira link quebrado na hora de clicar
Gere o criteria a partir da MESMA estrutura que gerou os candidatos, nunca escrito na mão em paralelo
- Chame o endpoint
resultado = client.system_one(
state=state,
questions={"proximo_link": pergunta},
)
print(resultado)
Se você prefere bater direto na API, o corpo é state + model + o mapa de questions:
{
"state": {
"objetivo": "chegar na página 'Teoria dos grafos'",
"pagina_atual": "Leonhard Euler",
"links_candidatos": { "link_01": "Sete pontes de Königsberg" }
},
"model": "jev-latest",
"questions": {
"proximo_link": {
"type": "choice",
"instructions": "Escolha o link que mais aproxima a navegação do objetivo",
"criteria": {
"link_01": "Problema histórico que deu origem ao estudo de grafos",
"link_02": null
}
}
}
}
Curso RecomendadoDesenvolva sistemas mais inteligentes, rápidos e robustos com JevConhecer cursoO erro comum deste passo: mandar cada candidato como uma requisição separada. Não precisa, o mapa de questions existe justamente pra você fazer várias perguntas tipadas na mesma passada
- Leia a resposta inteira, não só a opção escolhida
Numa pergunta Choice o modelo devolve três coisas: a opção escolhida, uma probabilidade para cada opção e um valor de confiança entre 0 e 1
A opção escolhida você usa pra buscar a URL no seu mapa
A confiança é o seu gatilho de fallback: abaixo do corte, em vez de clicar, o agente volta atrás, tenta outra página ou pede uma lista nova de candidatos
E as probabilidades servem pra montar uma lista de backup, o segundo colocado vira plano B quando o primeiro dá 404 ou cai em loop
Qual corte usar? Isso é calibração sua, não existe número mágico na doc, e desconfie de quem te vender um =)
O erro comum deste passo: tratar a saída como se fosse determinística e ignorar a confiança completamente. Aí o agente segue com a mesma cara de certeza em um chute e num acerto
- Feche o loop
Aplica a escolha, faz o fetch da nova página, extrai os links de novo, empurra a página anterior pro caminho_percorrido e repete
O histórico no state é o que evita o agente ficar batendo ping pong entre duas páginas
O erro comum deste passo: deixar o caminho_percorrido crescer pra sempre. Em navegação longa, ele vira exatamente aquele "detalhe irrelevante" que derruba a acurácia: guarde os últimos passos, não a saga completa
Quando a página tem mais links do que o Choice aceita
Aqui mora o problema de verdade
Uma pergunta Choice aceita no máximo 255 opções
E, segundo o próprio post de lançamento, no Wikiracing cada passo pode significar escolher entre centenas a milhares de links
A conta não fecha, né? A TypeSafe resolve isso com um sistema de 2 estágios:
- Estágio 1: pontuar as opções de forma independente
Você quebra a lista gigante em lotes e usa Score pra dar uma nota a cada link, sem ele precisar comparar com a lista toda de uma vez
O Score aceita de 2 a 10 níveis, então dá pra fazer algo simples tipo "nada a ver / talvez / provável / quase certo"
Esse mesmo formato de pontuação em níveis é o que aparece quando você usa Score pra priorizar leads, a lógica é idêntica, só muda o que está sendo pontuado
- Estágio 2: um Choice explícito entre as finalistas
Pega os melhores pontuados, monta o criteria só com eles e faz a escolha final com Choice
Agora sim você cabe no limite, e a decisão final continua restrita a links que existem de verdade
- Respeite o orçamento de contexto ao lotear
O limite por requisição é de 64k tokens para o state mais todas as questions somadas, e 32k tokens para o state mais a pergunta mais longa
Tome cuidado! É fácil esquecer que o state é contado junto: se você manda um state gordo e 200 perguntas de Score no mesmo request, o teto chega bem antes do que você imagina
O erro comum deste passo: dimensionar o lote olhando só a quantidade de links, sem contar o peso do state que vai junto em cada requisição
Onde esse padrão se encaixa além do Wikiracing
Wikiracing é a demo bonitinha, mas a modelagem é a mesma em um monte de fluxo real:
- Crawler decidindo qual resultado de busca abrir: os 10 resultados viram 10 opções, o objetivo vai no state
- Agente de pesquisa escolhendo a próxima fonte: mesma coisa, com o histórico de fontes já lidas no state pra não repetir
- Navegação em documentação: o sumário é a lista de opções, e a pergunta é "qual seção responde a dúvida do usuário?"
- Fila de crawling: em vez de escolher um link por vez, você pontua a fila inteira com Score e reordena
E dá pra combinar com o cookbook oficial de function calling, que modela chamada de ferramenta como pergunta de conjunto fechado: um Choice seleciona a função, com uma opção explícita none para comandos não suportados, e um Choice por argumento feito especulativamente na mesma requisição
Traduzindo pra navegação: a opção none é o seu "nenhum link serve aqui"
Sem ela, o modelo é obrigado a escolher algum link, mesmo quando a página inteira é um beco sem saída. Isso é um detalhe pequeno que muda o comportamento do loop inteiro

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.E pra saber a hora de parar, o Noul cai como uma luva: ele pede a probabilidade de a resposta ser sim, numa escala de 0 (não) a 1 (sim)
"Já chegamos no destino?" é pergunta de Noul, não de Choice
O legal é que ela cabe no MESMO request da escolha do link, já que questions é um mapa
Problemas comuns na navegação autônoma com Jev (e como prevenir)
A TypeSafe mantém uma página de "jaggedness" pro jev-1.13, revisada em 17/09/2026, listando os modos de falha conhecidos
É leitura obrigatória antes de colocar isso em produção, e resolve boa parte dos sintomas abaixo
Sintoma: o agente escolhe bem na primeira página e piora conforme navega
Causa provável: state grande com detalhe irrelevante, o famoso "Large state with irrelevant detail" da página de jaggedness. Cada hop você foi empilhando mais texto, mais histórico, mais contexto
Solução: mande só o essencial. Títulos dos links, um resumo curto da página atual, o objetivo e os últimos passos do caminho. O resto fica no seu código, não no request
Sintoma: a instrução parece clara, mas o modelo responde fora do espírito dela
Causa provável: leitura literal das instruções, também documentada como modo de falha
Solução: escreva instructions com critério explícito em vez de intenção implícita. "Prefira links de páginas-índice e desambiguação" funciona melhor que "escolha o melhor link"
Sintoma: o agente erra ao ordenar artigos por data ou contar ocorrências
Causa provável: a página de jaggedness lista fraqueza em matemática e contagem, e comparação de datas, já que o modelo lê datas como texto e não como quantidades ordenadas
Solução: não terceirize isso. Ordenação por data, contagem e cálculo são trabalho do seu código, que já entrega a lista pronta pro Jev só decidir
Sintoma: a página visitada convence o agente a fazer o que ela quer
Esse é o mais sério, e vale parar aqui
Causa provável: conteúdo adversarial. A doc é honesta: o jev-1.13 trata o state como dado, e não como hostil por padrão. Conteúdo escrito pra direcionar o modelo pode influenciar o resultado
A VentureBeat relatou uma demonstração bem ilustrativa: ao avaliar se bloqueava um rm -rf ~/.ssh, o Jev deu probabilidade de bloqueio 0,76 com confiança 0,64
Depois que um engenheiro inseriu um campo falso de saída de ferramenta dizendo que o usuário havia pré-aprovado o comando, a probabilidade caiu para 0,48 e a confiança para 0,22
Ou seja: o texto que o agente buscou acabou pesando na decisão sobre o próprio agente
Na navegação web isso é literalmente o cenário padrão, você está lendo página de terceiro o tempo todo
Solução: limite o que o Jev vê, no espírito do middleware que a LangChain publicou. Lá, o Jev decide se as tool calls do agente rodam, e a saída de ferramenta fica explicitamente fora da entrada do classificador, justamente pra que o conteúdo buscado pelo agente não autorize a própria execução
Transportando pro nosso loop: a decisão de segurança ("posso seguir esse domínio?", "posso executar isso?") não pode compartilhar o mesmo state da decisão de navegação
São duas perguntas diferentes, com entradas diferentes
E se a sua entrada é texto que qualquer um escreve, a mesma cautela de moderar conteúdo enviado por usuários se aplica aqui: o que entra no state é dado, não ordem
Extrair só o texto âncora dos links, jogar fora scripts, comentários HTML e blocos escondidos já corta um bocado da superfície
Próximo passo
A ideia central do post é uma só: schema no lugar de prompt
Quando a escolha do próximo link é um Choice com as opções declaradas por você, o link inventado simplesmente deixa de ser um resultado possível. O modelo não tem como devolver uma URL que não está no conjunto
E o custo ajuda a rodar isso em loop: US$ 0,042 por milhão de tokens de entrada, com saída gratuita, e latência de ponta a ponta informada pela TypeSafe entre 70 e 500 ms por chamada
A própria empresa fala em até 193,6 vezes mais velocidade e 444,6 vezes menos custo que alternativas baseadas em LLM em fluxos System One, e trata esses números como o teto do que esperar na prática, então trate como número de fornecedor mesmo, beleza?
Meu conselho de movimento: cria a conta, usa o crédito inicial e roda um loop pequeno, de duas páginas só, com 10 links candidatos
Você sente o comportamento da confiança bem rápido, e aí sim cresce pro esquema de 2 estágios
Se você vive dentro do Claude Code, a TypeSafe mantém uma agent skill oficial no repositório typesafe-ai/skills. A instalação é via marketplace de plugins:
claude plugin marketplace add typesafe-ai/skills
claude plugin install typesafe@typesafe-ai
Depois é só invocar com /typesafe:typesafe-ai
Em outros agentes, o caminho é o npx skills:
npx skills add typesafe-ai/skills --skill typesafe-ai
E se a sua stack é edge, o Jev também é servido por terceiros, com página de modelo própria na Cloudflare Workers AI como typesafe/jev
Agora é montar o loop e ver o agente parar de chutar URL 😀
Até o próximo post!
Perguntas frequentes
E se a página tiver mais de 255 links candidatos, o Choice ainda funciona?
Não direto, porque uma pergunta Choice aceita no máximo 255 opções. Pra cardinalidade maior, a TypeSafe usa um sistema de 2 estágios: primeiro pontua as opções de forma independente (Score), depois faz uma escolha explícita (Choice) só com as melhores. Numa página densa da Wikipédia, com centenas a milhares de links, esse é o caminho recomendado.
O Jev consegue abrir a página e seguir o link sozinho?
Não. O Jev só decide: ele recebe o state com os candidatos e devolve qual opção escolher, com probabilidade por opção e confiança. Buscar a página, extrair os links e navegar até a URL escolhida é código seu, fora do Jev.
Quanto custa rodar isso em muitos passos de navegação?
Sai barato pro tipo de loop que a gente montou aqui, porque a cobrança é só sobre os tokens de entrada e a saída é gratuita. A conta nova em console.typesafe.ai vem com US$ 5 de crédito, que a TypeSafe estima em cerca de 120 milhões de tokens de entrada, o que dá muito passo de navegação antes de gastar o crédito inicial.
Posso jogar o HTML inteiro da página no state pra dar mais contexto ao Jev?
Não é uma boa ideia. A página de jaggedness do jev-1.13 documenta ‘Large state with irrelevant detail’ como modo de falha conhecido: a acurácia cai quando o state cresce com conteúdo que não importa pra decisão. Título do link mais um resumo curto da página já é suficiente, e ainda deixa a requisição bem mais leve.
É seguro deixar o Jev decidir o link com base no texto que ele mesmo encontrou na página?
Exige cuidado, porque a página de jaggedness do jev-1.13 registra que o state não é tratado como hostil por padrão: conteúdo escrito de forma adversarial pode influenciar o resultado. A defesa prática é limitar o que entra no state: extraia só o texto âncora dos links, jogue fora scripts, comentários HTML e blocos escondidos, e nunca misture a decisão de navegação com a decisão de segurança no mesmo state.
Dá pra usar isso fora do Claude Code, em outro agente de navegação?
Dá sim, o padrão não depende de agente nenhum. A API System One é uma chamada HTTP só: você usa o SDK de Python, o SDK de JavaScript ou bate direto em POST https://api.typesafe.ai/v1/systemone. O que muda é quem faz o fetch da página e extrai os links, e isso continua sendo código seu.
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.
