Телеграм-бот, который пересказывает голосовые
Мой пет-проект: бот, который слушает голосовое сообщение, расшифровывает его локально через Whisper и присылает короткую выжимку через Gemini.
Голосовые сообщения я недолюбливаю. Кто-то присылает три минуты потока сознания, а ты сиди и слушай, чтобы выловить одну важную фразу. В какой-то момент мне это надоело, и я написал бота, который делает это за меня: отправляешь ему аудио, получаешь короткий пересказ текстом.
Бот живёт в Telegram под именем @audiosumbot. Проект крошечный — один файл на сто с небольшим строк Python, — но внутри происходит кое-что интересное, о чём хочется рассказать.
Что он делает
Логика простая. Вы отправляете боту голосовое или аудиофайл. Он скачивает его, прогоняет через распознавание речи, чистит расшифровку и присылает выжимку с основными тезисами. Само аудио после обработки удаляется с диска.
Стек
Зависимостей всего четыре, и это сознательно:
pyTelegramBotAPI— общение с Telegram. Бот работает на long polling, без вебхуков, так что белый IP и HTTPS-эндпоинт не нужны.openai-whisper— распознавание речи. Модельbaseкрутится прямо на машине, без обращений к чужому API.google-generativeai— Gemini 1.5 Pro, который чистит текст и делает выжимку. Версию взял именно 1.5: она ест заметно меньше ресурсов, а для чистки расшифровки и короткой выжимки её с головой хватает.python-dotenv— читает токен и ключ из.env.
Отдельно стоит сказать про ffmpeg. В зависимостях его нет, потому что это системный пакет, но без него Whisper не сможет раскодировать аудио. Я споткнулся об это на пустом сервере, так что упомяну заранее.
Распознавание локальное, а суммаризация — в облаке. Расшифровка остаётся приватной и ничего не стоит, а тяжёлую языковую работу берёт на себя Gemini. Модель Whisper я загружаю один раз при старте и переиспользую — иначе каждое сообщение ждало бы загрузку модели заново.
Раз распознавание идёт на самой машине, есть смысл запускать бота не на дешёвом VPS, а дома. Домашний макбук обычно в разы мощнее бюджетной виртуалки, а значит, потянет модель Whisper покрупнее — а чем крупнее модель, тем точнее она разбирает речь. Я в коде оставил base как компромисс, но если поднимаете у себя на нормальном железе — смело берите модель побольше, расшифровка станет заметно чище.
Как устроена обработка
Самое любопытное здесь — что бот гоняет текст через Gemini дважды.
Сначала Whisper выдаёт сырую расшифровку. Распознавание речи ошибается: путает слова, теряет знаки препинания, иногда выдаёт бессвязицу там, где человек говорил невнятно. Если скормить такой текст в суммаризацию напрямую, выжимка унаследует все эти огрехи.
Поэтому первый запрос к Gemini — это не «сделай выжимку», а «почини». Модель просят исправить грамматику и восстановить логику, ничего не добавляя от себя. И только потом, уже по вычищенному тексту, идёт второй запрос — собственно выжимка с тезисами.
Весь путь сообщения выглядит так:
голосовое → Telegram скачивает файл → временный файл на диске
│
▼
Whisper "base" (локально, язык — русский)
│
▼
Gemini 1.5 Pro — чистка расшифровки
│
▼
Gemini 1.5 Pro — выжимка с тезисами
│
▼
ответ пользователю → файл удаляется
Пока идёт обработка, бот сразу присылает примерную оценку времени — берёт длительность аудио и умножает на два. Прикидка грубая, но ожидание молча раздражает сильнее, чем неточный таймер.
Удаление временного файла я завернул в finally, так что он стирается даже если что-то упало в середине. Мелочь, но без неё диск со временем забьётся обрезками чужих голосовых.
Как пользоваться
- Открыть чат с @audiosumbot и нажать
/start. - Отправить аудио. Можно записать голосовое прямо в чате, переслать чужое, скинуть запись с диктофона или загрузить файл документом в форматах
.m4a,.mp3,.wavили.ogg. - Дождаться ответа. Бот напишет, что принял аудио, потом что обрабатывает текст, и в конце пришлёт краткий отчёт.
Одна важная оговорка: язык распознавания зашит русским. На английской или другой речи Whisper выдаст кашу, и выжимка получится бесполезной. Это бот для русскоязычных голосовых, и переучивать его на лету я пока не стал.
Чего тут осознанно нет
Это пет-проект, и я не делал вид, что строю продакшен. Бот однопоточный: пока он расшифровывает одно сообщение, остальные ждут в очереди. Нет ограничения на длину аудио, нет Docker-образа, зависимости не запинены по версиям. Для личного использования и пары друзей этого хватает с запасом, а городить очереди и автоскейлинг ради бота, который слушает мои же голосовые, — пустая трата вечера.
Если хочется покопаться в коде или поднять свою копию — он весь тут, целиком в одном файле: