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.