Como usar o Jev para decidir se um pull request pode seguir sozinho no pipeline?

fluxo do Jev avaliando um pull request no pipeline de CI
Resposta rápida

O Jev é o primeiro System One Model da TypeSafe AI, anunciado em 15/09/2026, e ele não gera texto: avalia um state e devolve valor tipado, probabilidades e confidence. No CI isso vira um if-statement inteligente: você monta o contexto do pull request (título, paths, contagem de linhas e diff), pergunta o risco com choice, score ou noul, e ramifica entre merge automático, revisão humana ou bloqueio usando confidence-gated routing. A TypeSafe documenta três faixas de confiança e recomenda limiar por ação, calibrado com seus próprios dados. O caminho seguro é começar consultivo e registrar tudo em JSON pra auditar depois.

Todo pipeline de CI vive o mesmo dilema chato: ou tudo espera revisão humana e a fila trava, ou tudo passa e uma hora alguém quebra produção na sexta às 18h

A ideia aqui é outra: colocar um if-statement inteligente no meio do caminho, que olha o pull request e classifica o risco antes de decidir o que fazer com ele

É exatamente esse o papel do Jev, o primeiro System One Model da TypeSafe AI, apresentado no blog oficial em 15 de setembro de 2026

E tem um detalhe que muda tudo: ele não gera texto

O Jev recebe um state, responde uma pergunta tipada e devolve valor estruturado mais distribuição de probabilidade, pro teu código ramificar em cima disso

Se o que tu quer é um modelo generativo pra escrever código do zero, o assunto é outro e já falamos de quem tem acesso ao GPT-6 Astra por aqui

Então bora montar isso pelo caminho seguro: do primeiro POST autenticado até o gate que decide merge, revisão ou bloqueio, beleza? 🙂

O que você precisa antes de começar

A boa notícia é que a barreira caiu: não existe mais lista de espera

O cadastro é feito em console.typesafe.ai e vem com US$ 5 de crédito gratuito pra brincar

Checklist do que tu precisa ter na mão:

  • API key da TypeSafe, que vai no header Authorization: Bearer <sua key>
  • Endpoint System One: POST https://api.typesafe.ai/v1/systemone
  • Modelo: jev-1.13 (IDs versionados como jev-1.13.0 também são aceitos no campo model)
  • Um workflow de CI que consiga montar o contexto do PR (título, arquivos alterados e diff)

Sobre custo, o modelo é cobrado só na entrada: US$ 0,042 por milhão de tokens de entrada, e os tokens de saída são gratuitos

Faz sentido quando tu lembra que a saída é um valor tipado e umas probabilidades, não um textão

Curso de Jev: Sistemas Mais Inteligentes, Rápidos e Robustos
Curso Recomendado

Curso de Jev: Sistemas Mais Inteligentes, Rápidos e Robustos

Desenvolva sistemas mais inteligentes, rápidos e robustos com Jev

Opcional: a agent skill no Claude Code

A TypeSafe publica uma agent skill que entrega o contexto da API pro teu agente de código, o que ajuda demais na hora de escrever o client

No Claude Code, a instalação é via plugin:

claude plugin marketplace add typesafe-ai/skills
claude plugin install typesafe@typesafe-ai

Depois é só invocar com /typesafe:typesafe-ai

A instalação é local ao projeto por padrão, então se tu quer ela disponível em tudo, usa a flag -g

E já que o agente vai encostar em pull request, vale decidir antes se tu prefere o gh CLI ou o GitHub MCP pra essa parte

Passo a passo: do diff do PR até a decisão no pipeline

A lógica é simples de enxergar: monta contexto, faz a pergunta certa, lê a resposta tipada, ramifica

Bora ver na prática?

  1. Monte o state do PR

O campo state aceita string, objeto, array ou null, então tu tem liberdade de formato

Um bom ponto de partida é copiar o que a GitHub Action de risco da Sentry faz: ela monta o state com título e descrição do PR, caminhos e status dos arquivos, contagem de linhas e o diff completo

state = {
    "title": pr["title"],
    "description": pr["body"],
    "files": [
        {"path": f["filename"], "status": f["status"],
         "additions": f["additions"], "deletions": f["deletions"]}
        for f in files
    ],
    "diff": full_diff,
}

O erro comum deste passo: mandar só o diff, sem os paths

Um PR que toca docs/ e um que toca o módulo de pagamento podem ter diff parecido em tamanho, e o caminho do arquivo é justamente o sinal que separa os dois

  1. Escolha a primitive certa

São três tipos de pergunta, cada uma com os campos type e instructions mais seus próprios criteria

Primitive Pra que serve O que volta na resposta
choice Escolher uma opção de uma lista que você define choice, probabilities (somam 1) e confidence
score Posicionar em um nível de uma escala ordenada score (pode cair entre níveis), probabilidade por nível e confidence
noul Responder uma afirmação verdadeiro/falso noul, de 0 (não) a 1 (sim)

Pra rotular risco em categorias, choice resolve

Pra nível ordenado de gravidade, score

E pra uma pergunta seca do tipo "este PR mexe em caminho de autenticação?", noul

  1. Escreva os criteria descrevendo situações, não graus

Esse é o passo que separa um gate útil de um gate aleatório

A documentação do Score é explícita: os níveis vão em um array ordenado, do extremo baixo pro alto, e devem descrever situações concretas em vez de graus abstratos

Tipo assim, no estilo do exemplo da própria doc: "feature quebrada ou degradada, mas existe workaround"

{
  "type": "score",
  "instructions": "Avalie o risco de regressao em producao deste pull request",
  "criteria": [
    "Mudanca apenas em documentacao, comentarios ou arquivos de teste, sem efeito em runtime",
    "Mudanca isolada em uma funcao com testes cobrindo o caminho alterado",
    "Mudanca em modulo compartilhado, com efeito possivel em outras features",
    "Mudanca em autenticacao, cobranca, migracao de banco ou configuracao de deploy"
  ]
}

O erro comum deste passo: escrever criteria como "baixo", "medio", "alto"

Isso não diz nada pro modelo nem pro colega que vai ler teu workflow daqui a seis meses

Ah, e cuidado com o tamanho da escala: o Score exige no mínimo 2 níveis e a API aceita no máximo 10

  1. Faça o POST autenticado

Agora é juntar model, state e a pergunta em uma chamada só

curl -X POST https://api.typesafe.ai/v1/systemone \
  -H "Authorization: Bearer $TYPESAFE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "jev-1.13",
    "state": { "title": "fix: retry on 429", "diff": "..." },
    "type": "choice",
    "instructions": "Classifique o risco deste pull request",
    "criteria": ["low", "medium", "high"]
  }'

Tome cuidado! O campo de tipo da pergunta só aceita minúsculas

Mandar "Choice" ou "SCORE" é o erro comum aqui, e é daqueles que faz tu perder vinte minutos olhando pro payload achando que o problema é outro

  1. Leia a resposta tipada, não só o rótulo

A resposta de uma pergunta choice traz a opção vencedora, as probabilidades de todas as opções (que somam 1) e um valor de confidence

{
  "choice": "medium",
  "probabilities": { "low": 0.21, "medium": 0.62, "high": 0.17 },
  "confidence": 0.74
}

O erro comum deste passo: usar só o campo choice e jogar fora o resto

As probabilidades e o confidence são justamente o que permite tu decidir se confia naquele rótulo ou não

  1. Ramifique com confidence-gated routing

A TypeSafe documenta um padrão pra isso, dividindo a confiança em três faixas: alta significa agir automaticamente, média significa agir com cautela (pedir confirmação ou sinalizar pra revisão) e baixa significa não agir, mandando pra um humano ou pra outro sistema

A doc de confidence traz inclusive o exemplo de código roteando pra revisão humana quando a confiança fica abaixo de um limiar:

if answer.confidence < 0.8:
    route_to_human_review(pr)
else:
    handle(answer)

O erro comum deste passo: cravar um 0.8 global e achar que resolveu

A própria TypeSafe orienta que o limiar não é um número único: ações diferentes no mesmo sistema devem ser travadas em níveis diferentes, conforme a consequência do erro, e os limiares precisam ser testados plotando confiança contra acurácia nos teus próprios dados

  1. Trate contexto ausente como unclassified explícito

PR sem descrição, diff que não veio, contexto rejeitado: acontece

A Action da Sentry resolve isso da forma certa, deixando o resultado explicitamente como não classificado em vez de chutar um rótulo

O erro comum deste passo é o clássico except: risk = "low"

Falha silenciosa que vira merge automático é o pior bug possível nesse desenho

Merge automático, revisão humana ou bloqueio: como definir cada saída

As três saídas mapeiam direto nas três faixas de confiança que a TypeSafe documenta, e cada uma tem um gatilho bem definido:

  • Merge automático: confiança alta e risco na ponta baixa da escala, aquela mudança que no mundo real ninguém revisa com carinho mesmo
  • Revisão humana: faixa média, ou risco médio, ou confiança que não bateu o limiar daquela ação específica
  • Bloqueio: risco alto com confiança alta, aquele caminho que tu não quer que passe sozinho nem em dia bom

O ponto que mais gente erra é achar que dá pra usar o mesmo limiar nas três

Não dá

A consequência de errar um merge automático é MUITO maior que a de pedir uma revisão desnecessária, então o gate do merge automático tem que ser bem mais apertado que o gate da label

E o número certo não sai de achismo: sai de plotar confiança contra acurácia nos dados do teu time

A progressão que a Sentry usou (e vale copiar)

O caminho real observado no repositório getsentry/cli é um roteiro bonito de como fazer isso sem quebrar a cara

Primeiro veio a etapa consultiva: o PR #1596 rodou a análise de risco com Jev quando o PR é aberto, atualizado, reaberto ou marcado como ready for review, com permissões read-only no repositório e resultado publicado no summary do Actions mais um artefato JSON

Repara que nesse primeiro passo o Jev não decide nada, ele só opina

Depois, em um segundo momento, o PR #1600 passou a publicar as labels de risco direto no pull request: risk: low, risk: medium e risk: high, substituindo apenas as labels de risco anteriores e preservando as demais

Ou seja: primeiro observa, depois age de forma reversível (label é fácil de tirar), e só aí tu pensa em automação de merge

O contraponto honesto da comunidade

Existe também uma Action da comunidade, o jev-pr-review, que pontua cada arquivo do PR com Jev e opera só em shadow mode

Ela comenta e nunca faz merge

O detalhe mais interessante é que o automerge está desenhado ali, porém deliberadamente inalcançável até existirem dados reais de calibração

Achei isso muito massa, sinceramente: é o oposto do hype de "deixa a IA mergear tudo"

Só pra deixar claro, esse projeto é da comunidade, não da TypeSafe

O que registrar para auditar a decisão depois

Decisão automática sem rastro é pedido de desculpa futuro

Se o gate barrou um PR urgente às 3h da manhã, alguém vai querer saber exatamente por quê

A Action de risco da Sentry escreve um job summary e um resultado em JSON (em risk-pr-result.json por padrão), além de expor os outputs risk-label e status pro restante do workflow consumir

- id: risk
  uses: getsentry/pr-risk-action@main

- name: Exige revisao humana em risco alto
  if: steps.risk.outputs.risk-label == 'high'
  run: echo "Revisao humana obrigatoria neste PR"

E o conteúdo do JSON é o que faz a auditoria existir de verdade

Ele registra:

  • a revisão exata que foi analisada
  • as probabilidades por classe
  • a confiança do provedor, quando disponível
  • o hash da request
  • as versões envolvidas
  • uso, tentativas e latência
  • o custo conhecido ou estimado

Com isso na mão, revisitar uma decisão seis meses depois deixa de ser arqueologia

E a segurança do desenho?

Essa parte é fácil de esquecer e perigosa de errar: tu está rodando CI em cima de código de PR, às vezes de fora

O desenho da Action da Sentry resolve isso lendo as revisões exatas do Git em um repositório bare isolado, sem checkout e sem executar o código do PR

Além disso, ela executa apenas código de scorer confiável e verifica a revisão do PR antes de publicar o summary e o JSON

Traduzindo: o diff entra como dado, nunca como código executável

Se tu for escrever a tua própria versão disso, copia essa parte antes de copiar qualquer outra

Comece consultivo, depois aperte o parafuso

O caminho seguro pra colocar o Jev no teu pipeline cabe em quatro movimentos

  1. Roda como etapa consultiva, sem poder de bloquear nada
  2. Coleta o JSON de auditoria por algumas semanas de PRs reais
  3. Plota confiança contra acurácia nos teus dados e descobre o limiar de cada ação
  4. Só então libera automação por faixa, começando pela ação mais barata de errar

Sobre performance, a TypeSafe reporta latência ponta a ponta de 70 a 500 ms em tarefas adequadas, e declara ganhos de 20x a 200x em velocidade e 40x a 400x em custo nos workflows de decisão

Agora, honestidade: esses são claims do fabricante, e o próprio post de lançamento diz que os números maiores estão no topo da faixa de ganhos do mundo real

Então trata o topo da faixa como melhor caso, não como promessa

O próximo passo é bem direto: cria a conta no console, usa o crédito inicial gratuito e roda um primeiro experimento em shadow mode no teu repositório, só comentando o risco sem mexer em merge nenhum

Se os rótulos baterem com o que teu time acha na revisão, aí sim tu aperta o parafuso 😀

Abraço e até o próximo post!

Matheus Battisti

Perguntas frequentes

Quanto custa rodar o Jev em todo PR aberto no repositório?

O Jev cobra só pela entrada, US$ 0,042 por milhão de tokens, e a saída sai de graça. Como o state de um PR (título, paths, diff) cabe em poucos milhares de tokens na maioria dos casos, o custo por classificação tende a ser baixo. Vale simular com o volume real do teu repositório antes de rodar em todo PR.

Dá pra deixar o Jev aprovar e mergear PR sozinho, sem humano no loop?

Tecnicamente sim, mas a própria TypeSafe recomenda o confidence-gated routing: alta confiança age automático, média pede cautela ou revisão, baixa não age e vai pro humano. Os exemplos reais seguem essa linha: a Sentry e o repositório getsentry/cli usam o Jev como etapa consultiva ou de label, não como aprovador final.

Quando usar choice em vez de score pra classificar risco de PR?

Use choice quando o risco é uma categoria fechada tipo ‘low’, ‘medium’, ‘high’, e a resposta te dá a opção vencedora mais a probabilidade de cada uma. Use score quando faz sentido um valor ordenado que pode cair entre níveis, com no mínimo 2 e no máximo 10 níveis definidos. Pra uma pergunta binária tipo ‘este PR mexe em autenticação?’, o noul resolve com um valor de 0 a 1.

A agent skill do Jev é obrigatória pra usar a API no Claude Code?

Não, ela é opcional. A API funciona com qualquer chamada HTTP autenticada com Bearer key no endpoint System One, independente de agente. A skill só ajuda o Claude Code a ter o contexto da API na mão, via plugin instalado com claude plugin install typesafe@typesafe-ai.

Existe algum exemplo público de Jev classificando risco de pull request?

Sim, a Sentry mantém uma GitHub Action pública, a pr-risk-action, que classifica o risco de pull requests usando Jev. O repositório getsentry/cli também adotou o Jev, primeiro como etapa consultiva, só publicando o resultado no summary do Actions, e depois passando a publicar labels de risco direto no pull request.

Qual limiar de confidence usar pra travar o merge automático?

Não existe um número único: a TypeSafe orienta calibrar o limiar por ação, plotando confiança contra acurácia nos teus próprios dados. O exemplo de código da documentação roteia pra revisão humana quando confidence fica abaixo de 0.8, mas isso é ponto de partida, não regra fixa. Ações com consequência maior de erro merecem um limiar mais rígido que ações de baixo impacto.



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 45min

Blog | Mais populares