DEV Community

Transcrevendo áudio e gerando capítulos com IA (Whisper + GPT) sem estourar o custo

Semana dessas caí num problema que parecia trivial e não era: pegar um áudio longo, tipo um episódio de podcast, e gerar os capítulos sozinho - aqueles "00:00 Intro", "04:12 fulano fala sobre X". Com IA, e sem tomar um susto na fatura da OpenAI no fim do mês.

Trabalho com full stack e esse tipo de automação com IA acabou virando parte da rotina. Como quebrei a cabeça um tempo até achar um caminho que funciona e sai barato, achei que valia escrever.

O que precisa acontecer

Basicamente três etapas:

  • transcrever o áudio, mas com os tempos de cada trecho
  • transformar essa transcrição em capítulos que façam sentido
  • e fazer isso sem gastar uma fortuna, porque áudio longo vira um caminhão de token

Transcrição com o Whisper

A parte que muita gente erra é essa: dá pra pedir a transcrição já com os timestamps por segmento, usando verbose_json. Assim o Whisper te entrega onde cada fala começa e termina, e você não precisa pedir pro GPT "chutar" os minutos depois (spoiler: ele chuta mal).

import OpenAI from "openai";
import fs from "node:fs";

const openai = new OpenAI();

const transcription = await openai.audio.transcriptions.create({
  file: fs.createReadStream("episodio.mp3"),
  model: "whisper-1",
  response_format: "verbose_json",
  timestamp_granularities: ["segment"],
});

// transcription.segments -> [{ start, end, text }, ...]

Gerando os capítulos com o GPT

Aqui tem uma tentação que sai caro: mandar a transcrição inteira, palavra por palavra, pro modelo. Não faça isso. O que eu faço é condensar antes: pra cada segmento, mando só o timestamp e o comecinho do texto. É o suficiente pro modelo entender onde o assunto muda, e corta um monte de token.

const resumoSegmentos = transcription.segments
  .map((s) => `[${formatTime(s.start)}] ${s.text.slice(0, 120)}`)
  .join("\n");

const res = await openai.chat.completions.create({
  model: "gpt-4o-mini",
  response_format: { type: "json_object" },
  messages: [
    {
      role: "user",
      content: `Gere de 5 a 8 capítulos a partir da transcrição com tempos. Responda em JSON: { "capitulos": [{ "inicio": "mm:ss", "titulo": "..." }] }. Transcrição: ${resumoSegmentos}`,
    },
  ],
});

const { capitulos } = JSON.parse(res.choices[0].message.content);

Duas coisas que me pouparam dor de cabeça: usar response_format: { type: "json_object" }, que garante um JSON válido de volta (nada de ficar limpando texto solto com regex), e deixar o Whisper cuidar dos tempos enquanto o GPT cuida só dos títulos. Cada um no que faz bem.

Onde o custo realmente cai

Quando fui olhar a conta, o que pesava não era o "modelo caro", era eu mandando contexto demais. O que mudou o jogo:

  • Escolher o modelo pela tarefa. Titular capítulo não precisa do modelo topo de linha; um "mini" resolve por uma fração do preço.
  • Resumir os segmentos antes de enviar, como mostrei ali em cima.
  • Cachear a transcrição. O áudio não muda depois de transcrito, então guardo o resultado. Se eu quiser regerar os capítulos, roda só a parte barata.

Resumindo

No fim, IA "cara" quase sempre é IA mal orquestrada. Boa parte do custo tá em quanto contexto você joga pro modelo, não só em qual modelo você usa. E combinar ferramentas pelo forte de cada uma (Whisper pro tempo, GPT pra linguagem) deixa o resultado bem mais previsível do que tentar fazer um só modelo dar conta de tudo.

Se quiser dar uma olhada em outras coisas que já construí - tem umas demos de sistemas pra abrir e testar - meu portfólio tá aqui: https://felipegazolla.dev

Comments

No comments yet. Start the discussion.