Blog
AI/Voice
12 de março de 20269 min

Imagens de IA de voz e ditafone inline no TAMSIV

A v1.3.2 é a versão mais ambiciosa que publiquei no TAMSIV. Duas funcionalidades principais, uma migração técnica delicada e uma mudança de filosofia na relação entre voz e conteúdo visual.

Na superfície, é simples: você fala, a IA gera uma imagem, que é anexada à sua tarefa. Por baixo, é um pipeline que encadeia speech-to-text, análise contextual por LLM, geração de imagem, upload para o Supabase Storage e exibição com URL assinada. Além de um gravador de voz que passa de uma sobreposição de tela cheia para um componente inline integrado na parte inferior da tela. E como bônus, uma migração de gesture handler que me fez percorrer cada arquivo do projeto em busca de importações viciosas.

Pontos chave
  • As imagens de IA são geradas diretamente da voz: o LLM analisa o contexto da tarefa para criar um prompt otimizado, sem intervenção do usuário.
  • O gravador de voz inline substitui a sobreposição de tela cheia, com transcrição exibida antes do fim do TTS para uma sensação de reatividade imediata.
  • A migração do gesture handler corrigiu um bug invisível no iOS, mas que bloqueava no Android em modo de lançamento.
  • A opção "skip TTS" permite um ganho duplo: tempo de resposta dividido e custos de API reduzidos para usuários que não precisam da resposta de voz.
Smartphone exibindo uma imagem gerada por IA que se integra diretamente em um cartão de tarefa, arte digital colorida emergindo da tela

Como funciona a geração de imagens de IA diretamente da voz?

A ideia nasceu de uma observação simples: uma tarefa com uma imagem é imediatamente mais envolvente do que uma tarefa apenas com texto. Pesquisas em psicologia cognitiva confirmam isso: de acordo com um estudo de John Medina (Brain Rules), o cérebro processa imagens 60.000 vezes mais rápido que o texto. Se você puder associar um visual relevante a cada tarefa, você aumenta a retenção e a motivação.

O problema é que ninguém vai procurar uma imagem manualmente para cada tarefa. Precisava ser automático, contextual e acionado pela voz. Aqui está o pipeline completo:

  1. O usuário fala: "Crie uma tarefa para preparar a apresentação do cliente com uma imagem".
  2. STT nativo transcreve a voz em texto, como descrito em meu artigo sobre STT nativo vs Deepgram.
  3. O LLM analisa o contexto: título da tarefa, descrição, tags existentes.
  4. O LLM gera um prompt otimizado para o modelo de imagem, em inglês, com detalhes de estilo e composição.
  5. O provedor de imagem (Runware ou Gemini) gera o visual.
  6. Upload para o Supabase Storage, criação de um registro em privat.task_attachments com o tipo ai_generated.
  7. Exibição imediata via URL assinada.

Eu detalhei a escolha entre os provedores de imagem no artigo dedicado à geração de imagens de IA. A v1.3.2 integrou este pipeline diretamente no fluxo de voz, tornando-o acessível sem qualquer atrito.

Por que o LLM escreve o prompt em vez do usuário?

Pedir a um usuário para escrever um bom prompt de imagem é como pedir a alguém para falar fluentemente uma língua que nunca aprendeu. Os modelos de geração de imagem são sensíveis à formulação: a ordem das palavras, os modificadores de estilo, os termos técnicos como "cinematic lighting" ou "shallow depth of field" fazem uma diferença enorme no resultado.

A solução é elegante: o LLM conversacional, que já entende o contexto da discussão, torna-se um tradutor entre a intenção humana e a linguagem técnica do modelo de imagem. O usuário diz "uma imagem de apresentação profissional", o LLM traduz para "professional business presentation slides on a modern desk, clean corporate environment, soft directional lighting, photorealistic, 4K detail".

É o mesmo princípio que aplico em toda a arquitetura do TAMSIV: a IA deve fazer o trabalho cognitivo que o usuário não deveria ter que fazer. Eu mencionei isso no artigo sobre personalização de voz: inteligência não é apenas entender as palavras. É entender a intenção por trás das palavras.

Como o gravador de voz inline muda a experiência do usuário?

Mão segurando um smartphone com uma interface compacta de gravação de voz na parte inferior da tela, visualização de onda sonora, interface escura com detalhes em azul

Antes da v1.3.2, o gravador de voz abria uma sobreposição de tela cheia. Você pressionava o microfone, tudo desaparecia em favor de uma interface dedicada à conversa. Era funcional, mas quebrava o contexto. Você não via mais sua lista de tarefas, não via mais onde estava.

O gravador de voz inline muda o jogo. Ele se integra diretamente na parte inferior da tela, como um teclado. Você ainda vê seu conteúdo acima. A transcrição do texto aparece em tempo real enquanto você fala. E, acima de tudo, o texto transcrito é exibido antes do fim da geração do TTS.

Por que isso é importante? De acordo com estudos do Nielsen Norman Group sobre tempos de resposta, 1 segundo é o limite para manter o fluxo de pensamento do usuário. Além disso, ele começa a sentir um atraso. Ao exibir a transcrição imediatamente enquanto o áudio é gerado em paralelo, enganamos a percepção: o usuário vê que a IA entendeu, mesmo que a resposta de áudio ainda não esteja pronta.

Esta é uma técnica bem conhecida em UX: o modelo RAIL do Google recomenda exatamente isso. Responder visualmente em menos de 100ms para que a interação pareça instantânea, mesmo que o processamento completo leve mais tempo.

O que a opção "skip TTS" oferece na prática?

Nem todos os usuários precisam ouvir a resposta da IA. Alguns estão em um ambiente barulhento. Outros querem apenas ler a transcrição. Outros ainda usam o TAMSIV no modo silencioso por hábito.

A opção "skip TTS" permite desativar a síntese de voz da resposta. O ganho é duplo:

  • Tempo de resposta: sem esperar a geração e o download do áudio TTS, a resposta é exibida quase instantaneamente.
  • Custos de API: cada chamada TTS tem um custo (OpenAI cobra por caractere). Em milhares de interações diárias, isso se soma rapidamente.

É também uma questão de acessibilidade. Algumas pessoas preferem ler a ouvir. Outras têm restrições auditivas. Ao oferecer a escolha, respeitamos as preferências de cada um. É o mesmo espírito do design do gravador de voz original: a voz é um canal, não uma obrigação.

Por que a migração do gesture handler era tão crítica?

Desenvolvedor depurando importações de gesture handler em várias telas com código React Native em tema escuro, sessão de programação noturna

É o tipo de bug que te faz duvidar da sua sanidade mental. Tudo funciona em debug. Tudo funciona no iOS. Você muda para o modo de lançamento no Android: o componente não responde mais ao toque. Nenhum erro nos logs. Nenhuma falha. Simplesmente não funciona.

O culpado: importações de TouchableOpacity, FlatList e ScrollView vindas de react-native em vez de react-native-gesture-handler, usadas dentro de GestureDetector. A documentação do React Native Gesture Handler é clara: em um GestureDetector, todos os componentes táteis devem vir da biblioteca gesture handler, não do React Native padrão.

O bug era vicioso por três razões:

  1. Invisível em debug: a ponte JavaScript do React Native no modo debug lida com eventos táteis de forma diferente do modo de lançamento com Hermes.
  2. Invisível no iOS: o UIKit e o sistema de cadeia de resposta do iOS são mais tolerantes do que o sistema de gerenciamento de eventos do Android.
  3. Nenhum erro explícito: nenhum aviso, nenhuma falha. O componente é exibido, tem o estilo correto, mas o toque não aciona nada.

A correção exigiu percorrer cada arquivo do projeto. Não um grep rápido, porque algumas importações estavam misturadas: o TouchableOpacity vinha do gesture handler, mas o ScrollView no mesmo arquivo vinha do React Native. Acabei estabelecendo uma regra estrita para o desenvolvimento futuro, que aplico até hoje.

Como garantir o desempenho com essas novas funcionalidades?

Adicionar funcionalidades é fácil. Adicionar funcionalidades sem degradar o desempenho é uma arte. A v1.3.2 introduz um pipeline de imagem e um gravador de voz inline, dois componentes potencialmente pesados. Aqui estão as otimizações implementadas.

Primeiro, zero re-renderizações desnecessárias. O gravador de voz inline usa React.memo e callbacks estáveis para evitar acionar re-renderizações na lista de tarefas acima. Cada animação passa por useNativeDriver: true para rodar na thread nativa, não na thread JavaScript.

Em seguida, a limpeza agressiva. O AudioPlayerService implementa um tempo limite de segurança de 30 segundos. Se um áudio não terminar dentro desse tempo (problema de rede, arquivo corrompido), o serviço força a limpeza. Sem isso, os recursos de áudio se acumulam na memória. Eu já havia detalhado a arquitetura desse serviço no artigo sobre o pipeline de voz.

Finalmente, as imagens geradas são carregadas com lazy loading com um placeholder borrado. A imagem só é baixada quando o cartão da tarefa está visível na tela. Em um feed de 50 tarefas, isso significa potencialmente 50 imagens que não são carregadas desnecessariamente. É o tipo de otimização que impacta diretamente o egress do Supabase que eu havia trabalhado para reduzir.

Qual é o impacto da v1.3.2 no uso diário?

A mudança mais notável é a fluidez. Antes da v1.3.2, usar o TAMSIV era funcional, mas um pouco rígido. Depois, tornou-se natural. Você fala, vê sua tarefa ser criada com uma imagem, e continua seu dia. O gravador de voz inline não te tira mais do seu contexto.

Os feedbacks dos testadores alfa confirmaram a intuição. O gravador de voz inline foi unanimemente preferido à sobreposição. A imagem de IA tornou-se a funcionalidade mais usada depois da criação básica de tarefas. E, acima de tudo, a correção do gesture handler resolveu uma dúzia de relatos de "botões que não funcionam" que não conseguíamos reproduzir em debug.

Esta é a versão que fez o TAMSIV passar de "funciona" para "é agradável". E em build in public, é um marco tão importante quanto o primeiro commit. Eu mencionei isso no balanço aos 650 commits: a qualidade percebida faz a diferença entre um aplicativo que você experimenta e um aplicativo que você mantém.

Perguntas Frequentes

É possível gerar imagens de IA para memorandos também?

Atualmente, a geração de imagens de IA está disponível para tarefas. O mecanismo usa a tabela privat.task_attachments com o tipo ai_generated. A extensão para memorandos está planejada e é tecnicamente simples, já que a tabela privat.memo_attachments já existe com a mesma estrutura.

O gravador de voz inline funciona em segundo plano?

Não. O gravador de voz requer que o aplicativo esteja em primeiro plano para a captura de áudio e a exibição da transcrição em tempo real. É uma escolha deliberada: o reconhecimento de voz nativo do dispositivo é otimizado para o primeiro plano, e a exibição imediata da transcrição é a chave da experiência.

A opção skip TTS é permanente ou por conversa?

É uma configuração permanente armazenada no perfil do usuário. Uma vez ativada, todas as conversas futuras serão apenas em modo de texto. Você pode reativá-la a qualquer momento nas configurações.

O bug do gesture handler ainda afeta o aplicativo?

Não. A migração foi completa e uma regra de desenvolvimento estrita foi implementada: qualquer componente tátil dentro de um GestureDetector deve obrigatoriamente usar as importações de react-native-gesture-handler. Isso é verificado em cada revisão de código.

Quanto custa a geração de uma imagem de IA?

Com o provedor Runware (HiDream-I1-Fast), cerca de 0,003 euros por imagem. Com Gemini 2.5 Flash Image, um pouco mais. Os custos são controlados por cotas por plano de assinatura: o plano Free não tem acesso, o Pro tem uma cota diária, o Team tem uma cota mais alta.