Голосовой ассистент на LangChain, Ollama и Whisper: полный гайд | AiManual
AiManual Logo Ai / Manual.
29 Дек 2025 Гайд

Как собрать голосового ассистента на LangChain, Ollama и Whisper: пошаговый гайд

Пошаговое руководство по созданию локального голосового агента на LangChain, Ollama и Whisper. Установка, настройка, код и практические примеры.

Почему локальный голосовой ассистент — это будущее?

Представьте себе голосового помощника, который работает полностью на вашем компьютере, не отправляет ваши данные в облако, работает без интернета и может быть настроен под ваши конкретные задачи. Это не фантастика — это реальность, которую можно собрать сегодня с помощью трёх ключевых технологий: LangChain для управления контекстом и цепочками, Ollama для запуска локальных языковых моделей и Whisper для преобразования речи в текст.

Главное преимущество локального решения — приватность. Ваши разговоры, вопросы и контекст никогда не покидают ваш компьютер. Это критически важно для бизнес-приложений, медицинских консультаций или просто личных бесед.

Архитектура решения: как всё работает вместе

Прежде чем переходить к коду, давайте разберёмся с архитектурой нашего голосового ассистента:

КомпонентРольАльтернативы
Whisper (OpenAI)Распознавание речи (STT)Vosk, Silero
OllamaЗапуск LLM локальноLM Studio, llama.cpp
LangChainОркестрация и контекстSemantic Kernel, Haystack
pyttsx3 / gTTSСинтез речи (TTS)Coqui TTS, Piper

Рабочий процесс выглядит так: вы говорите → Whisper преобразует речь в текст → LangChain обрабатывает запрос с контекстом → Ollama генерирует ответ → система преобразует текст в речь.

1Подготовка окружения и установка зависимостей

Начнём с создания чистого Python-окружения и установки всех необходимых пакетов. Рекомендую использовать Python 3.10 или выше.

# Создаём виртуальное окружение
python -m venv voice_assistant_env
source voice_assistant_env/bin/activate  # Linux/Mac
# или
voice_assistant_env\Scripts\activate     # Windows

# Устанавливаем основные зависимости
pip install langchain langchain-community
pip install openai-whisper
pip install pyaudio  # для захвата аудио с микрофона
pip install pyttsx3  # для синтеза речи (оффлайн)
# или pip install gtts  # для онлайн синтеза через Google
pip install sounddevice soundfile  # для работы с аудио

Внимание: установка pyaudio на некоторых системах может требовать дополнительных зависимостей. На Ubuntu/Debian: sudo apt-get install portaudio19-dev python3-pyaudio. На macOS: brew install portaudio.

2Установка и настройка Ollama

Ollama — это инструмент для запуска больших языковых моделей локально. Он поддерживает множество моделей, включая Llama 2, Mistral, CodeLlama и другие.

# Установка Ollama (Linux/Mac)
curl -fsSL https://ollama.com/install.sh | sh

# Запуск Ollama сервера
ollama serve &

# Скачиваем модель (например, Mistral 7B)
ollama pull mistral

# Проверяем работу
ollama run mistral "Привет! Как дела?"

Для Windows скачайте установщик с официального сайта. После установки модель будет доступна через локальный API на порту 11434.

💡
Выбор модели зависит от ваших ресурсов. Mistral 7B требует ~8GB RAM, Llama 2 7B — примерно столько же. Для слабых компьютеров можно использовать TinyLlama (1.1B) или Phi-2 (2.7B).

3Создание базового голосового ассистента

Теперь соберём все компоненты в единый скрипт. Создадим файл voice_assistant.py:

import whisper
import pyttsx3
import sounddevice as sd
import soundfile as sf
import numpy as np
from langchain.llms import Ollama
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
import tempfile
import os

class VoiceAssistant:
    def __init__(self, model_name="mistral"):
        # Инициализация Whisper для распознавания речи
        print("Загрузка модели Whisper...")
        self.stt_model = whisper.load_model("base")  # base, small, medium, large
        
        # Инициализация синтеза речи
        print("Инициализация TTS...")
        self.tts_engine = pyttsx3.init()
        self.tts_engine.setProperty('rate', 150)  # Скорость речи
        self.tts_engine.setProperty('volume', 0.9)  # Громкость
        
        # Инициализация LangChain с Ollama
        print(f"Подключение к модели {model_name}...")
        self.llm = Ollama(model=model_name, base_url="http://localhost:11434")
        
        # Память для контекста диалога
        self.memory = ConversationBufferMemory()
        self.conversation = ConversationChain(
            llm=self.llm,
            memory=self.memory,
            verbose=True
        )
        
        # Настройки аудио
        self.sample_rate = 16000
        self.duration = 5  # секунд записи
        
    def record_audio(self):
        """Запись аудио с микрофона"""
        print("Говорите сейчас...")
        audio = sd.rec(
            int(self.duration * self.sample_rate),
            samplerate=self.sample_rate,
            channels=1,
            dtype='float32'
        )
        sd.wait()
        print("Запись завершена")
        return audio.flatten()
    
    def speech_to_text(self, audio_data):
        """Преобразование речи в текст с помощью Whisper"""
        # Сохраняем временный файл
        with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp_file:
            sf.write(tmp_file.name, audio_data, self.sample_rate)
            
            # Транскрибация
            result = self.stt_model.transcribe(tmp_file.name, language="ru")
            
        os.unlink(tmp_file.name)
        return result["text"]
    
    def process_query(self, text):
        """Обработка запроса через LangChain и Ollama"""
        response = self.conversation.predict(input=text)
        return response
    
    def text_to_speech(self, text):
        """Преобразование текста в речь"""
        self.tts_engine.say(text)
        self.tts_engine.runAndWait()
    
    def run(self):
        """Основной цикл ассистента"""
        print("Голосовой ассистент запущен. Скажите 'стоп' для выхода.")
        
        while True:
            try:
                # Шаг 1: Запись аудио
                audio = self.record_audio()
                
                # Шаг 2: Преобразование в текст
                text = self.speech_to_text(audio)
                print(f"Вы сказали: {text}")
                
                if text.lower().strip() in ['стоп', 'stop', 'выход', 'exit']:
                    print("Завершение работы...")
                    break
                
                if not text.strip():
                    print("Речь не распознана, попробуйте снова")
                    continue
                
                # Шаг 3: Обработка запроса
                print("Обработка запроса...")
                response = self.process_query(text)
                print(f"Ассистент: {response}")
                
                # Шаг 4: Озвучивание ответа
                self.text_to_speech(response)
                
            except KeyboardInterrupt:
                print("\nПрервано пользователем")
                break
            except Exception as e:
                print(f"Ошибка: {e}")
                continue

if __name__ == "__main__":
    # Создаём ассистента с моделью mistral
    assistant = VoiceAssistant(model_name="mistral")
    assistant.run()

4Расширение функциональности: RAG и инструменты

Базовый ассистент уже работает, но его можно значительно улучшить. Добавим Retrieval-Augmented Generation (RAG) для работы с вашими документами и инструменты для выполнения действий.

from langchain.embeddings import OllamaEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.document_loaders import TextLoader, DirectoryLoader
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType

class AdvancedVoiceAssistant(VoiceAssistant):
    def __init__(self, model_name="mistral", docs_path="./docs"):
        super().__init__(model_name)
        
        # Загрузка и индексация документов для RAG
        self.setup_rag(docs_path)
        
        # Создание агента с инструментами
        self.setup_agent()
    
    def setup_rag(self, docs_path):
        """Настройка RAG системы"""
        if os.path.exists(docs_path):
            print("Загрузка документов для RAG...")
            loader = DirectoryLoader(docs_path, glob="**/*.txt")
            documents = loader.load()
            
            text_splitter = RecursiveCharacterTextSplitter(
                chunk_size=1000,
                chunk_overlap=200
            )
            texts = text_splitter.split_documents(documents)
            
            # Создание векторной базы
            embeddings = OllamaEmbeddings(
                model=model_name,
                base_url="http://localhost:11434"
            )
            self.vectorstore = Chroma.from_documents(
                documents=texts,
                embedding=embeddings
            )
            self.retriever = self.vectorstore.as_retriever()
    
    def search_documents(self, query):
        """Поиск в документах"""
        if hasattr(self, 'retriever'):
            docs = self.retriever.get_relevant_documents(query)
            return "\n".join([doc.page_content[:500] for doc in docs[:3]])
        return "Документы не загружены"
    
    def setup_agent(self):
        """Настройка агента с инструментами"""
        tools = [
            Tool(
                name="Document Search",
                func=self.search_documents,
                description="Поиск информации в ваших документах"
            ),
            Tool(
                name="Calculator",
                func=lambda x: str(eval(x)),
                description="Выполнение математических вычислений"
            )
        ]
        
        self.agent = initialize_agent(
            tools,
            self.llm,
            agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
            verbose=True,
            memory=self.memory
        )
    
    def process_query(self, text):
        """Обработка запроса через агента"""
        return self.agent.run(text)
💡
RAG позволяет ассистенту работать с вашими личными документами, PDF-файлами, заметками. Это превращает его из простого чат-бота в персонального эксперта по вашим данным.

Оптимизация и улучшение производительности

Локальный ассистент может работать медленно, особенно на слабом железе. Вот ключевые оптимизации:

  • Используйте меньшие модели Whisper: base или small вместо medium/large
  • Квантование моделей Ollama: ollama pull mistral:7b-q4_K_M — q4 версии в 2 раза меньше
  • Кэширование эмбеддингов: сохраняйте векторную базу на диск
  • Асинхронная обработка: используйте asyncio для параллельной работы компонентов

Возможные ошибки и их решение

ОшибкаПричинаРешение
CUDA out of memoryНе хватает видеопамятиИспользуйте меньшую модель, увеличьте swap
Portaudio errorПроблемы с микрофономПроверьте доступность микрофона в системе
Ollama connection refusedСервер Ollama не запущенЗапустите ollama serve в отдельном терминале
Whisper не распознаёт русскийЯзык не указанДобавьте параметр language="ru" в transcribe()

Практические применения и развитие проекта

Ваш голосовой ассистент может стать основой для множества полезных приложений:

  1. Персональный секретарь: управление календарём, напоминаниями, заметками
  2. Образовательный помощник: объяснение сложных тем, проверка знаний
  3. Техническая поддержка: ответы на вопросы по документации, как в статье про Multi-modal RAG
  4. Голосовой интерфейс для DevOps: управление инфраструктурой голосом, как в DevOps для ИИ

Для дальнейшего развития рекомендую изучить бесплатный курс по AI-агентам, где подробно разбираются продвинутые техники.

Совет: начните с простой версии, убедитесь, что все компоненты работают, и только потом добавляйте сложные функции вроде RAG или интеграции с внешними API.

Заключение

Вы создали полностью локального голосового ассистента, который не уступает по функциональности облачным решениям, но при этом гарантирует приватность ваших данных. Комбинация LangChain, Ollama и Whisper открывает огромные возможности для создания специализированных голосовых интерфейсов — от персональных помощников до корпоративных экспертных систем.

Экспериментируйте с разными моделями, добавляйте свои инструменты, интегрируйте с другими системами. И помните: лучший ассистент — тот, который решает именно ваши задачи.