Python: как создать простейшего голосового помощника?
Для создания голосового помощника не нужно обладать большими знаниями в программировании, главное понимать каким функционалом он должен владеть. Многие компании создают их на первой линии связи с клиентом для удобства, оптимизации рабочих процессов и наилучшей классификации звонков.
В данной статье представлена программа, которая может стать основой для Вашего собственного чат-бота, а если точнее – голосового помощника для распознавания голоса и последующего выполнения команд. С ее помощью мы сможем понять принцип работы наиболее часто встречаемых голосовых помощников.
Для начала объявим необходимые нам библиотеки:
Также не забудем вести лог файл, который понадобится нам, если же мы все-таки решим улучшить бота для работы с нейронной сетью. Многие компании использую нейронную сеть в своих голосовых помощниках для понимания эмоций клиента и соответствующего реагирования на них. Также стоит не забывать, что с помощью анализа логов, мы сможем понять слабые места алгоритма бота и улучшить взаимодействие с клиентами.
В лог файл мы записываем время сообщения, автора (бот или пользователь) и собственно сам сказанный текст.
Выводим первое сообщение за авторством бота: Привет! Чем я могу вам помочь?
А с помощью такой процедуры в Jupyter Notebook мы можем озвучить через устройство воспроизведения, настроенное по умолчанию, сказанные слова:
Как озвучивать текст мы рассмотрели выше, но как же мы свой голос сможем превратить в текст? Тут нам поможет распознавание речи от Google и некоторые манипуляции с микрофоном.
Что может сделать наш помощник кроме того, чтобы нас слушать? Все ограничено нашей фантазией! Рассмотрим несколько интересный примеров.
Начнем с простого, пусть при команде открыть сайт – он откроет сайт (не ожидали?).
Иногда полезно послушать свои слова, да чужими устами. Пусть бот еще умеет и повторять за нами:
Пусть еще и собеседником будет, но начнем мы пока только со знакомства:
Мы также можем попросить голосового помощника назвать случайное число в выбранных нами пределах в формате: Назови случайное число от (1ое число) до (2ое число).
Для того, чтобы завершить программу, достаточно только попрощаться с ботом:
Пишем голосового ассистента на Python
Технологии в области машинного обучения за последний год развиваются с потрясающей скоростью. Всё больше компаний делятся своими наработками, тем самым открывая новые возможности для создания умных цифровых помощников.
В рамках данной статьи я хочу поделиться своим опытом реализации голосового ассистента и предложить вам несколько идей для того, чтобы сделать его ещё умнее и полезнее.

Что умеет мой голосовой ассистент?
Описание умения | Работа в offline-режиме | Требуемые зависимости |
Распознавать и синтезировать речь | Поддерживается | pip install PyAudio (использование микрофона) |
pip install pyttsx3 (синтез речи)
Для распознавания речи можно выбрать одну или взять обе:
- pip install SpeechRecognition (высокое качество online-распознавания, множество языков)
- pip install vosk (высокое качество offline-распознавания, меньше языков)
Шаг 1. Обработка голосового ввода
Начнём с того, что научимся обрабатывать голосовой ввод. Нам потребуется микрофон и пара установленных библиотек: PyAudio и SpeechRecognition.
Подготовим основные инструменты для распознавания речи:
Теперь создадим функцию для записи и распознавания речи. Для онлайн-распознавания нам потребуется Google, поскольку он имеет высокое качество распознавания на большом количестве языков.
А что делать, если нет доступа в Интернет? Можно воспользоваться решениями для offline-распознавания. Мне лично безумно понравился проект Vosk.
Теперь, внедрив offline-решение и добавив в проект нужные языковые модели, при отсутствии доступа к сети у нас автоматически будет выполняться переключение на offline-распознавание.
Замечу, что для того, чтобы не нужно было два раза повторять одну и ту же фразу, я решила записывать аудио с микрофона во временный wav-файл, который будет удаляться после каждого распознавания.
Таким образом, полученный код выглядит следующим образом:
Возможно, вы спросите «А зачем поддерживать offline-возможности?»
Я считаю, что всегда стоит учитывать, что пользователь может быть отрезан от сети. В таком случае, голосовой ассистент всё еще может быть полезным, если использовать его как разговорного бота или для решения ряда простых задач, например, посчитать что-то, порекомендовать фильм, помочь сделать выбор кухни, сыграть в игру и т.д.
Шаг 2. Конфигурация голосового ассистента
Поскольку наш голосовой ассистент может иметь пол, язык речи, ну и по классике, имя, то давайте выделим под эти данные отдельный класс, с которым будем работать в дальнейшем.
Для того, чтобы задать нашему ассистенту голос, мы воспользуемся библиотекой для offline-синтеза речи pyttsx3. Она автоматически найдет голоса, доступные для синтеза на нашем компьютере в зависимости от настроек операционной системы (поэтому, возможно, что у вас могут быть доступны другие голоса и вам нужны будут другие индексы).
Также добавим в в main-функцию инициализацию синтеза речи и отдельную функцию для её проигрывания. Чтобы убедиться, что всё работает, сделаем небольшую проверку на то, что пользователь с нами поздоровался, и выдадим ему обратное приветствие от ассистента:
На самом деле, здесь бы хотелось самостоятельно научиться писать синтезатор речи, однако моих знаний здесь не будет достаточно. Если вы можете подсказать хорошую литературу, курс или интересное документированное решение, которое поможет разобраться в этой теме глубоко — пожалуйста, напишите в комментариях.
Шаг 3. Обработка команд
Теперь, когда мы «научились» распознавать и синтезировать речь с помощью просто божественных разработок наших коллег, можно начать изобретать свой велосипед для обработки речевых команд пользователя 😀
В моём случае я использую мультиязычные варианты хранения команд, поскольку у меня в демонстрационном проекте не так много событий, и меня устраивает точность определения той или иной команды. Однако, для больших проектов я рекомендую разделить конфигурации по языкам.
Для хранения команд я могу предложить два способа.
1 способ
Можно использовать прекрасный JSON-подобный объект, в котором хранить намерения, сценарии развития, ответы при неудавшихся попытках (такие часто используются для чат-ботов). Выглядит это примерно вот так:
Такой вариант подойдёт тем, кто хочет натренировать ассистента на то, чтобы он отвечал на сложные фразы. Более того, здесь можно применить NLU-подход и создать возможность предугадывать намерение пользователя, сверяя их с теми, что уже есть в конфигурации.
Подробно этот способ мы его рассмотрим на 5 шаге данной статьи. А пока обращу ваше внимание на более простой вариант
2 способ
Можно взять упрощенный словарь, у которого в качестве ключей будет hashable-тип tuple (поскольку словари используют хэши для быстрого хранения и извлечения элементов), а в виде значений будут названия функций, которые будут выполняться. Для коротких команд подойдёт вот такой вариант:
Для его обработки нам потребуется дополнить код следующим образом:
В функции будут передаваться дополнительные аргументы, сказанные после командного слова. То есть, если сказать фразу «видео милые котики«, команда «видео» вызовет функцию search_for_video_on_youtube() с аргументом «милые котики» и выдаст вот такой результат:
Пример такой функции с обработкой входящих аргументов:
Ну вот и всё! Основной функционал бота готов. Далее вы можете до бесконечности улучшать его различными способами. Моя реализация с подробными комментариями доступна на моём GitHub.
Ниже мы рассмотрим ряд улучшений, чтобы сделать нашего ассистента ещё умнее.
Шаг 4. Добавление мультиязычности
Чтобы научить нашего ассистента работать с несколькими языковыми моделями, будет удобнее всего организовать небольшой JSON-файл с простой структурой:
В моём случае я использую переключение между русским и английским языком, поскольку мне для этого доступны модели для распознавания речи и голоса для синтеза речи. Язык будет выбран в зависимости от языка речи самого голосового ассистента.
Для того, чтобы получать перевод мы можем создать отдельный класс с методом, который будет возвращать нам строку с переводом:
В main-функции до цикла объявим наш переводчик таким образом: translator = Translation()
Теперь при проигрывании речи ассистента мы сможем получить перевод следующим образом:
Как видно из примера выше, это работает даже для тех строк, которые требуют вставки дополнительных аргументов. Таким образом можно переводить «стандартные» наборы фраз для ваших ассистентов.
Шаг 5. Немного машинного обучения
А теперь вернёмся к характерному для большинства чат-ботов варианту с JSON-объектом для хранения команд из нескольких слов, о котором я упоминала в пункте 3. Он подойдёт для тех, кто не хочет использовать строгие команды и планирует расширить понимание намерений пользователя, используя NLU-методы.
Грубо говоря, в таком случае фразы «добрый день«, «добрый вечер» и «доброе утро» будут считаться равнозначными. Ассистент будет понимать, что во всех трёх случаях намерением пользователя было поприветствовать своего голосового помощника.
С помощью данного способа вы также сможете создать разговорного бота для чатов либо разговорный режим для вашего голосового ассистента (на случаи, когда вам нужен будет собеседник).
Для реализации такой возможности нам нужно будет добавить пару функций:
А также немного модифицировать main-функцию, добавив инициализацию переменных для подготовки модели и изменив цикл на версию, соответствующую новой конфигурации:
Однако, такой способ сложнее контролировать: он требует постоянной проверки того, что та или иная фраза всё ещё верно определяется системой как часть того или иного намерения. Поэтому данным способом стоит пользоваться с аккуратностью (либо экспериментировать с самой моделью).
Заключение
На этом мой небольшой туториал подошёл к концу.
Мне будет приятно, если вы поделитесь со мной в комментариях известными вам open-source решениями, которые можно внедрить в данный проект, а также вашими идеями касательно того, какие ещё online и offline-функции можно реализовать.
Документированные исходники моего голосового ассистента в двух вариантах можно найти здесь.
P.S: решение работает на Windows, Linux и MacOS с незначительными различиями при установке библиотек PyAudio и Google.
Кстати, тех, кто планирует строить карьеру в IT, я буду рада видеть на своём YouTube-канале IT DIVA. Там вы сможете найти видео по тому, как оформлять GitHub, проходить собеседования, получать повышение, справляться с профессиональным выгоранием, управлять разработкой и т.д.
Оставайтесь на линии: как создать идеального голосового помощника
Развитие искусственного интеллекта можно сравнить с процессом познания окружающего мира человеком. Так, с момента рождения мы начинаем воспринимать визуальные, аудиальные и другие образы так же, как бот воспринимает информацию через свои «уши» или технологии распознавания речи. Следующим шагом становится изучение слов и самостоятельное формирование фраз и предложений для общения. Бот на лету схватывает все, чему его учат. За это отвечает его «мозг» и дизайнеры голосовых интерфейсов, которые составляют словари для робота. Чтобы озвучить сформированные мысли, человек использует язык, а бот – синтез речи.
Безусловно, существует множество различных дополнительных сервисов, которые могут максимально приблизить поведение и звучание бота к человеческому. Но для начала рассмотрим те, без которых бот не сможет связать ни слова.
Распознавание речи
Одним из основных этапов на пути к полноценной речи бота является распознавание речи. Это многоуровневый процесс восстановления сказанного по акустическим сигналам. Система структурирует полученный результат в слова, фразы и отдельные предложения и преобразует в текстовый формат.
Первый этап – анализ сигнала. Компьютер отправляет полученный запрос на сервер, где он проходит очистку от помех и посторонних шумов. После чего запись сжимается и делится на фрагменты, длина каждого — 25 миллисекунд. Полученные фрагменты пропускаются через акустическую модель – карту голоса по отношению к напечатанным словам, которая создается путем сравнения произнесенного звука с текстом сказанных слов. Эта модель и определяет, какие именно звуки были произнесены, для последующего распознавания.
Второй этап – это распознавание сигнала. В акустической модели хранятся эталонные звуки, с которыми и сравниваются буквы, слоги и слова. С помощью машинного обучения система подбирает варианты произнесенных слов и их контекст, а также собирает из звуков предполагаемые слова.
Заключительным этапом распознавания является преобразование сигнала в текст. На данном этапе система определяет верный порядок слов, основываясь на языковые модели, и подбирает нераспознанные слова по смыслу. Эта информация поступает в декодер, где аудиоданные преобразуются в текст.
Проработанный сценарий
Насколько развит будет ваш бот, зависит лишь от запросов пользователей и опыта дизайнеров голосовых интерфейсов, которые разрабатывают возможные варианты развития диалога. Отвечая на тот или иной вопрос, робот задействует свой «мозг» или центр принятия решений, который работает в соответствии с заданными сценариями. Так, сначала разрабатываются ветки диалога. Например, если цель бота – верифицировать ответившего, он должен задать вопрос, ответом на который будет либо согласие, либо отрицание. Далее в ветки положительного и отрицательного ответа добавляются всевозможные формы согласия и отказа: да, угу, конечно, еще бы/ нет, не-а, не, ни за что и т.д. Здесь же дизайнеры голосовых интерфейсов продумывают варианты диалога на случай, если ответивший гневно просит больше не звонить ему или если бот набрал в неудобное время.
Надо отметить одну важную делать. Бизнесу эффективнее делать «тупого» бота: выбор понижает эффективность коммуникации. К примеру, как только мы говорим клиенту «если хотите изменить время или адрес доставки, назовите удобную дату и новый адрес», он начинает размышлять, удобна ли ему доставка в эту дату или лучше поменять данные. В итоге процесс затягивается на неопределенный срок.
Более того, чтобы создать «умного» бота, то есть обучить нейросеть и «закрыть» хотя бы одну ветку диалога, потребуется большое количество референсного материала – диалоги пользователей с живыми операторами – и масса времени. Как правило, предоставляемой информации недостаточно для качественного обучения нейросети.
Синтез речи
Технологии синтеза речи – неотъемлемая и, пожалуй, самая важная с пользовательской стороны часть голосового робота. Благодаря синтезу речи можно озвучить любой текст голосом, максимально приближенным к естественному. Чтобы сделать синтезированную речь «живой», необходимо отработать ее тембр, плавность звучания, расстановку ударений и пауз, а также интонацию.
Сам процесс синтеза речи происходит в три этапа. Сначала система преобразовывает распознанный ранее текст в удобный для чтения формат – на данном этапе числа записываются словами, а сокращения расшифровываются. Также в рамках первого этапа алгоритм разделяет текст на отдельные предложения и фразы для дальнейшего чтения с правильной интонацией.
На следующем этапе алгоритм выполняет фонетическую транскрипцию. Чтобы понять, как правильно произносить слова и где ставить ударения, система использует встроенные словари. Если компьютер не находит ответа в словаре, он транскрибирует слова самостоятельно, опираясь на академические правила. Если и это не помогает, то используются записи дикторов, которые заранее записываются реальными людьми и добавляются в «речевую базу». После этого система воссоздает подходящую интонацию с помощью данных о фразах и предложениях.
На завершающем этапе система озвучивает транскрибированный текст, используя акустическую модель. Чтобы озвучить текст, робот использует генератор звуковых волн, в который загружаются все характеристики о частотных фразах, полученные от акустической модели.
3 главные ошибки новичков
Плохо проработанные словари
Поверхностная работа со словарями может запутать робота и вызвать негативную реакцию у пользователя, если последний слышит ответы невпопад. Поэтому, работая над словарями, убедитесь, что в ветку положительных ответов вы добавили не только, например, «да», но и «конечно», «удобно» и даже «ну».
Непродуманный сценарий
Робота нужно всему учить, особенно это касается вежливости. Так, при проработке сценариев есть очевидные варианты ответов: да/нет/перезвоните. Однако, порой робот не может распознать ответ пользователя из-за сильных фоновых шумов, тихого голоса и других факторов. Новички часто в этом случае просто обрывают звонок, а бот, соответственно, бросает трубку, не попрощавшись с пользователем и не выполнив цель звонка. Поэтому всегда ставьте себя на место ответившего: лучше переспросить, чем улыбнуться, не разобрав вопроса, правда?
Отключенная клавиатура
Если цель вашего звонка – проведение опроса, обязательно позаботьтесь о том, чтобы пользователь мог ставить оценку нажатием клавиши. Несмотря на развитость и повсеместность голосовых технологий, многим до сих пор привычнее кликнуть, чем произнести ответ вслух. Более того, без возможности ввода с клавиатуры обзвон будет лишь наполовину полезен: при прослушивании вы будете слышать звук нажатой клавиши, но не узнаете результата.
Голосовые боты совершенствуются с каждым годом, а значит в скором времени коммуникация станет намного более эффективной и комфортной для пользователей. В будущем благодаря эффективным и развивающимся системам разработки боты смогут чувствовать эмоциональный настрой человека и с легкостью отвечать на темы, не прописанные в сценарии.