Uma vaga com quatrocentos candidatos produz o mesmo resultado em quase toda empresa: alguém olha os cinquenta primeiros com atenção, os cem seguintes por alto, e o resto quase não é lido. Não é descaso; é o limite do tempo disponível. O efeito colateral é que a ordem de chegada pesa mais que o conteúdo.
O Jev, modelo da TypeSafe AI, devolve decisões tipadas com probabilidade em vez de texto gerado. Aplicado a currículos, o ganho principal não é a velocidade: é que a vaga precisa escrever o que considera relevante, em níveis descritos, antes de qualquer avaliação acontecer. Esse texto vira o registro mais honesto do que o processo está medindo.
A parte que precisa ficar dita
Decisão sobre candidatura afeta a vida de uma pessoa. O artigo 20 da Lei 13.709/2018 dá ao titular o direito de solicitar revisão de decisões tomadas unicamente por tratamento automatizado que afetem seus interesses. Este site é de comunidade, não dá orientação jurídica e não substitui a avaliação do jurídico da sua empresa.
O que a arquitetura deve fazer, e é o que descrevemos aqui: usar o modelo para ordenar e sinalizar, nunca para eliminar sozinho; manter a decisão de avançar com uma pessoa; guardar a distribuição, a confiança e a versão do modelo junto com cada avaliação; e ter um caminho de revisão que produza registro. O padrão está em revisão humana no lugar certo.
O desenho das perguntas
Uma chamada por currículo. E, antes dela, um trabalho de limpeza que é parte do
desenho: retirar do state os campos que não devem pesar na avaliação.
from typesafe_sdk import Noul, Score, TypeSafeClient
perguntas = {
"experiencia_na_funcao": Score(
instructions="Quanta experiência direta na função descrita na vaga o texto evidencia?",
criteria=[
"Nenhuma experiência na função.",
"Contato pontual, em outra função.",
"Atuou na função em projetos ou por período curto.",
"Atuou na função como atribuição principal.",
"Atuou na função com escopo amplo e responsabilidade sobre resultados.",
],
),
"profundidade_tecnica": Score(
instructions="Qual a profundidade técnica evidenciada nas ferramentas exigidas pela vaga?",
criteria=[
"Nenhuma menção às ferramentas.",
"Menciona sem detalhe.",
"Usou em projetos, com alguma especificidade.",
"Ferramenta principal, em vários projetos.",
"Domínio evidente: arquitetura, desempenho, decisões técnicas.",
],
),
"evidencia_de_resultado": Score(
instructions="Quanto o texto descreve resultados concretos, e não apenas atribuições?",
criteria=[
"Só lista cargos e períodos.",
"Descreve atribuições.",
"Descreve entregas nomeadas.",
"Descreve entregas com efeito observável descrito pelo candidato.",
],
),
"requisito_obrigatorio_presente": Noul(
instructions="O texto evidencia o requisito obrigatório da vaga: registro profissional ativo no conselho da categoria?"
),
"disponibilidade_declarada": Noul(
instructions="O candidato declara disponibilidade para o regime de trabalho descrito na vaga?"
),
}
Requisito obrigatório é um Noul, não um nível de régua, porque requisito obrigatório não se compensa: nota alta nas outras dimensões não substitui um registro profissional que a lei exige para a função. A diferença entre filtro e peso é o erro conceitual mais comum neste caso, e a discussão está em pontuação composta.
O que o código faz com a resposta
Piso de confiança primeiro. Currículo com formatação estranha, texto extraído de PDF com colunas embaralhadas ou conteúdo muito curto derruba a confiança. Esse caso vai direto para leitura humana, e não para o fim da fila — a diferença importa.
Regras determinísticas depois. requisito_obrigatorio_presente abaixo do
corte sinaliza, não elimina: o candidato vai para uma lista à parte onde uma
pessoa confirma se o requisito realmente falta ou se apenas não estava escrito.
Combinação por último, e só para ordenar. As duas primeiras réguas têm cinco níveis, então dividem por 4; a terceira tem quatro níveis e divide por 3.
faltou_confianca = any(
r.answers[k].confidence < PISO
for k in ("experiencia_na_funcao", "profundidade_tecnica")
)
if faltou_confianca:
return leitura_humana(cv, motivo="confiança baixa")
if r.answers["requisito_obrigatorio_presente"].noul < 0.4:
return lista_de_verificacao(cv, motivo="requisito não evidenciado")
exp = r.answers["experiencia_na_funcao"].score / 4
tec = r.answers["profundidade_tecnica"].score / 4
res = r.answers["evidencia_de_resultado"].score / 3
nota = 0.45 * exp + 0.35 * tec + 0.20 * res
registrar(cv, nota=nota, distribuicao={k: r.answers[k].probabilities
for k in PERGUNTAS_COM_DISTRIBUICAO},
modelo=r.model)
fila_de_leitura(cv, ordem=nota) # ordena; não elimina
O nome da função final é deliberado: fila_de_leitura, não aprovados. O
sistema decide em que ordem uma pessoa lê, e é só isso.
Onde entra a pessoa
Na decisão, sempre. E em mais três lugares:
No topo e no fundo da lista. Ler os melhores colocados é natural; ler uma
amostra dos piores é o que detecta régua mal escrita. Se a amostra do fundo
revela candidatos fortes, o problema está no criteria, não no candidato.
Na lista de requisito não evidenciado. Um registro profissional pode existir e não estar escrito no currículo. Confirmar é trabalho humano barato e evita descartar alguém por erro de redação.
Na revisão periódica por grupo. Medir a distribuição de notas por origem de candidatura, por formação e por outros recortes que a sua área jurídica e de pessoas considerar relevantes é a única forma de descobrir um viés sistemático da régua. Guardar a distribuição é o que torna essa medição possível depois.
Custo
Assumindo dez mil currículos por mês — suposição deste artigo — e um state de
cerca de quatro mil tokens, que é um currículo razoavelmente longo já convertido
em texto: 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 currículo sai por cerca de
R$ 0,00091 e o mês por cerca de R$ 9,07. A fórmula está em
quanto custa uma decisão.
Onde isso quebra
Contagem e aritmética de tempo. “Quantos anos de experiência tem?” é
exatamente o tipo de pergunta que a documentação desaconselha: o jev-1.13 não
conta de forma confiável e lê datas como texto, não como quantidade ordenada.
Se os períodos de trabalho vierem estruturados no seu sistema de candidaturas,
calcule os anos em código e mande o número. Se estiverem no texto corrido,
aceite que essa dimensão é uma estimativa e não a use como corte.
Leitura literal. O modelo responde à pergunta escrita, não à intenção. “Tem experiência com liderança?” e “liderou time com subordinados diretos?” produzem notas diferentes, e a segunda é a que você provavelmente quis perguntar.
State grande e ruidoso. Currículo extraído de PDF vem com cabeçalho, rodapé, tabela quebrada e caracteres soltos. Detalhe irrelevante age como distrator — é um dos nove modos de falha declarados. Limpe antes; o efeito está em context rot.
Conteúdo adversarial. Existe texto branco em fundo branco dentro de
currículo, escrito para enganar filtros automáticos. A documentação avisa que o
state não é tratado como hostil por padrão. Extrair o texto visível e
comparar com o texto completo é uma verificação barata que vale fazer antes da
chamada.
O modelo não valida fato nenhum. Ele avalia o que está escrito. Diploma, registro e vínculo anterior se conferem em fonte própria.
A lista completa dos limites está em limites do Jev, e os outros fluxos em casos de uso.
Perguntas frequentes
Posso reprovar candidatos automaticamente?
Este guia não dá orientação jurídica e não recomenda isso. O artigo 20 da Lei 13.709/2018 dá ao titular o direito de solicitar revisão de decisões tomadas unicamente por tratamento automatizado que afetem seus interesses. O desenho que descrevemos ordena e sinaliza, mas mantém a decisão de avançar ou não com uma pessoa.
Como isso é diferente de um filtro por palavra-chave?
Um filtro por palavra-chave elimina quem escreveu diferente. Uma pergunta com níveis descritos avalia a evidência no texto e devolve uma nota com a distribuição, o que dá para auditar, comparar entre candidatos e ajustar mudando um peso em vez de reescrever um regex.
O modelo pode discriminar?
O risco existe em qualquer sistema que lê texto de pessoas, e não some por usar probabilidade. Três defesas de desenho ajudam: tirar do state os campos que não deveriam pesar, escrever critérios que citem evidência relacionada à função, e medir o resultado por grupo antes de confiar na fila.
Como o modelo sabe o que a vaga exige?
Pelo que você escreve nos criteria. O Jev não é ajustado com os seus dados: a documentação diz que os mesmos pesos servem todas as contas e que a adaptação ao domínio acontece pelo state e pela descrição dos níveis e das opções.
Quanto custa avaliar dez mil currículos?
Assumindo um state de cerca de quatro mil tokens, que é um currículo razoavelmente longo em texto, 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, cada currículo sai por cerca de R$ 0,00091 e dez mil por cerca de R$ 9,07.