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

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
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.
Formações
Formação Vibe Coding
Do Prompt ao Produto: Crie Software Real com IA
- 474 aulas
- 20 projetos
- 39h 27min
Blog | Mais populares

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.

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 vale a pena? Veredito honesto sobre decisões tipadas em vez de texto
Jev vale a pena? Veja o veredito honesto sobre o modelo System One da TypeSafe AI: decisões tipadas, preço e quando não usar.
