Como transformar transcrição de reunião em tarefas com dono e prioridade usando o Jev

fluxo do Jev transformando transcrição de reunião em tarefas com dono e prioridade
Resposta rápida

Usar o Jev numa transcrição de reunião é o contrário de pedir "extraia as tarefas" pro chat: o código quebra a transcrição em trechos candidatos e o Jev responde perguntas fechadas sobre cada trecho. Noul diz se o trecho tem compromisso de ação, Choice escolhe o dono dentro da lista de participantes e Score coloca a prioridade numa régua ordenada, tudo na mesma chamada, com probabilidade e confidence de 0 a 1. A faixa de confiança decide o que vira tarefa automática, o que vira rascunho e o que vai pra revisão humana. O texto da tarefa sai do trecho, não do modelo.

A reunião acabou, todo mundo saiu feliz, e o que sobrou foi uma transcrição de 40 minutos e nenhuma tarefa criada

Aí você joga o arquivo num chat e pede "extraia as tarefas dessa reunião"

Volta uma lista bonita em texto corrido, com bullet, com nome de gente que às vezes nem estava na call, com "prioridade alta" escrito como adjetivo solto, e nada disso entra no board sem alguém sentar e reescrever na mão

O Jev resolve outro pedaço do problema: ele é o primeiro modelo público da TypeSafe AI e pertence a uma classe chamada System One Model, que recebe um estado não estruturado e devolve decisões tipadas com probabilidades calibradas, sem gerar texto livre

Ou seja: ele não escreve a tarefa pra você

Ele responde perguntas fechadas sobre um trecho que VOCÊ já separou, tipo "isso aqui é um compromisso de ação?", "quem entre esses participantes assumiu?", "quão urgente é?"

E devolve isso como campo, com probabilidade, pronto pro seu código decidir o que fazer

Bora montar esse pipeline?

O que você precisa antes de começar

Do lado do acesso:

  • Conta com acesso ao Jev: o modelo foi anunciado e liberado em early access em 15 de setembro de 2026, no mesmo dia em que a TypeSafe AI saiu do stealth com uma rodada seed de US$ 40 milhões liderada pela DCVC. O acesso segue em early access, com a empresa liberando desenvolvedores da lista de espera aos poucos
  • Python 3.10 ou superior
  • SDK instalado a partir do índice da própria empresa
pip install "typesafe-sdk>=0.5.7" --extra-index-url https://pypi.typesafe.ai/

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

export TYPESAFE_API_KEY="sua_chave_aqui"

Do lado do tema, dois insumos que não são opcionais:

A transcrição em texto puro. O estado aceito pelo Jev pode ser uma string, um objeto JSON ou um array de textos, e é só isso: imagens, áudio e vídeo não são suportados. Então a transcrição já tem que estar pronta antes, o Jev não transcreve nada

A lista de participantes da reunião. Esse é o roster de onde vão sair as opções do Choice de dono. Sem ele você não tem de onde escolher o responsável, e já te adianto que isso não é detalhe: o cookbook de pre-parsed value extraction da TypeSafe aponta que nomes de pessoas não têm regex que os cubra, então os candidatos precisam vir de uma lista que você já tem, de um reconhecedor de entidades ou de um LLM que os proponha

Um aviso sobre idioma: o idioma principal de treino do Jev é o inglês, e outros idiomas são aceitos com acurácia menor

Isso importa MUITO aqui, porque transcrição de reunião no Brasil vem em português

Na prática dá pra escrever as instruções e os criteria em inglês mesmo com o trecho em português, e medir a confiança que volta antes de confiar no automático

Atalho pra quem vai codar com agente:

A TypeSafe publica uma agent skill que dá ao agente de código o contexto da API

No Claude Code a instalação é por marketplace de plugins:

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

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

Em outros agentes:

npx skills add typesafe-ai/skills --skill typesafe-ai

A skill oficial fica no repositório typesafe-ai/skills, e a documentação ainda disponibiliza um índice completo em /llms.txt pro agente descobrir as páginas antes de sair explorando 🙂

Passo a passo: da transcrição ao board com dono e prioridade

A ideia guia do pipeline inteiro é a do cookbook de pre-parsed value extraction: código determinístico gera os candidatos, o Jev escolhe qual candidato responde à pergunta, e o código a jusante normaliza e age

Guarda essa frase, porque quase todo erro daqui pra frente é alguém invertendo essa ordem

  1. Quebrar a transcrição em trechos candidatos com código

Regex por falante, depois split por sentença, ajustada pra achar DEMAIS

É melhor gerar 300 candidatos e o Jev descartar 260 do que gerar 40 e perder o compromisso que importava

import re

LINHA = re.compile(r"^\[(?P<hora>[^\]]+)\]\s*(?P<falante>[^:]+):\s*(?P<fala>.+)$")

def quebrar(transcricao: str):
    trechos = []
    for linha in transcricao.splitlines():
        m = LINHA.match(linha.strip())
        if not m:
            continue
        for sentenca in re.split(r"(?<=[.!?])\s+", m.group("fala")):
            sentenca = sentenca.strip()
            if len(sentenca) < 15:
                continue
            trechos.append({
                "hora": m.group("hora"),
                "falante": m.group("falante").strip(),
                "texto": sentenca,
            })
    return trechos

O erro comum deste passo: pedir pro Jev "encontrar as tarefas" na transcrição inteira

Ele não faz isso, ele não gera texto livre, ele decide sobre o que você entrega

  1. Montar o estado como objeto JSON nomeado

A documentação recomenda objeto na maioria dos casos justamente pra nomear cada parte do estado

Então em vez de mandar uma string crua com o trecho solto, você manda o trecho, quem falou, a linha anterior e a pauta, cada coisa no seu campo

def montar_estado(atual, anterior, pauta, participantes):
    return {
        "meeting_agenda": pauta,
        "participants": participantes,
        "speaker": atual["falante"],
        "previous_line": anterior["texto"] if anterior else "",
        "excerpt": atual["texto"],
    }

O erro comum deste passo: mandar a reunião inteira como estado

Estados grandes cheios de detalhe irrelevante estão na lista de falhas conhecidas do modelo, e ainda tem orçamento a respeitar: 64.000 tokens cobrem estado mais todas as perguntas, e 32.000 tokens se aplicam ao estado mais a pergunta mais longa

Trecho curto, contexto mínimo, decisão limpa

  1. A pergunta de triagem com Noul

Noul julga uma única proposição e devolve a probabilidade de a resposta ser sim

Valor perto de 1 é sim forte, perto de 0 é não forte, e perto de 0,5 indica probabilidades semelhantes (ou seja, empate, o modelo não está te ajudando ali)

O campo criteria é opcional e serve pra esclarecer o que significa sim e não, e nesse caso ele é ouro: "compromisso de ação" é vago demais pra deixar solto

from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

client = TypeSafeClient()

triagem = Noul(
    instructions="Does this excerpt contain a commitment to do something after the meeting?",
    criteria={
        "yes": "someone agrees to perform a concrete task, or a task is clearly assigned to a named person",
        "no": "opinion, status update, question, or open discussion with no commitment",
    },
)

O erro comum deste passo: tratar o Noul como booleano

Ele é probabilidade, e o valor do meio é informação (é o trecho que você manda pra revisão humana em vez de jogar fora)

  1. O dono com Choice, em cima do roster

Choice usa o campo criteria, um mapa de opção para descrição, e devolve a opção escolhida mais a distribuição completa de probabilidades

As descrições valem tanto quanto os nomes: é ali que você diz o que cada pessoa faz, pra o modelo não escolher pelo som do nome

E sempre inclua a saída de escape de "não atribuído"

participantes = {
    "ana_souza": "Ana Souza, product manager, owns scope and roadmap decisions",
    "bruno_lima": "Bruno Lima, backend engineer, owns API and database work",
    "carla_reis": "Carla Reis, designer, owns interface and research work",
    "unassigned": "no participant clearly takes ownership of this task in the excerpt",
}

dono = Choice(
    instructions="Who is responsible for the task described in the excerpt?",
    criteria=participantes,
)

Um Choice aceita no máximo 255 opções, o que cobre qualquer reunião humana com folga

Se o seu caso estourar isso (transcrição de evento, all hands gigante), a documentação orienta estreitar em duas etapas: primeiro a seção, depois o item dentro dela

O erro comum deste passo: esperar que o modelo "descubra" nomes que não estão no roster

Nomes não têm regex que os cubra, lembra? Se a pessoa não está na lista, ela não existe pro Choice

  1. A prioridade com Score

Score avalia uma régua ordenada definida em criteria, devolve uma posição que pode cair entre dois níveis, mais a probabilidade de cada nível e um valor de confiança

Essa parte do "pode cair entre dois níveis" é o que diferencia de um adjetivo: você recebe posição, não rótulo

O limite documentado é de 10 níveis, e sinceramente 4 ou 5 já resolve board de time

prioridade = Score(
    instructions="How urgent is acting on this commitment?",
    criteria=[
        "backlog",
        "this_month",
        "this_week",
        "today",
        "blocking_other_people",
    ],
)

O erro comum deste passo: escrever níveis que não formam uma ordem (tipo misturar "bug", "urgente" e "cliente")

Régua é ordem crescente de uma coisa só, o resto é Choice

  1. Mandar as três perguntas numa única chamada

O Jev lê o estado uma vez e avalia todas as perguntas em paralelo, e as primitivas Choice, Score e Noul podem ser misturadas na mesma requisição

No SDK Python as perguntas vão como dicionário pra client.system_one(state, {...}) e as respostas são lidas em response.nouls, response.choices e response.scores pela chave da pergunta

anterior = None

for atual in trechos:
    estado = montar_estado(atual, anterior, pauta, list(participantes))

    response = client.system_one(estado, {
        "is_task": triagem,
        "owner": dono,
        "priority": prioridade,
    })

    print(response.nouls["is_task"].noul)
    print(response.choices["owner"].choice, response.choices["owner"].confidence)
    print(response.scores["priority"].score, response.scores["priority"].probabilities)

    anterior = atual

Detalhe que evita dor de cabeça: as chaves do dicionário de perguntas não são enviadas ao modelo, elas servem só pra mapear as respostas de volta

Então nomear a chave de "is_task" não instrui nada, quem instrui é o campo instructions

  1. Rotear pela confiança, não pelo palpite

Respostas de Choice e Score carregam um valor de confidence entre 0 e 1, derivado da distribuição de probabilidades

E a documentação recomenda dividir isso em três faixas: alta pra agir automaticamente, média pra prosseguir com cautela ou pedir confirmação, baixa pra mandar pra um humano ou outro sistema

O limiar exato varia por ação, conforme a consequência do erro, então os números abaixo são escolha sua, não do modelo

def rotear(response, limiar_alto=0.85, limiar_medio=0.6):
    if response.nouls["is_task"].noul < 0.5:
        return "descartar"

    conf = min(
        response.choices["owner"].confidence,
        response.scores["priority"].confidence,
    )

    if conf >= limiar_alto:
        return "criar_tarefa"
    if conf >= limiar_medio:
        return "rascunho_para_confirmar"
    return "revisao_humana"

Errar o dono de uma tarefa custa barato, errar o dono de um pagamento custa caro

Por isso o limiar é por ação e não global

  1. Normalizar e criar a tarefa com código a jusante

Aqui é o passo que a galera esquece: o título da tarefa sai do TRECHO, não do modelo

O Jev nunca retorna texto livre, então quem monta a string, corta o tamanho, resolve o id do usuário e chama a API do board é o seu código

def montar_tarefa(trecho, response):
    return {
        "titulo": trecho["texto"][:120],
        "responsavel": response.choices["owner"].choice,
        "prioridade": response.scores["priority"].score,
        "origem": f"reuniao 2026-09-24 {trecho['hora']} ({trecho['falante']})",
    }

O erro comum deste passo: tentar arrancar do modelo uma descrição bonitinha

Não é o trabalho dele, e se você quiser polimento de texto depois, isso é outra etapa com outra ferramenta

Saída tipada x lista em texto: por que a diferença aparece no board

O que está em jogo Pedir a lista pro chat Decidir trecho por trecho com o Jev
Formato da saída Texto livre que você ainda precisa parsear Um campo por pergunta, já tipado
Dono da tarefa Nome inventado, abreviado ou variado a cada rodada Opção escolhida dentro do roster que você passou
Prioridade Adjetivo solto ("alta", "urgente") Posição numa régua ordenada, com probabilidade por nível
Medida de incerteza Não existe confidence de 0 a 1, derivado da distribuição
Quando o modelo erra Reler o texto e corrigir na mão Limiar por faixa de confiança define o que é automático
Preço listado Varia por provedor e cobra a saída US$ 0,042 por 1 milhão de tokens de entrada, com tokens de saída gratuitos
Latência Depende do tamanho do texto gerado 70 a 500 ms ponta a ponta, número do próprio fornecedor

Nos materiais de lançamento, a TypeSafe afirma até 200x mais velocidade de inferência e custo até 400x menor que LLMs comparáveis em tarefas de classificação

São alegações do fornecedor, vale tratar como tal e medir no teu caso

Mas a diferença que aparece primeiro nem é preço: é que a saída tipada cai direto no board

E reforçando pela última vez, porque é o ponto que mais confunde: o Jev não gera o texto da tarefa

O título vem do trecho, não do modelo

Quando o objetivo é justamente PRODUZIR texto novo a partir de um material longo, a ferramenta é outra, é aquele tipo de fluxo de transformar o TCC em artigo científico, que é geração, não decisão

Erros que aparecem nesse pipeline (e como prevenir)

A TypeSafe mantém uma página de jaggedness do jev-1.13 listando as falhas conhecidas do modelo, e é lindo isso existir

Quase tudo que quebra nesse pipeline está lá: leitura literal da pergunta, fraqueza em precisão numérica, comparação de datas e horas não confiável, indireção, estados grandes cheios de detalhe irrelevante, conteúdo adversarial e critérios contraditórios

Sintoma: os prazos das tarefas saem errados

Causa: a documentação afirma que o Jev lê datas como texto, não como quantidades ordenadas, o que torna não confiável perguntar qual data vem antes, a distância entre elas ou se uma cai dentro de uma janela

Solução: extraia a data com código (regex mais parser) e nunca pergunte comparação de datas pro modelo

Como prevenir: se a pergunta tem a palavra "antes", "depois" ou "dentro de", ela é do código, não do Jev

Sintoma: o dono sai trocado quando quem fala não é quem assume

Causa: indireção, uma das falhas documentadas. "A Ana pediu, mas o Bruno vai fazer" é exatamente o caso que confunde

Solução: nomear falante e mencionados em campos separados do estado e escrever o instructions sem ambiguidade, perguntando quem EXECUTA, não quem falou

Como prevenir: teste a pergunta em cinco trechos onde o falante não é o dono, antes de ligar no automático

Sintoma: resultado instável, o mesmo tipo de trecho cai ora em uma prioridade ora em outra

Causa: estado grande cheio de detalhe irrelevante, ou trecho longo com dois compromissos misturados

Solução: um compromisso por chamada, trecho curto, contexto só do que ajuda a decidir

Como prevenir: se o trecho tem dois verbos de ação com donos diferentes, quebre antes de perguntar

Sintoma: 429 Too Many Requests no meio do processamento

Causa: você disparou a transcrição inteira em paralelo. Os limites de taxa são medidos em tokens por segundo e requisições por minuto, e uma requisição acima de qualquer um deles retorna 429

Solução: lotear as chamadas, tratar o retry com backoff, e lembrar que a TypeSafe avisa que esses limites mudam sem aviso durante o early access

Como prevenir: não fixe número mágico no seu worker, leia o erro e recue. Limites maiores existem em planos custom e enterprise via [email protected]

Outras decisões da mesma reunião que caem no mesmo pipeline

Depois que a quebra em trechos está pronta, o custo de perguntar mais coisa é quase zero, porque o Jev lê o estado uma vez e avalia as perguntas em paralelo

Então dá pra enriquecer bastante:

  • Separar decisão tomada de assunto em aberto com um Noul: "este trecho registra uma decisão final?". Vira ata automática, não só board
  • Classificar o tipo do item com Choice: bug, follow-up, contratação, compra, documentação. Mesmo padrão do dono, só muda o mapa de criteria
  • Medir se o item precisa de reunião nova com Score, numa régua do tipo resolve por mensagem, resolve em call rápida, precisa de reunião com todo mundo
  • Sinalizar risco ou bloqueio com Noul, pra escalar antes que vire incêndio na sprint seguinte

Todas cabem na mesma requisição, respeitando o orçamento de 64.000 tokens pra estado mais todas as perguntas

É por isso que o custo por trecho quase não muda quando você acrescenta a quarta e a quinta pergunta

E se você faz isso pra cliente, esse é o tipo de rotina chata e repetitiva que encaixa bem num fluxo de automatizar tarefas do cliente com IA, porque o resultado é verificável e o erro é mensurável

Vídeo: contexto sobre economizar tokens em fluxos com IA

Pra quem quer começar a pensar em redução de custo nos fluxos com IA, esse vídeo do canal mostra um cenário de economia na prática, com o custo de tokens caindo pela metade e uma economia de 9,60 no cenário mostrado

Conclusão

A divisão de trabalho é o coração da coisa toda:

O código quebra a transcrição em trechos candidatos e normaliza o resultado no final

O Jev decide, e só decide: Noul pra triagem, Choice pro dono, Score pra prioridade, tudo numa chamada só, sem texto livre no meio

E a faixa de confiança define o que vira tarefa sozinha, o que vira rascunho pra alguém confirmar e o que vai pra revisão humana

Próximo passo concreto, e eu faria exatamente nessa ordem: pega UMA reunião antiga, daquelas em que as tarefas já foram criadas na mão

Roda o pipeline nela e compara as duas listas lado a lado

Ajusta as descrições do Choice de dono e os níveis do Score até a saída bater com o que o time faria, e SÓ DEPOIS liga no board de verdade

É chato? Um pouco

Mas é bem menos chato que descobrir a régua torta com 200 tarefas já criadas no board do time, acredite 😛

até o próximo post!

Perguntas frequentes

O Jev consegue ler a transcrição de reunião inteira e listar as tarefas sozinho?

Não. O Jev é um System One Model, recebe um estado não estruturado e devolve decisões tipadas com probabilidades calibradas, sem gerar texto livre. Ele não varre a reunião procurando tarefas: seu código precisa quebrar a transcrição em trechos candidatos antes, e o Jev só responde perguntas fechadas sobre cada trecho.

Dá pra usar o Jev com transcrição de reunião em português?

Dá, mas com ressalva: o idioma principal de treino do Jev é o inglês, e outros idiomas são aceitos com acurácia menor. Na prática funciona escrever instructions e criteria em inglês mesmo com o trecho da reunião em português, e olhar o confidence antes de confiar no automático.

Quanto custa processar a transcrição de uma reunião inteira com o Jev?

O preço listado é US$ 0,042 por 1 milhão de tokens de entrada, com tokens de saída gratuitos. Cada chamada tem orçamento de 64.000 tokens somando estado mais todas as perguntas, ou 32.000 tokens somando estado mais a pergunta mais longa, então trechos curtos rendem mais chamadas dentro do mesmo custo.

Como o Jev decide quem é o dono de uma tarefa extraída da reunião?

Por um Choice em que o criteria é o mapa de participantes reais daquela call, funcionando como roster de opções. Isso é necessário porque nomes de pessoas não têm regex que os cubra, então os candidatos de dono precisam vir de uma lista prévia, de um reconhecedor de entidades ou de um LLM que os proponha.

O Jev é confiável pra decidir prazo ou data de uma tarefa mencionada na reunião?

Não é o ponto forte dele. A comparação de datas e horas está entre as falhas conhecidas documentadas pela própria TypeSafe, porque o Jev lê datas como texto e não como quantidade ordenada. Perguntar qual data vem antes ou se algo cai dentro de um prazo não é confiável hoje.

Como saber se posso confiar automaticamente na prioridade que o Jev atribuiu a uma tarefa?

Pelo confidence que vem junto de cada resposta de Choice e Score, um valor entre 0 e 1 calculado a partir da distribuição de probabilidades. A documentação recomenda três faixas: confiança alta age sozinha, média segue com cautela ou pede confirmação, e baixa vai pra um humano decidir.




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

Blog | Mais populares