Transcrever ligações de atendimento: o que dá certo e o que não dá
Ligação gravada é o áudio mais previsível que existe: duas vozes, um assunto, sempre o mesmo formato. Isso muda o que vale pedir para a API e o que vale conferir no resultado.
Ligação de suporte é um áudio bem-comportado. Duas pessoas, um assunto, duração entre três e vinte minutos, gravação sempre do mesmo jeito. Isso é uma vantagem grande: o pipeline que funciona na primeira ligação funciona nas próximas cem mil sem ajuste.
O que muda de um acervo de gravações para outro é uma decisão tomada antes da API: se o gravador guarda os dois lados separados ou misturados.
Duas faixas resolvem o problema mais difícil
Se a sua gravação tem o agente num canal e o cliente no outro, você não precisa de diarização. Separe os canais e transcreva cada um. A atribuição fica exata, por construção, e nenhum algoritmo pode competir com isso.
ffmpeg -i ligacao.wav -map_channel 0.0.0 agente.wav -map_channel 0.0.1 cliente.wavDuas transcrições de uma ligação de dez minutos custam o mesmo que uma de vinte,
porque a cobrança é por hora de áudio processada: US$ 0,03 por hora, sem o
adicional de speakers. Sai mais barato que a mesma ligação com separação
automática, e acerta mais.
Para juntar as duas na ordem certa, os timestamps de palavra são a chave: as duas transcrições compartilham o mesmo relógio, que é o começo do arquivo.
const turnos = [...agente.words.map((w) => ({ ...w, lado: "agente" })), ...cliente.words.map((w) => ({ ...w, lado: "cliente" }))].sort(
(a, b) => a.start - b.start,
);O erro mediano do timestamp fica entre 69 e 86 ms, então a intercalação sai na ordem certa mesmo em resposta rápida.
Uma faixa só, com speakers: 2
Quando a gravação vem misturada, aí sim é caso de diarização:
curl https://api.transcrevo.com/v1/transcripts \
-H "Authorization: Bearer $TRANSCREVO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"uploadId": "0f3c2d11-8a4b-4c6e-b2d9-5e7f1a9c3b42",
"speakers": 2,
"language": "pt",
"webhookUrl": "https://seu-servidor.com/hooks/transcrevo"
}'Aqui informar a contagem é seguro, porque numa ligação você sabe mesmo: são
dois. Esse é um dos poucos casos em que dar o número exato é claramente melhor
que deixar true decidir.
Os rótulos continuam anônimos: "A" e "B" são a primeira e a segunda voz.
Descobrir qual é o agente costuma ser trivial na prática, porque quem abre a
ligação com a saudação padrão é sempre o mesmo lado.
Onde erra, e por que importa mais aqui
Ligação de atendimento é feita de turno curto. "Pois não", "só um momento", "uhum", "isso mesmo", "consegue confirmar o CPF". E turno curto é exatamente onde a separação de falantes é pior:
| Turno | Acerto de locutor |
|---|---|
| Acima de 15 segundos | 95 a 99% |
| Abaixo de 5 segundos | 59 a 75% |
Somado a isso, fala sobreposta tem DER de 14,8%, contra 4,6% no geral. Cliente irritado falando por cima do agente é o caso mais comum de sobreposição num acervo de suporte.
A consequência prática:
- Ler a ligação funciona. Explicação do problema, resposta do agente, encaminhamento: são blocos longos, e a atribuição acerta.
- Contar comportamento não funciona. Quantas vezes o agente interrompeu, quanto tempo cada lado ocupou, quem falou mais: essas métricas vivem do turno de dois segundos, e é ali que o acerto cai para dois terços. Se a sua avaliação de qualidade depende disso, o caminho é gravar em duas faixas, não escolher outro algoritmo.
Os números completos, com a metodologia, estão em precisão e qualidade, e o que a separação faz e não faz está em o que é diarização.
O glossário monta sozinho
Suporte é o caso em que o glossário por requisição rende mais, porque você já sabe do que a ligação vai tratar: o nome do cliente está no ticket, o do produto está no cadastro, as siglas internas são fixas.
{
"uploadId": "0f3c2d11-…",
"glossary": { "bertual": "Bertuol", "essetá": "SST", "plano prata": "Plano Prata" }
}Até 100 entradas por requisição, aplicadas só naquele áudio. Nome próprio e sigla são o erro mais comum de qualquer transcrição, e num acervo de suporte eles são justamente o que a busca vai procurar depois. Os detalhes estão em como corrigir nome próprio errado.
O que a API não faz
Ela devolve texto com timestamps e, se você pedir, rótulo de falante. Não devolve resumo, sentimento, tema, nota de qualidade nem alerta de palavra proibida. Isso não é omissão de roadmap: é onde a linha foi traçada. O texto é o insumo, e a análise em cima dele é decisão do seu produto.
Também não existe transcrição ao vivo. O processamento é assíncrono: você cria, ela roda, e você recebe por consulta ou webhook. Supervisor acompanhando a ligação em tempo real não é um caso atendido por esta API.
Volume, retenção e a conta
Um centro de atendimento médio gera bastante áudio, então três coisas operacionais importam mais que no caso avulso.
O saldo. Sem crédito, novas transcrições são recusadas com
402 insufficient_balance e a fila para. Monitore available (que já desconta o
que as transcrições em voo seguraram, não o total) ou ligue a recarga
automática no painel.
Os tetos. 120 criações de transcrição por minuto. Um lote noturno destravando
de uma vez encosta nisso; espalhe pela espera do Retry-After em vez de tentar
de novo na hora.
A retenção. DELETE /v1/transcripts/{id} apaga o texto, as palavras e o
áudio guardado. O registro de uso continua, porque é dele que sai a fatura, mas o
conteúdo some e não tem como recuperar. Numa política de retenção de 90 dias, é
um cron.
A conta: 1.000 horas de ligação custam US$ 30 sem separação de falantes e US$ 50 com. Acima de 10.000 horas transcritas pela conta, a tarifa cai sozinha para US$ 0,02. A tabela inteira está em preços e limites.