О ChatGPT сейчас не говорит только ленивый. Но ему чего-то не хватает, например голоса. Давайте попробуем соединить голосовой помощник Алиса и ChatGPT. Таким образом мы сможем взаимодействовать с ChatGPT с помощью голоса. А он с помощью голоса может нам отвечать. Конечно тут будут ограничения. Я подробно опишу их дальше. Данная статья не столько о ChatGPT, сколько о том, как писать навыки для Алисы. Было интересно разобраться и написать такой навык за вечер. Официальное API ChatGPT открыто и для его использования нужен только API_KEY c сайта OpenAI https://platform.openai.com/account/api-keys. Апи платное, есть триал и лимит бесплатного использования на первые три месяца. Сейчас,похоже, чтобы зайти туда нужен VPN. Для взаимодействия будем пользоваться официальной питоновской библиотекой openai.Код взаимодействия с chatGPT моделью: aquery принимает текст запроса к chatGPT, а также опционально список предыдущих запросов prev_messages. Так мы сможем держать chatGPT в контексте наших предыдущих сообщений и можем поддерживать диалог.openai.ChatCompletion.acreate функция запроса к chatGPT. model это модель которую надо использовать. messages список объектов запросов. Вот по сути и весь код взаимодействия с ChatGPT API. Что же такое навык для Алисы? Навык можно рассматривать как какую-то подпрограмму которая Алиса запускает, когда произносишь специальную фразу активации. Далее общение происходит напрямую с навыком, минуя Алису. Единственная фраза, которую она обрабатывает в этом режиме "Алиса, хватит". Технически навык это выделенный post https endpoint.  Алиса посылает POST запрос с текстом озвученным пользователем и ожидает ответ с тем текстом, который она должна озвучить. Навыки можно создавать и на платформе Yandex Cloud Functions. Для этого надо зарегистрироваться на Yandex Cloud и создать платежный аккаунт. Но Cloud Functions для навыков Алисы не тарифицируется. К сожалению создание платежного аккаунта доступно только для пользователей из России и Казахстана. Поэтому мы будем делать наш собственный сервер. Для этого надо иметь сервер с IP доступным извне, доменом и включенным https. Будем считать что все это у нас уже есть, настроено и работает. Первая проблема вытекает именно из того что Алиса посылает запрос на наш сервер и ждет. Алиса ждет ровно 3 секунды. Если ответ не приходит за это время, Алиса скажет "Навык не отвечает" и просто выкинет вас из навыка. В это время входит и время отправки запроса и получения ответа, так что на обработку запроса остается совсем мало времени.Понятно что генерация ответа у GPT займет больше. На этот случай после запроса пользователя мы просто просим подождать и позвать нас позже. Чтобы пользователю было не скучно можно, например, проиграть музыку, которую мы загрузили в навык. Однако навык не может инициализировать разговор, потому пользователь должен сказать что-то, чтобы активировать навык позже. Да, это достаточно неудобно и приходится каждый раз спрашивать навык о том готов ли ответ.Начнем с запуска сервера. Будем использовать FastAPI.main.py Запускаем сервер вот так Тут мы просто написали обработчик POST json запросов. Получаем запрос(https://yandex.ru/dev/dialogs/alice/doc/request.html). Подготавливаем словарь, который будем возвращать с нашим ответом (https://yandex.ru/dev/dialogs/alice/doc/response.html).Подробнее о запросах и ответах можно прочитать по данным ссылкам. Скажу только что в большинстве случаев нам будет нужен только текст запроса пользователя. request['request']['original_utterance']. А ответ мы вернем в response['response']['text']. Конечно в запросе есть и другие поля. Яндекс проводит обработку текста запроса и возвращает это нам, например можно получить именованные сущности которые назвал пользователь в своем запросе, например имена или адреса, или интенты.session_state позволяет хранить данным между запросами к навыку, на первое время этого будет достаточно и так мы сможем сохранять контекст и поддерживать беседу с пользователем.Функция handle_dialog будет отвечать за обработку запроса и отправку ответа от chatGPT.  req['request']['original_utterance'] может быть пустым. Это значит что пользователь только активировал навык. Приветствуем его.Мы завели словарь answer. В этом словаре ключ - вопрос пользователя, а значение - ответ нейросети. Конечно, лучше хранить сессии пользователя вместо этого и не памяти а, например, на Redis. В коде мы запрашиваем ответ у chatGPT если он не уложился в 1 секунду, то отвечаем пользователю, что пока не готовы и предлагаем спросить нас позже. Все следующие запросы пользователя мы игнорируем. Они нужны нам только для того чтобы активировать запрос навыка, так как навык не может инициировать разговор. Если при повторном запросе ответ все еще не готов мы снова просим повторить запрос позже. Также мы храним историю предыдущих запросов.Если с момента предыдущего запроса к навыку прошло достаточно времени лампочка на Алисе тухнет и чтобы задать следующий вопрос мы должны ее разбудить. Очевидно единственный способ это позвать колонку и после этого задать вопрос. Однако, если мы не смотрим на колонку, мы не узнаем активирована она еще или нет. Именно поэтому мы используем CUT_WORD. Мы просто удаляем Имя колонки из начала запроса. ChatGPT это видеть незачем.Ну и последняя функция. Это обертка над нашей функцией обращения к GPT-3 модели. Обрабатывает ошибки и обновляет наш словарь answers.В принципе это весь код, его можно найти на Github. Дальше нам надо опубликовать навык. Наш обработчик должен быть доступен с серверов яндекса по https. Кроме того сервер должен иметь публичный IP.  Подробнее о том как подключить новый навык на платформе диалогов Яндекса хорошо написано в инструкции  В качестве Webhook URL используем URL нашего обработчика Если мы не хотим публиковать навык мы можем сделать его приватным. В этом случае даже не надо отправлять его на модерацию и навыком сможете воспользоваться только вы или те у кого есть специальное приглашение. Особое внимание следует уделить Активационные имена и Примеры запросов. Это список фраз которые мы можем использовать, чтобы запустить навык. Имена должны быть достаточно уникальными с одной стороны чтобы не совпадать с фразами других возможных навыков. С другой стороны Алиса должна различать эти фразы и правильно их воспринимать не путая с другими словами. Если не соблюдать это правило вы потратите много времени доказывая Алисе, что вы хотите запустить.Вот и все,наш первый навык готов. В конце прикреплю пару примеров работы навыка.  Вот несколько выводов которые хотелось бы указать в заключении. Делать навыки для алисы очень просто, мы просто должны правильно обрабатывать запросы. Алиса имеет ограничение на время запроса в три секунды. Если не укладываемся на UX взаимодействия сильно падает и мы должны просить пользователя активировать нас позже. Имеется ограничение на длину ответа в 1024 символов. Мы должны сделать пагинацию для длинных ответов. Алиса не сможет прочитать нам код, потому запросы на генерацию кода лучше делать на сайте. Навык должен отвечать быстро и кратко, голосовое взаимодействие занимает много времени и не надо отнимать его у пользователя еще больше