Сегодня мне в голову пришла мысль: «А почему бы не написать Telegram чат-бота с ИИ, которого потом можно будет обучать?» Сейчас сделать это совсем легко, поэтому, недолго думая, я принялся к написанию кода.
Языком я выбрал Python, т.к. на нём легче всего работать с подобного рода приложениями.
Итак, для создания Telegram чат-бота с ИИ нам потребуется:
1. API Telegram. В качестве обёртки я взял проверенную библиотеку python-telegram-bot
2. API ИИ. Выбрал я продукт от Google, а именно Dialogflow. Он предоставляет довольно-таки неплохое бесплатное API. Обёртка Dialogflow для Python
Шаг 1. Создаём бота в Telegram
Придумываем имя нашему боту и пишем @botfather. После создания бота нам придёт API токен, который желательно бы где-то сохранить, т.к. в дальнейшем он нам понадобится.
Шаг 2. Пишем основу бота
Создаём папку Bot, в которой потом создаём файл bot.py. Здесь будет код нашего бота.
Открываем консоль и переходим в директорию с файлом, устанавливаем python-telegram-bot.
pip install python-telegram-bot --upgrade
После установки мы уже можем написать «основу», которая пока что будет просто отвечать однотипными сообщениями. Импортируем необходимые модули и прописываем наш токен API:
Код настроек и импорта
# Настройки from telegram.ext import Updater, CommandHandler, MessageHandler, Filters updater = Updater(token='ВАШ API КЛЮЧ') # Токен API к Telegram dispatcher = updater.dispatcher
Далее напишем 2 обработчика команд. Это callback-функции, которые будут вызываться тогда, когда будет получено обновление. Напишем две таких функции для команды
/start и для обычного любого текстового сообщения. В качестве аргументов туда передаются два параметра:
bot и
update.
Bot содержит необходимые методы для взаимодействия с API, а
update содержит данные о пришедшем сообщении.
Код callback'ов
# Обработка команд def startCommand(bot, update): bot.send_message(chat_id=update.message.chat_id, text='Привет, давай пообщаемся?') def textMessage(bot, update): response = 'Получил Ваше сообщение: ' + update.message.text bot.send_message(chat_id=update.message.chat_id, text=response)
Теперь осталось лишь присвоить уведомлениям эти обработчики и начать поиск обновлений. Делается это очень просто:
Код хендлеров
# Хендлеры start_command_handler = CommandHandler('start', startCommand) text_message_handler = MessageHandler(Filters.text, textMessage) # Добавляем хендлеры в диспатчер dispatcher.add_handler(start_command_handler) dispatcher.add_handler(text_message_handler) # Начинаем поиск обновлений updater.start_polling(clean=True) # Останавливаем бота, если были нажаты Ctrl + C updater.idle()
Итого, полная основа скрипта выглядит вот так:
Код полной основы бота
# Настройки from telegram.ext import Updater, CommandHandler, MessageHandler, Filters updater = Updater(token='ВАШ API ТОКЕН') # Токен API к Telegram dispatcher = updater.dispatcher # Обработка команд def startCommand(bot, update): bot.send_message(chat_id=update.message.chat_id, text='Привет, давай пообщаемся?') def textMessage(bot, update): response = 'Получил Ваше сообщение: ' + update.message.text bot.send_message(chat_id=update.message.chat_id, text=response) # Хендлеры start_command_handler = CommandHandler('start', startCommand) text_message_handler = MessageHandler(Filters.text, textMessage) # Добавляем хендлеры в диспатчер dispatcher.add_handler(start_command_handler) dispatcher.add_handler(text_message_handler) # Начинаем поиск обновлений updater.start_polling(clean=True) # Останавливаем бота, если были нажаты Ctrl + C updater.idle()
Теперь мы можем проверить работоспособность нашего нового бота. Вставляем на 2 строке наш API токен, сохраняем изменения, переносимся в консоль и запускаем бота:
python bot.py
После запуска пишем ему. Если всё настроено правильно, то Вы увидите вот это:
Основа бота написана, приступаем к следующему шагу!
P.s. не забывайте выключить бота, для этого вернитесь в консоль и нажмите Ctrl + C, подождите пару секунд и бот успешно завершит работу.
Шаг 3. Настройка ИИ
В первую очередь, идём и регистрируемся на Dialogflow (просто входим с помощью своего Google аккаунта). Сразу после авторизации мы попадаем в панель управления.
Жмём на кнопку Create agent и заполняем поля по усмотрению (это никакой роли не сыграет, это нужно лишь для следующего действия).
Жмём на Create и видим следующую картину:
Расскажу, почему созданный нами ранее «Агент» никакой роли не играет. Во вкладке Intents есть «команды», по которым работает бот. Сейчас он умеет лишь отвечать на фразы типа «Привет», и если не понимает, то отвечает «Я вас не понял». Не сильно впечатляет.
После создания нашего пустого агента, у нас появилась куча других вкладок. Нам нужно нажать на Prebuilt Agents (это уже специально обученные агенты, которые имеют множество команд) и из всего представленного списка выбрать Small Talk.
Наводим на него и жмём Import. Далее ничего не меняя, жмём Ok. Агент импортировался и теперь мы можем его настроить. Для этого в левом верхнем углу жмём на шестерёнку возле Small-Talk и попадаем на страницу настроек. Теперь мы можем изменить имя агента, как захотим (я оставляю как было). Меняем часовой пояс и во вкладке Languages проверяем, чтобы был установлен русский язык (если не установлен, то ставим).
Возвращаемся на вкладку General, спускаемся немного вниз и копируем Client access token
Теперь наш ИИ полностью настроен, можно возвращаться к боту.
Шаг 4. Собираем всё вместе
ИИ готов, основа бота готова, что дальше? Дальше нам нужно скачать обёртку API от Dialogflow для питона.
pip install apiai
Установили? Возвращаемся к нашему боту. Добавляем в нашу секцию «Настройки» импорт модулей
apiai и
json (нужно, чтобы в будущем разбирать json ответы от dialogflow). Теперь это выглядит вот так:
Код обновлённых настроек
# Настройки from telegram.ext import Updater, CommandHandler, MessageHandler, Filters import apiai, json updater = Updater(token='ВАШ API КЛЮЧ') # Токен API к Telegram dispatcher = updater.dispatcher
Переходим к функции
textMessage (которая отвечает за получение любого текстового сообщения) и посылаем полученные сообщения на сервера Dialogflow:
Код отправления сообщений на Dialogflow
def textMessage(bot, update): request = apiai.ApiAI('ВАШ API ТОКЕН').text_request() # Токен API к Dialogflow request.lang = 'ru' # На каком языке будет послан запрос request.session_id = 'BatlabAIBot' # ID Сессии диалога (нужно, чтобы потом учить бота) request.query = update.message.text # Посылаем запрос к ИИ с сообщением от юзера
Этот код будет посылать запрос к Dialogflow, но нам нужно также извлечь ответ. Дописываем парочку строк, итого
textMessage выглядит вот так:
Полный код функции textMessage
def textMessage(bot, update): request = apiai.ApiAI('ВАШ API ТОКЕН').text_request() # Токен API к Dialogflow request.lang = 'ru' # На каком языке будет послан запрос request.session_id = 'BatlabAIBot' # ID Сессии диалога (нужно, чтобы потом учить бота) request.query = update.message.text # Посылаем запрос к ИИ с сообщением от юзера responseJson = json.loads(request.getresponse().read().decode('utf-8')) response = responseJson['result']['fulfillment']['speech'] # Разбираем JSON и вытаскиваем ответ # Если есть ответ от бота - присылаем юзеру, если нет - бот его не понял if response: bot.send_message(chat_id=update.message.chat_id, text=response) else: bot.send_message(chat_id=update.message.chat_id, text='Я Вас не совсем понял!')
Немного пояснений. С помощью
request.getresponse().read()
получается ответ от сервера, закодированный в байтах. Чтобы декодировать его, просто применяем метод
decode('utf-8')
и после этого «заворачиваем» всё в
json.loads()
чтобы распарсить json ответ.
Если ответа нет (точнее, json приходит всегда, но не всегда есть сам массив с ответом ИИ), то это означает, что Small-Talk не понял пользователя (обучением можно будет заняться позже). Поэтому если «ответа» нет, то пишем пользователю «Я Вас не совсем понял!».
Итого, полный код бота с ИИ будет выглядеть вот так:
Полный код бота с ИИ
# Настройки from telegram.ext import Updater, CommandHandler, MessageHandler, Filters import apiai, json updater = Updater(token='ВАШ API ТОКЕН') # Токен API к Telegram dispatcher = updater.dispatcher # Обработка команд def startCommand(bot, update): bot.send_message(chat_id=update.message.chat_id, text='Привет, давай пообщаемся?') def textMessage(bot, update): request = apiai.ApiAI('ВАШ API ТОКЕН').text_request() # Токен API к Dialogflow request.lang = 'ru' # На каком языке будет послан запрос request.session_id = 'BatlabAIBot' # ID Сессии диалога (нужно, чтобы потом учить бота) request.query = update.message.text # Посылаем запрос к ИИ с сообщением от юзера responseJson = json.loads(request.getresponse().read().decode('utf-8')) response = responseJson['result']['fulfillment']['speech'] # Разбираем JSON и вытаскиваем ответ # Если есть ответ от бота - присылаем юзеру, если нет - бот его не понял if response: bot.send_message(chat_id=update.message.chat_id, text=response) else: bot.send_message(chat_id=update.message.chat_id, text='Я Вас не совсем понял!') # Хендлеры start_command_handler = CommandHandler('start', startCommand) text_message_handler = MessageHandler(Filters.text, textMessage) # Добавляем хендлеры в диспатчер dispatcher.add_handler(start_command_handler) dispatcher.add_handler(text_message_handler) # Начинаем поиск обновлений updater.start_polling(clean=True) # Останавливаем бота, если были нажаты Ctrl + C updater.idle()
Сохраняем изменения, запускаем бота и идём проверять:
Вот и всё! Бот в 30 строк с ИИ написан!
Шаг 5. Заключительная часть
Думаю, Вы убедились, что написать бота с ИИ – дело 10 минут. Осталось лишь теперь его учить и учить. Делать это, кстати, можно во вкладке Training. Там можно посмотреть все сообщения, которые писались и что на них ответил бот (или не ответил). Там же его можно и обучать, говоря боту где он ответил правильно, а где нет.
Надеюсь, статья была Вам полезна, удачи в обучении!