A reunião de triagem de bugs tem um formato conhecido: uma lista longa, uma pessoa lendo em voz alta, duas pessoas discordando sobre o que é P1, e a mesma discussão de novo na semana seguinte. O que torna a reunião cansativa não é o julgamento difícil — é que 80% da lista é óbvia e passa pela mesma cerimônia dos 20% que não são.
O Jev, modelo da TypeSafe AI que devolve decisões tipadas com probabilidade em vez de texto, resolve a parte óbvia. E, o que importa mais, obriga a equipe a escrever o que significa cada nível de severidade — que é a discussão que a reunião nunca termina.
O desenho das perguntas
Uma chamada por relato. No state, o texto do relato e os campos que a sua
telemetria já sabe, já calculados.
{
"state": {
"titulo": "Pedido some do carrinho ao trocar de aba",
"relato": "Quando eu deixo o carrinho aberto e volto depois de um tempo, os itens somem. Perdi um pedido de quase mil reais que eu tinha montado item por item. Não apareceu erro nenhum.",
"plataforma": "web",
"usuarios_afetados_7d": 412,
"dias_desde_o_primeiro_relato": 3,
"tem_contorno_documentado": false
},
"questions": {
"area": {
"type": "choice",
"instructions": "Qual área do produto este relato aponta?",
"criteria": {
"carrinho_e_checkout": "Montagem do pedido, carrinho, pagamento, finalização.",
"conta_e_acesso": "Login, cadastro, permissão, recuperação de senha.",
"catalogo": "Busca, listagem, ficha de produto, estoque exibido.",
"integracao": "API, webhook, importação e exportação de dados.",
"indeterminada": "O relato não permite identificar a área."
}
},
"severidade": {
"type": "score",
"instructions": "Qual a gravidade do comportamento descrito para quem usa o produto?",
"criteria": [
"Cosmético; não afeta o que dá para fazer.",
"Funcionalidade degradada, com contorno possível.",
"Funcionalidade bloqueada, sem contorno descrito.",
"Perda de dados, de dinheiro ou risco de segurança."
]
},
"clareza_do_relato": {
"type": "score",
"instructions": "Quanto este relato permite reproduzir o problema?",
"criteria": [
"Só a queixa, sem contexto.",
"Descreve o sintoma, sem passos.",
"Descreve passos parciais ou condição de ocorrência.",
"Passos completos e resultado esperado versus obtido."
]
},
"menciona_perda_de_dados": {
"type": "noul",
"instructions": "O relato descreve perda de dados, de trabalho salvo ou de dinheiro do usuário?"
},
"menciona_seguranca": {
"type": "noul",
"instructions": "O relato descreve acesso indevido, vazamento de dado de outra pessoa ou falha de autenticação?"
}
}
}
Os dois números do state — usuarios_afetados_7d e
dias_desde_o_primeiro_relato — vêm prontos do seu sistema. Isso não é detalhe
de implementação: é o que impede a arquitetura de pedir ao modelo duas coisas
que ele declaradamente não faz bem.
O que o código faz com a resposta
Piso de confiança primeiro. Área com confiança baixa significa relato vago. Vai para uma fila de “pedir mais informação”, não para um time.
Regras determinísticas depois. menciona_seguranca acima do corte escala
na hora para o time responsável, fora da fila normal. menciona_perda_de_dados
força prioridade máxima. As duas são políticas de engenharia, e políticas não
devem depender de pesos.
Combinação por último, com os números que vieram do seu banco.
a = r.answers["area"]
if r.answers["menciona_seguranca"].noul > 0.5:
return escalar_seguranca(bug) # corte baixo de propósito
if r.answers["menciona_perda_de_dados"].noul > 0.6:
prioridade_base = 1.0
else:
prioridade_base = r.answers["severidade"].score / 3
if a.confidence < PISO:
return pedir_mais_informacao(bug)
alcance = min(bug["usuarios_afetados_7d"] / 1000, 1.0) # aritmética no código
idade = min(bug["dias_desde_o_primeiro_relato"] / 30, 1.0)
prioridade = 0.55 * prioridade_base + 0.35 * alcance + 0.10 * idade
enfileirar(bug, time=TIMES[a.choice], prioridade=prioridade,
clareza=r.answers["clareza_do_relato"].score)
A nota de clareza não entra na prioridade: ela vira uma etiqueta. Bug prioritário com clareza baixa é o primeiro da fila de “pedir passos ao usuário”, o que é uma ação diferente de “corrigir”.
Onde entra a pessoa
O limiar acompanha o risco. Segurança tem corte baixo, em 0,5, porque um falso positivo custa a leitura de um engenheiro e um falso negativo custa um incidente. Área e prioridade têm corte alto, porque errar o time custa um ciclo de sprint.
A revisão humana continua existindo — mas muda de objeto. Em vez de discutir a
lista inteira, a reunião discute a faixa de confiança baixa e a fronteira entre
os dois níveis mais altos da régua. Quando essa discussão acontece, a saída dela
é uma frase melhor no criteria, não uma decisão sobre aquele bug específico. É
assim que a régua melhora com o tempo; o assunto está em
critérios que separam.
Custo
Assumindo dez mil relatos por mês — suposição deste artigo, típica de um produto
grande com canal aberto de feedback — e um state de cerca de dois mil tokens:
ao preço oficial de US$ 0,042 por milhão de tokens de entrada, com saída
gratuita, e o dólar estimado em R$ 5,40, cada relato sai por cerca de
R$ 0,00045 e o mês por cerca de R$ 4,54. A fórmula está em
quanto custa uma decisão.
Onde isso quebra
Este caso esbarra em três dos nove modos de falha declarados do jev-1.13, e
por isso o desenho acima empurra tanta coisa para o código.
Contagem. “Quantos usuários relataram isso?” não é pergunta para o modelo. A documentação diz que ele reconhece a forma de uma resposta em vez de contar, e que o erro cresce com o tamanho da coisa contada. O número vem da telemetria.
Comparação de datas. “Este bug está aberto há mais de duas semanas?” é aritmética sobre datas, e o modelo lê data como texto, não como quantidade ordenada. Calcule os dias no seu sistema e passe o inteiro.
Numérico versus semântico. A documentação observa que perguntas com representação semântica funcionam melhor que com representação numérica, e cita o caso de valores hexadecimais contra nomes de cor. Em bug, isso significa não pedir ao modelo para julgar um código de erro ou um stack trace como se fosse texto comum — mande o trecho relevante e pergunte sobre o comportamento descrito, não sobre o número.
Não confunda severidade com reprodução. O modelo pontua o texto do relato. Ele não executa o sistema, não confirma o bug e não sabe se o problema já foi corrigido em outra branch. A lista completa dos limites está em limites do Jev, e os outros fluxos desta família em casos de uso.
Perguntas frequentes
O modelo consegue estimar severidade de bug?
Consegue pontuar contra níveis que você descreve, que é diferente de adivinhar um número. Um Score com quatro níveis — cosmético, degradado com contorno, bloqueante e perda de dados — dá uma nota reprodutível sobre o texto do relato. Ele não avalia o código nem reproduz o erro.
Por que perda de dados é Noul e não um nível da régua?
Porque perda de dados costuma ser uma regra de escalonamento imediato, não algo que se pondera com outras dimensões. Um Noul responde uma condição binária que dispara política no seu código; o Score serve para ordenar o resto.
Ele conta quantos usuários foram afetados?
Não. A documentação oficial diz que o jev-1.13 não conta de forma confiável e que o erro cresce com o tamanho da coisa contada. A contagem vem da sua telemetria e entra pronta no state, como número.
E o tempo aberto do bug, entra na prioridade?
Entra, mas calculado em código. O modelo lê data como texto, não como quantidade ordenada, então comparar datas é um dos limites declarados. Calcule os dias no seu sistema e some o peso na fórmula.
Quanto custa triar dez mil relatos?
Assumindo um state de cerca de dois mil tokens, que cobre o relato e os campos técnicos, ao preço oficial de US$ 0,042 por milhão de tokens de entrada e com o dólar estimado em R$ 5,40, dez mil relatos saem por cerca de R$ 4,54.