Como extrair campos de texto bagunçado com o Jev (e por que o regex continua no jogo)

fluxo para extrair campos com o Jev usando regex e schema de perguntas
Resposta rápida

Para extrair campos com o Jev, o fluxo oficial não é mandar o texto cru e esperar o schema preenchido sozinho. É assim: um regex ajustado para achar demais gera os candidatos, o Jev escolhe qual candidato responde à pergunta e o seu código normaliza e grava. Cada campo do schema vira uma pergunta (Choice, Score ou Noul) e a resposta volta com o valor copiado, a probabilidade de cada opção e uma confiança de 0 a 1. O regex continua no jogo pra formato fixo, ordenação de datas e cálculo numérico

Fala aí, beleza? Todo dev tem aquele regex de 80 caracteres que funciona lindamente até chegar o primeiro documento formatado de um jeito diferente

Aí quebra, você adiciona mais um grupo opcional, quebra de novo, e em seis meses ninguém mais entende a linha

O Jev é o primeiro modelo da classe System One da TypeSafe AI: você manda perguntas estruturadas sobre um estado e recebe respostas tipadas com probabilidades calibradas, em vez de texto gerado

E aqui vai o aviso que muita gente vai querer ouvir diferente: ele NÃO substitui o regex

O fluxo que a documentação oficial descreve é de dupla: o regex acha os candidatos, o Jev escolhe qual candidato responde à pergunta, e o seu código normaliza e age sobre o valor

Bora ver na prática?

O que você precisa antes de começar

O SDK oficial tem versão em Python e em JavaScript/TypeScript, e a instalação é o clássico next, next e finish:

# Python 3.10 ou superior
python -m pip install typesafe-sdk

# Node.js 20 ou mais novo
npm install @typesafe-ai/sdk

O cliente do SDK lê a variável de ambiente TYPESAFE_API_KEY e chama jev-latest por padrão

Formação Claude Code
Formação Recomendada

Formação Claude Code

Domine Claude Code do absoluto zero até o avançado

  • 120 aulas
  • 4 projetos
  • 9h 45min

Esse jev-latest é um alias que resolve pra um ID versionado, e hoje ele aponta pro jev-1.13.0

A própria resposta reporta no campo model qual versão respondeu, e você também pode passar o ID versionado direto pra fixar a versão (útil quando você não quer que o comportamento mude debaixo do seu parser)

Agora os limites de entrada, porque isso muda o desenho da sua pipeline:

  • Entrada text-only: string, objeto JSON ou array de valores de texto. Imagem, áudio e vídeo não são suportados
  • Janela de contexto do Jev 1.13: 32.000 tokens
  • Preço na página viva de provedores: US$ 0,042 por milhão de tokens de entrada e US$ 0 por milhão de tokens de saída

Sacou a implicação? Se o seu documento é PDF escaneado, o OCR continua sendo problema seu antes de chegar no Jev 🙂

Passo a passo: do texto cru ao valor tipado

A referência aqui é o cookbook oficial, chamado Pre-parsed value extraction, e o quickstart do SDK

1. Defina os campos desejados: cada campo vira uma pergunta

Na integração do Pydantic AI com a TypeSafe, cada campo do tipo de saída vira uma pergunta

Ou seja, um modelo Pydantic com vários campos extrai vários valores em uma requisição só

from pydantic import BaseModel

class DadosDaFatura(BaseModel):
    endereco_do_recibo: str
    telefone: str
    total: str
    moeda: str
    eh_cobranca: bool

Pensa no schema como a lista de perguntas que você faria pra um estagiário lendo o documento, não como um molde mágico que o modelo preenche sozinho

O erro comum deste passo: escrever campo vago tipo valor

Valor de quê? Do subtotal, do imposto, do total? O modelo é literal, e a documentação oficial de jaggedness do Jev 1.13 registra isso: ele responde a pergunta que você escreveu, não a que você quis dizer

2. Escolha a primitiva certa: Choice, Score ou Noul

São três primitivas de pergunta:

  • Choice: escolher uma opção de um conjunto definido
  • Score: pontuar contra níveis ordenados
  • Noul: uma afirmação sim/não que retorna a probabilidade calibrada de ser verdadeira

Pra extração de campo, o feijão com arroz é Choice: você entrega as opções e pergunta qual delas responde

Noul entra pros atributos booleanos, do tipo "este valor é uma cobrança"

O erro comum deste passo: usar Score pra chegar num número exato

A documentação oficial diz na lata que o Jev 1.13 tem dificuldade com precisão numérica e que a saída de Score não deve ser usada pra calcular a magnitude exata de um número entre dois níveis do critério. Tome cuidado!

3. Gere os candidatos com um regex ajustado pra achar demais

Este é o passo que inverte a lógica do que você está acostumado

O regex aqui não precisa ser preciso, ele precisa ser generoso

A missão dele é não deixar o valor certo de fora, nem que venham cinco candidatos errados junto

import re
from typesafe_sdk import Choice, Noul, TypeSafeClient

client = TypeSafeClient()  # lê TYPESAFE_API_KEY do ambiente

texto = open("email_do_cliente.txt").read()

candidatos_telefone = re.findall(r"\+?\d[\d\s().-]{7,}\d", texto)

Se você nunca brincou de garimpar padrão numérico em string, o básico de extrair números de uma string já resolve a parte da geração de candidatos

O erro comum deste passo: apertar o regex

Se o candidato certo não entra na lista, o Jev não tem como escolher ele. A primitiva é de escolha, não de invenção

4. Mande o texto e os candidatos como opções do Choice

O estado é o texto (ou o texto estruturado), e as opções são os candidatos que você garimpou

pergunta = Choice(
    question="Qual destes telefones é o número de contato do remetente?",
    options=candidatos_telefone,
)

resposta = client.ask(state=texto, question=pergunta)

Confira a assinatura exata no quickstart oficial do SDK, que é onde os imports e o cliente estão documentados

O erro comum deste passo: estourar o teto

Uma pergunta Choice aceita no máximo 255 opções

Passou disso, a documentação indica estreitar em dois estágios: primeiro um Choice pra escolher a seção do documento, depois outro Choice pro trecho dentro dela

O outro erro é jogar o documento inteiro cheio de rodapé, assinatura e disclaimer no estado. A acurácia cai conforme o estado fica ruidoso com detalhes irrelevantes, e níveis extras de indireção degradam o resultado

5. Leia a resposta: opção, probabilidades e confiança

A resposta de um Choice inclui a opção selecionada, a probabilidade de cada opção e um valor de confiança

Esse valor de confiança vai de 0 a 1 e é derivado do formato da distribuição de probabilidade: distribuição concentrada gera confiança mais alta, distribuição mais plana gera confiança mais baixa

E aqui está a diferença prática mais importante em relação ao regex: o regex te devolve match ou nada

O Jev te devolve o valor E o quanto a decisão foi disputada

O erro comum deste passo: ignorar a confiança e gravar tudo no mesmo saco. Ela é justamente o sinal que você não tinha antes

6. Peça os atributos na mesma passada

O valor devolvido é o candidato escolhido, copiado (seleção verbatim)

Mas o cookbook oficial mostra que o Jev também lê atributos que o código precisa depois, como moeda, país e se um valor é crédito ou cobrança

eh_cobranca = Noul(
    statement="O valor total selecionado é uma cobrança ao cliente, e não um crédito"
)

O erro comum deste passo: fazer duas viagens pro que cabia em uma, já que um modelo com vários campos extrai vários valores em uma requisição

7. Normalize no código e grave no banco

O Jev escolheu "+1 (415) 555-0177"? Ótimo

Quem transforma isso em +14155550177 é o seu código, como o próprio fluxo do cookbook descreve: regex acha, Jev escolhe, código normaliza e age

telefone = re.sub(r"[^\d+]", "", resposta.value)

if resposta.confidence < 0.8:
    fila_de_revisao.append(registro)
else:
    salvar(registro)

O erro comum deste passo: gravar o verbatim direto no banco

O valor volta do jeitinho que estava no texto, com parênteses, espaço e o que mais o cliente tiver digitado 😛

Três extrações que o cookbook oficial já resolve

O cookbook traz três casos trabalhados, e todos têm a mesma cara: o problema não é ACHAR, é DECIDIR

1. O endereço para onde o remetente quer o recibo. O e-mail tem endereço de cobrança, endereço de entrega, endereço do rodapé da empresa e mais dois no histórico da thread. O regex acha os cinco, a pergunta define qual deles interessa

2. Um telefone no formato +14155550177. Mesma história: vários números no documento, um só é o contato que você quer

3. Um total de fatura de 1315.50 USD sinalizado como cobrança. Aqui aparece a combinação bonita: o Choice escolhe qual dos valores do documento é o total, e ele volta verbatim, do jeitinho que estava no texto

Junto vêm os atributos tipados na mesma passada: a moeda e se aquilo é crédito ou cobrança

Repara que os três casos fecham o mesmo ciclo: o regex acha, o Jev escolhe, o seu código normaliza e age 🙂

E quando não existe regex pro campo?

E-mails, telefones e valores monetários têm regex que cobre

Nome de pessoa não tem

Nesse caso os candidatos precisam vir de outro lugar: de uma lista que você já tem (um roster de clientes, por exemplo), de um reconhecedor de entidades nomeadas (NER) ou de um LLM que proponha as opções

Repara que o LLM entra aqui como gerador de candidatos, num papel bem diferente de quando você senta pra usar o Claude para escrever alguma coisa. Lá o modelo produz texto, aqui ele só sugere opções pro Jev decidir

Jev x regex x parsing manual: o que cada um resolve

Antes da tabela, um aviso: as colunas não são excludentes

O fluxo oficial usa regex e Jev JUNTOS, e o parsing manual continua no meio pra normalizar

Critério Regex sozinho Parsing manual no código Jev (com regex gerando candidatos)
Quem acha os candidatos O próprio padrão Você, com split, índice e heurística O regex, ajustado pra achar demais
Quem decide qual é o certo Ordem do match ou heurística Suas regras if/else O Jev, respondendo à pergunta que você escreveu
Formato novo aparece Quebra ou traz o valor errado Quebra e você reescreve a regra O regex generoso tende a pegar o candidato, e a decisão continua sendo por pergunta
Tipo de saída String crua do match O que você montar na mão Candidato copiado verbatim + atributos tipados (moeda, país, crédito ou cobrança)
Sinal de incerteza Nenhum: deu match ou não deu Nenhum Probabilidade por opção + confiança de 0 a 1
Custo Zero, roda local Zero de infra, caro de manutenção US$ 0,042 por milhão de tokens de entrada, US$ 0 na saída
Limite de entrada Tamanho do arquivo Tamanho do arquivo Text-only, 32.000 tokens de contexto, 255 opções por Choice
Onde quebra Documento com formato diferente Toda vez que o documento muda Pergunta ambígua, estado ruidoso, data e número

Quando o regex sozinho ainda ganha

Veredito honesto, e ele está documentado pela própria TypeSafe na página de jaggedness do Jev 1.13

Leitura literal. O modelo responde a pergunta que você escreveu, não a que você quis dizer, e lê palavras de escopo, negações e condições implícitas ao pé da letra. Pergunta torta, resposta torta

Precisão numérica. Documentado como ponto fraco: a saída de Score não deve ser usada pra calcular a magnitude exata de um número entre dois níveis do critério. Conta é com o código

Datas. O Jev 1.13 lê datas como texto, e não como quantidades ordenadas, sendo pouco confiável pra dizer qual data vem primeiro ou qual a distância entre elas. E piora com formatos misturados e referências relativas do tipo "na terça passada"

Ruído. A acurácia cai conforme o estado fica ruidoso com detalhes irrelevantes, e camadas extras de indireção degradam o resultado

Juntando tudo: se o seu documento tem formato fixo e único, se o campo é sempre a mesma posição do mesmo template, se o trabalho é ordenar datas ou calcular valor, o regex e o código continuam ganhando de lavada

O Jev brilha quando existe AMBIGUIDADE, ou seja, quando o regex acha cinco coisas parecidas e alguém precisa decidir qual delas era a que interessava

Pra quem está chegando agora nas ferramentas de IA pra dev

Se você ainda está montando seu arsenal de IA pro dia a dia de código, este vídeo do canal mostra o MiMo Code, uma IA de programar grátis, sem login e com 1 milhão de contexto:

Conclusão

A divisão de trabalho é o recado do post inteiro: o regex acha os candidatos, o Jev escolhe qual responde à pergunta, e o seu código normaliza e grava

Não é substituição, é pipeline

Próximo passo concreto: instala o SDK (python -m pip install typesafe-sdk ou npm install @typesafe-ai/sdk), configura a TYPESAFE_API_KEY no ambiente e reescreve UM campo do seu parser atual como uma pergunta Choice

Roda nos seus documentos reais e usa a confiança de 0 a 1 como régua: onde a distribuição vier plana, é exatamente onde o seu if/else também estava chutando 😀

Pra contexto: os System One Models e o Jev foram anunciados em post oficial no blog da TypeSafe, e o lançamento foi noticiado pela imprensa especializada em 19/09/2026, então é assunto novo e a documentação é a fonte pra acompanhar o que muda nas próximas versões…

Até o próximo post!

Perguntas frequentes

Dá pra extrair campos com o Jev sem usar nenhum regex antes?

Depende do campo. Para e-mail, telefone e valor monetário existe regex que cobre bem, então o fluxo continua sendo regex gerando candidatos e o Jev escolhendo. Já para nome de pessoa não há regex confiável, e aí os candidatos precisam vir de uma lista que você já tem, de um reconhecedor de entidades nomeadas ou de um LLM que proponha as opções.

O Jev consegue extrair campos de um PDF escaneado ou de uma foto de documento?

Não direto. O Jev aceita somente entrada de texto ou texto estruturado, como string, objeto JSON ou array de valores de texto, e não suporta imagem, áudio ou vídeo. Se o seu documento é PDF escaneado, o OCR continua sendo etapa sua antes de o texto chegar no Jev.

Quantos campos dá pra extrair em uma única requisição ao Jev?

Na integração do Pydantic AI com a TypeSafe, cada campo do tipo de saída vira uma pergunta. Então um modelo Pydantic com vários campos, tipo endereço, telefone e total, extrai todos esses valores em uma requisição só.

Qual a diferença entre usar Choice e Score pra extrair um campo?

Choice serve pra escolher qual candidato, dentre os que o regex achou, responde à pergunta, e é a primitiva certa pra extração de campo. Score pontua contra níveis ordenados, e a documentação oficial deixa claro que ele não deve ser usado pra calcular a magnitude exata de um número, porque o Jev 1.13 tem dificuldade documentada com precisão numérica.

Quantas opções uma pergunta Choice aceita ao extrair um campo com o Jev?

O teto documentado é 255 opções por Choice. Se os candidatos passarem disso, a saída indicada é estreitar em dois estágios: um primeiro Choice escolhe a seção do documento, e um segundo Choice escolhe o trecho dentro dela.

Quanto custa usar o Jev pra extrair campos de um documento?

Na página viva de provedores, o Jev 1.13 custa US$ 0,042 por milhão de tokens de entrada e US$ 0 por milhão de tokens de saída. A janela de contexto é de 32.000 tokens, o que importa pro tamanho do texto que você manda como estado da pergunta.




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 Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 27min

Blog | Mais populares