Как создать голосового ассистента с Whisper и GPT

Пошаговое руководство по созданию голосового ассистента на Python — Whisper для распознавания, GPT для ответов, TTS для озвучки.

Как создать голосового ассистента с Whisper и GPT

Голосовые ассистенты перестали быть монополией крупных корпораций. С помощью трёх компонентов — Whisper для распознавания речи, GPT для генерации ответов и TTS для синтеза голоса — можно собрать собственного ассистента за один вечер. Весь пайплайн работает на Python и может использовать как облачные API, так и локальные модели.

Архитектура

Голосовой ассистент — это цепочка из трёх этапов. Первый — STT (speech-to-text): микрофон записывает голос, Whisper превращает аудио в текст. Второй — LLM: текстовый запрос уходит в GPT или другую языковую модель, возвращается текстовый ответ. Третий — TTS (text-to-speech): текст ответа озвучивается синтезатором речи. Подробнее о технологиях распознавания и синтеза — в нашем обзоре голосового ИИ.

Задержка пайплайна складывается из трёх компонентов. На облачных API: Whisper — 1–2 сек, GPT — 1–3 сек, TTS — 0.5–1 сек. Итого 3–6 секунд от конца фразы до начала ответа. Для диалога — приемлемо, хотя и заметно.

Установка зависимостей

pip install openai pyaudio numpy sounddevice

Для записи с микрофона на Linux может потребоваться portaudio: sudo apt install portaudio19-dev. На macOS: brew install portaudio.

Запись голоса с микрофона

Первый шаг — запись аудио. Используем sounddevice с детекцией тишины для автоматической остановки:

import sounddevice as sd
import numpy as np
import wave
import tempfile

def record_audio(silence_threshold=500, silence_duration=1.5, sample_rate=16000):
    """Записывает речь до паузы в silence_duration секунд."""
    print("Говорите...")
    frames = []
    silent_frames = 0
    max_silent = int(silence_duration * sample_rate / 1024)
    
    def callback(indata, frame_count, time_info, status):
        nonlocal silent_frames
        volume = np.abs(indata).mean() * 10000
        frames.append(indata.copy())
        if volume < silence_threshold:
            silent_frames += 1
        else:
            silent_frames = 0
    
    with sd.InputStream(samplerate=sample_rate, channels=1, 
                        blocksize=1024, callback=callback):
        while silent_frames < max_silent or len(frames) < 10:
            sd.sleep(100)
    
    audio = np.concatenate(frames)
    tmp = tempfile.NamedTemporaryFile(suffix=".wav", delete=False)
    with wave.open(tmp.name, "wb") as wf:
        wf.setnchannels(1)
        wf.setsampwidth(2)
        wf.setframerate(sample_rate)
        wf.writeframes((audio * 32767).astype(np.int16).tobytes())
    return tmp.name

Распознавание через Whisper API

OpenAI предоставляет Whisper API, который распознаёт русскую речь с высокой точностью:

from openai import OpenAI

client = OpenAI()

def transcribe(audio_path):
    with open(audio_path, "rb") as f:
        result = client.audio.transcriptions.create(
            model="whisper-1",
            file=f,
            language="ru"
        )
    return result.text

Стоимость — $0.006 за минуту аудио. Для локального варианта установите faster-whisper — он работает в 4 раза быстрее оригинального Whisper и не требует GPU для модели small.

Генерация ответа через GPT

Текст от Whisper отправляется в языковую модель. Системный промпт задаёт характер ассистента:

conversation = []

SYSTEM = """Ты — голосовой ассистент. Отвечай кратко — 1-3 предложения. 
Твои ответы будут озвучены, поэтому не используй markdown, 
списки и специальные символы."""

def get_response(user_text):
    conversation.append({"role": "user", "content": user_text})
    
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "system", "content": SYSTEM}] + conversation[-10:],
        max_tokens=150
    )
    
    reply = response.choices[0].message.content
    conversation.append({"role": "assistant", "content": reply})
    return reply

Указание max_tokens=150 ограничивает длину ответа — для голосового ассистента важна краткость. Длинные ответы утомительно слушать. Подробнее о настройке промптов — в гайде по промпт-инжинирингу.

Синтез речи через TTS

OpenAI TTS генерирует реалистичную русскую речь:

import subprocess

def speak(text):
    response = client.audio.speech.create(
        model="tts-1",
        voice="nova",  # alloy, echo, fable, onyx, nova, shimmer
        input=text
    )
    tmp = tempfile.NamedTemporaryFile(suffix=".mp3", delete=False)
    response.stream_to_file(tmp.name)
    subprocess.run(["afplay", tmp.name])  # macOS
    # subprocess.run(["mpv", tmp.name])   # Linux

Голос nova хорошо работает с русским текстом. Стоимость — $0.015 за 1000 символов (модель tts-1) или $0.030 (tts-1-hd с улучшенным качеством).

Собираем всё вместе

def main():
    print("Голосовой ассистент запущен. Ctrl+C для выхода.")
    while True:
        try:
            audio_path = record_audio()
            text = transcribe(audio_path)
            print(f"Вы: {text}")
            
            if text.strip().lower() in ["стоп", "выход", "пока"]:
                speak("До свидания!")
                break
            
            reply = get_response(text)
            print(f"Ассистент: {reply}")
            speak(reply)
        except KeyboardInterrupt:
            break

if __name__ == "__main__":
    main()

Локальный вариант без облака

Для полностью локальной работы замените три компонента: Whisper API → faster-whisper (модель small, 460 МБ), GPT → Ollama с Llama 3.1 8B, TTS → piper-tts (офлайн-синтез на русском). Качество будет ниже, но данные не покидают устройство, и не нужна подписка.

Расширения

Базовый ассистент можно развить: добавить распознавание команд («поставь таймер», «включи музыку»), подключить к умному дому через Home Assistant API, интегрировать с календарём и почтой. Каждое расширение — отдельный инструмент в системном промпте, который GPT вызывает по контексту запроса. Принцип работы таких ИИ-агентов мы разбирали отдельно.

Технический стек голосового ассистента

Современный голосовой ассистент на базе LLM состоит из трёх компонентов: распознавание речи (ASR), языковая модель (LLM), синтез речи (TTS). Комбинация Whisper + GPT-4o + ElevenLabs даёт качество, сопоставимое с коммерческими ассистентами, при полном контроле над данными.

Сравнение ASR-движков

ДвижокWER (русский)СкоростьЦенаОфлайн
Whisper Large v3~5%~0.5x realtime$0.006/мин (API)Да (self-hosted)
Whisper Medium (local)~8%~2x realtimeБесплатноДа
Google Speech-to-Text~4%Realtime$0.009/минНет
Яндекс SpeechKit~4% (RU)Realtime~0.2 ₽/минНет
faster-whisper~5%~4x realtimeБесплатноДа

Оптимизация латентности

Главная проблема pipeline-ассистентов — задержка. Среднее: Whisper ~500мс + LLM ~800мс + TTS ~300мс = ~1.6 сек до первого звука. Методы снижения:

  • Streaming TTS — начинать синтез сразу после первых токенов LLM
  • Whisper Turbo — модель tiny/base для ~150мс ASR
  • GPT-4o Realtime API — нативный voice-to-voice без цепочки, latency ~300мс
  • VAD (Voice Activity Detection) — обрабатывать аудио только когда говорит пользователь

Self-hosted стек для конфиденциальности

Для обработки чувствительных данных: faster-whisper (локальный ASR) + Ollama + Llama 3.1 (локальный LLM) + Silero TTS (локальный TTS). Данные не покидают устройство. Производительность на M2 MacBook Pro: ~2 секунды полного цикла.

Готовые open-source проекты

Home Assistant + Whisper — для умного дома: wake word detection, локальный ASR, локальный LLM, управление устройствами. Полностью офлайн.

LocalAI — единый сервер для LLM, ASR, TTS с OpenAI-совместимым API. Позволяет заменить OpenAI API локальными моделями без изменения кода приложения.

Livekit Agents — фреймворк для production голосовых агентов: pipeline из ASR + LLM + TTS, WebRTC транспорт, масштабирование.