◈ TRIADIC.LIFE / Engenharia de IA / Módulo 8 0/9 aulas
Módulo 08 · 28h estimadas

IA no Front-end, UX e Multimodal

A mesma resposta de um modelo pode parecer mágica ou frustrante dependendo da interface. Este módulo cuida da ponta que o usuário vê: respostas em tempo real, incerteza comunicada com honestidade, imagens, documentos e voz como entrada, ML rodando no próprio navegador e testes que provam que tudo funciona num navegador de verdade.

7 aulas2 labs + app completoBack-end Node + front sem frameworkPré-requisito: Módulo 2

Ao final do módulo você vai

  • Aplicar padrões de UX específicos de IA: streaming, estados, incerteza, cancelamento.
  • Construir chat com streaming ponta a ponta, com a chave da API protegida no back-end.
  • Extrair dados de fotos e PDFs, com saída estruturada e citações.
  • Integrar voz e ML no navegador como melhorias progressivas.
  • Testar a experiência completa com Playwright.
cd o-arco/curso-ia/codigo/modulo-08
pip install -r python/requirements.txt
cd projeto && npm install && npm test     # 10 testes, incluindo navegador (se o Playwright estiver instalado)
npm run dev                                 # http://127.0.0.1:3000 (precisa de ANTHROPIC_API_KEY)

8.1 Padrões de UX para produtos com IA

Leitura · 2h
ProblemaPadrão
Espera longa e tela paradaStreaming + indicador de "gerando"; mostrar o tempo até o 1º token
Resposta indo para o lado erradoBotão parar sempre visível durante a geração (e cancelar no servidor também)
Usuário não sabe se pode confiarCitações e fontes clicáveis (Módulo 4); confiança explícita em extrações
IA errou e agiuDesfazer e confirmação antes de ações; prévia do que vai acontecer
Falha de rede ou da APIEstados de erro claros, com o que fazer; nunca uma bolha vazia
Expectativa irrealDizer o que o assistente faz e o que não faz; exemplos de perguntas
Acessibilidadearia-live para o texto que chega; respeitar prefers-reduced-motion; teclado em tudo
UI generativaAlém de texto, o modelo pode devolver dados estruturados que o front renderiza como componentes (tabelas, cartões, formulários). A regra é a mesma da aula 2.4: o modelo produz dados validados por schema, o seu código decide como desenhar. Nunca renderize HTML gerado pelo modelo direto na página.

8.2 Chat com streaming, do servidor ao navegador

Leitura + prática · 5h
Navegador (fetch + ReadableStream)⇄Seu back-end (valida, limita, guarda a chave)⇄API do LLM (stream)

No servidor (src/servidor.ts)

res.writeHead(200, { "content-type": "text/event-stream" });
const stream = client.messages.stream({ model, max_tokens: 4000, system: SISTEMA, messages });
res.on("close", () => stream.abort());                     // usuário saiu: para de pagar tokens
stream.on("text", (pedaco) => res.write(`event: texto\ndata: ${JSON.stringify({ pedaco })}\n\n`));
const final = await stream.finalMessage();
res.write(`event: fim\ndata: ${JSON.stringify({ stop_reason: final.stop_reason })}\n\n`);

No navegador (public/app.js)

const r = await fetch("/api/chat", { method: "POST", body, signal: controlador.signal });
for await (const { evento, dados } of lerEventos(r.body)) {
  if (evento === "texto") bolha.textContent += dados.pedaco;   // textContent, nunca innerHTML
}
// botão parar: controlador.abort()

Segurança do front

  • A chave nunca vai ao navegador. Tudo passa pelo back-end, que também fixa o prompt de sistema e o modelo.
  • textContent, não innerHTML: a resposta do modelo pode conter <img onerror=…>, por injeção ou por acaso. Para renderizar Markdown, use uma biblioteca com sanitização.
  • Política de segurança de conteúdo (Content-Security-Policy: default-src 'self'): mesmo que algo escape, scripts de fora não rodam. Por isso o app não tem nenhum script ou estilo inline.
  • Validação e limites no servidor: tamanho das mensagens, número de turnos, requisições por minuto por IP.

Quiz rápido

O usuário fecha a aba no meio de uma resposta em streaming. O que o servidor deve fazer?

Cancelar a requisição ao provedor quando a conexão cai evita custo e carga sem benefício.

8.3 Visão: fotos, telas e documentos

Leitura + labs · 4h

Modelos multimodais leem imagens e PDFs diretamente: notas fiscais, etiquetas, prints de erro, gráficos, contratos. Não é preciso OCR separado, e o modelo entende layout e contexto.

LAB 8.3 — Foto de cupom e contrato em PDF

python python/01_visao.py      # foto torta e borrada (dados/cupom.jpg) → JSON validado
python python/02_pdf.py        # contrato em PDF → resposta com citação de página
  1. Tire uma foto de um cupom real seu (cubra dados pessoais) e rode o lab. Compare o campo legibilidade com a realidade.
  2. Reduza a foto para 400 px de largura e rode de novo. O que acontece com os tokens e com a precisão?
  3. No PDF, pergunte algo que o contrato não diz. O modelo admite?

Boas práticas

  • Imagem antes do texto na mensagem.
  • Resolução: imagens custam tokens proporcionais ao tamanho. Redimensione no cliente antes de enviar; muito pequena perde detalhe.
  • Confira o tipo real do arquivo, não só a extensão: o servidor do projeto checa os primeiros bytes (assinatura) e recusa um "PNG" que é texto.
  • Dados sensíveis aparecem em fotos (documentos, rostos, cartões). Peça ao modelo para sinalizar e defina retenção curta.
  • Peça legibilidade e confiança na saída: fotos ruins são a maior causa de erro.

Quiz rápido

Onde deve ficar a chave de API num app que analisa fotos enviadas pelo navegador?

Qualquer coisa enviada ao navegador pode ser lida. O back-end valida a imagem (tipo real, tamanho) e só ele chama o modelo.

8.4 Áudio e voz

Leitura · 2h
PeçaOpçõesCuidados
Fala → texto (STT)APIs de transcrição (Whisper e similares, provedores de nuvem); Web Speech API do navegadorSotaques, ruído, nomes próprios; latência
Texto → fala (TTS)APIs de voz neural; speechSynthesis do navegadorLeia respostas curtas; listas e tabelas não funcionam em voz
Agentes de voz em tempo realAPIs de áudio em tempo real dos provedores, WebRTCInterrupções ("barge-in"), latência abaixo de ~1 s, custo por minuto

O app do projeto usa a Web Speech API como melhoria progressiva: o botão de microfone só aparece se o navegador suportar, e o usuário pode sempre digitar. Voz muda o design das respostas: frases curtas, sem formatação visual, confirmação falada antes de ações.

8.5 ML rodando no navegador

Leitura · 2h

Nem tudo precisa de um LLM na nuvem. Modelos pequenos rodam no próprio navegador (WebAssembly e WebGPU), sem custo por chamada e sem os dados saírem do dispositivo: classificação de sentimento, detecção de idioma, embeddings para busca local, detecção de objetos e pose em vídeo.

// Transformers.js: o modelo é baixado uma vez e fica em cache no navegador
import { pipeline } from "https://cdn.jsdelivr.net/npm/@huggingface/[email protected]";
const classificar = await pipeline("sentiment-analysis", "Xenova/bert-base-multilingual-uncased-sentiment");
console.log(await classificar("O produto chegou rápido e funciona muito bem!"));
  • Bibliotecas: Transformers.js (modelos do Hugging Face), TensorFlow.js, ONNX Runtime Web, MediaPipe (visão em tempo real).
  • Quando faz sentido: privacidade, uso offline, latência mínima, altíssimo volume de tarefas simples.
  • Custos escondidos: download do modelo (dezenas a centenas de MB), bateria, desempenho desigual entre aparelhos.
  • Padrão híbrido: filtro ou classificação no navegador, LLM na nuvem só quando necessário.

8.6 Prototipação e design assistidos por IA

Leitura · 2h
  • Texto → interface: ferramentas geram telas a partir de descrição. Ótimas para explorar alternativas rápido; o resultado é ponto de partida, não produto.
  • Design → código: de um arquivo de design ou de um print para componentes. Funciona melhor com um design system definido (cores, espaçamentos, componentes), que você passa como contexto.
  • Agentes de código no front (Módulo 7): o arquivo de contexto deve trazer os componentes existentes e as regras de acessibilidade, para o agente reaproveitar em vez de inventar.
  • Revise o que a IA esquece: estados vazios, de erro e de carregamento; teclado; contraste; textos longos; telas pequenas.

8.7 Testes de ponta a ponta

Leitura + prática · 3h

O test/e2e.test.ts abre um Chromium de verdade com Playwright, digita uma pergunta, espera o texto chegar em streaming, clica em "parar", envia uma imagem e confere a tabela de resultado. A API é falsa (test/api-falsa.ts imita até os eventos SSE), então o teste é rápido, gratuito e determinístico, e falha se houver qualquer erro no console, inclusive violações da política de segurança.

await pagina.fill("#entrada", "Qual o prazo para o interior de MG?");
await pagina.keyboard.press("Enter");
await pagina.locator(".msg.assistant").getByText("4 a 7 dias úteis").waitFor();
await pagina.locator("#parar").click();
assert.deepEqual(erros, [], "sem erros no console");

Agentes também podem testar interfaces: um agente com ferramentas de navegador explora o app como um usuário e relata problemas. É um complemento útil (acha o que você não pensou em testar), mas não substitui testes determinísticos no CI.

Projeto do módulo: assistente multimodal

Projeto · 10h · TypeScript + HTML/CSS/JS
ArquivoResponsabilidade
src/servidor.tsProxy da API: chat em SSE com cancelamento, análise de imagem estruturada, validação, limite por IP, checagem de assinatura de arquivo, CSP, proteção contra ../
public/Interface sem framework: streaming, parar, estados, voz progressiva, upload com prévia e limite de tamanho
test/servidor.test.ts9 testes do servidor com API falsa (inclusive SSE)
test/e2e.test.tsTeste no navegador com Playwright

Os testes acharam três bugs reais durante a construção: uma lista vazia de mensagens derrubava a validação com erro 500, imagens SVG recebiam o código de erro errado, e um upload grande demais deixava a conexão num estado que quebrava a requisição seguinte. Os três estão corrigidos e cobertos.

Entregáveis

  1. Renderize Markdown nas respostas com uma biblioteca de sanitização e prove com um teste que <img src=x onerror=alert(1)> não executa.
  2. Adicione citações clicáveis usando o RAG do Módulo 4 como fonte.
  3. Redimensione imagens no navegador (canvas) antes do envio e meça a economia de tokens.
  4. Adicione histórico persistente por usuário (no servidor) com opção de apagar.
  5. Faça um teste de acessibilidade (navegação só por teclado e leitor de tela) e corrija o que achar.

Critérios de avaliação

CritérioPeso
Markdown seguro com teste de XSS25%
Citações integradas ao RAG20%
Redimensionamento com medição15%
Histórico persistente com exclusão20%
Acessibilidade20%

Recursos para aprofundar

Todos gratuitos