В этой лекции наш бот станет умнее, потому что мы прикрутим к нему искусственный интеллект, а именно — ChatGPT. А работать с нашей программой всеми любимый чатик будет с помощью… правильно, специального API. То есть наш бот будет переключаться в режим работы с чатом, и все последующие сообщения пользователя уже будут обрабатываться именно им.
Чтобы отобразить меню, нам понадобиться всего одна функция – show_main_menu(). В нее нужно передать параметры update, context, а также список команд в фигурных скобках – так же, как мы передавали, например, в функцию sent_text_buttons()
Пример:
Шаг 1. Подключаем ChatGPT
Для начала нам понадобится токен chatGPT, это ключ, с помощью которого наш бот сможет общаться с сервером chatGPT. Его можно купить или достать каким-то окольным путем, но вам повезло, поскольку перед этой лекцией вам его уже прислали в бот. Первое наше действие с кодом в этом уроке — скопировать значение присланного токена и вставить его в соответствующее поле. Пример кода:
chatgpt = ChatGptService(token="вот-тут-вы-должны-вставить-ваш-chatgpt-токен")
Это код нужно написать прямо перед созданием бота:
chatgpt = ChatGptService(token="sk-pUFKDJLKK09898KJKJLJLK87878jkjkkllougTImm")
app = ApplicationBuilder().token("0980989809:fjkdfjlsdjfisdm").build()
# подключение хэндреров
Если вы это сделали – отлично, теперь давайте попробуем отправить нашему ИИ какое-нибудь сообщение.
По задумке у нашего бота должен быть особый режим общения с пользователем, когда пользователь может задавать вопросы прямо ИИ. Это режим называется gpt, и для него есть аналогичная команда.
Давайте добавим в наш проект функцию gpt. Выглядеть она может, например так:
async def gpt(update, context):
await send_text(update, context, "Напишите сообщение *ChatGPT*:")
Также нам нужно связать эту функцию с командой /gpt. Для этого добавим приложению нашего бота еще один хэндлер:
app = ApplicationBuilder().token("0980989809:fjkdfjlsdjfisdm").build()
app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("gpt", gpt))
app.run_polling()
Шаг 2. Режимы диалога
Теперь мы должны научить наш бот общаться в разных режимах. Вчера это было просто обучающее общение ни о чем, сегодня, но только после клика по команде /gpt, это должно быть общение с ChatGPT. Завтра, после ввода команды /date, это уже будет тренировка в переписке со знаменитостями. Поэтому нам нужно добавить в наш чат-бот такое понятие как «режим диалога» где хранить текущий режим. Можно их назвать по именам команд. Например, так:- main – режим общения по умолчанию (или клика по команде start)
- gpt – режим общения с чатом GPT.
- date – тренировка переписки и т.д.
- создадим пустой класс Dialog
- создадим переменную dialog которой присвоим объект типа Dialog
- атрибуту mode этой переменной присвоим имя режима
dialog = Dialog()
dialog.mode = "main"
Это код можно разместить в любом месте файла bot.py, но для красоты лучше ближе к концу – можно сразу перед созданием объекта ChatGptService.
Теперь в каждой функции, которая обрабатывает команду, нужно переключать режим диалога:
async def gpt(update, context):
dialog.mode = "gpt"
await send_text(update, context, "Напишите сообщение *ChatGPT*:")
И тоже для команды start:
async def start(update, context):
dialog.mode = "main"
text = load_message("main")
await send_photo(update, context, "main")
await send_text(update, context, text)
Шаг 3. Отправляем запрос ChatGPT
Для общения пользователя с чатом GPT мы создадим отдельную функцию – gpt_dialog. В ней мы будем делать 3 вещи:- Получаем сообщение от пользователя.
- Пересылаем сообщение пользователя чату-gpt.
- Ответ чата-gpt публикуем пользователю в чат.
async def gpt_dialog(update, context):
text = update.message.text
answer = chatgpt.send_question(text)
send_text(update, context, answer)
К этому коду есть 2 замечания: - функции send_question() и send_text() – асинхронные, перед их вызовом нужно использовать ключевое слово await.
- Метод send_question() принимает не 1, а 2 параметра: prompt и вопрос пользователя
async def gpt_dialog(update, context):
text = update.message.text
answer = await chatgpt.send_question("Дай четкий и короткий ответ на вопрос", text)
await send_text(update, context, answer)
Такой код будет работать. Ну почти. Мы же нигде не связали функцию gpt_dialog с нашим ботом. Сейчас все сообщения пользователя идут в функцию hello(). Предлагаю в начале это функции проверить режим диалога, и если он gpt, передать туда вызов:
async def hello(update, context):
if dialog.mode == "gpt":
await gpt_dialog(update, context)
else:
await send_text(update, context, "Привет!")
await send_text(update, context, "Как дела, *дружище*?")
await send_text(update, context, "Ты написал " + update.message.text)
Вот теперь все отлично: если диалог в режиме gpt, то все сообщения пользователя будет обрабатывать функция gpt_dialo(), иначе – hello().
Шаг 4. Использование prompt для ChatGPT
Также предлагаю использовать заготовленный prompt из папки resources\prompts, и немного подправить нашу функцию gpt_dialog:
async def gpt_dialog(update, context):
prompt = load_prompt("gpt")
text = update.message.text
answer = await chatgpt.send_question(prompt, text)
await send_text(update, context, answer)
Шаг 5. Добавляем отправку приветственных картинок.
Каждый раз, когда пользователь переключает режим диалога с помощью ввода команды, нужно присылать ему приветственную картинку и сообщение, чтобы он знал, что диалог переключился в новый режим. У меня уже есть заготовленные сообщения и картинки на этот случай. Имена заготовленных картинок и сообщений совпадают с именами режимов диалога («main» для /start, «gpt» для /gpt и т.д.) Загрузить заготовленное сообщение можно с помощью функции load_message(). Пример функции start():
async def start(update, context):
dialog.mode = "main"
text = load_message("main")
await send_photo(update, context, "main")
await send_text(update, context, text)
Функция gpt() имеет вид:
async def gpt(update, context):
dialog.mode = "gpt"
await send_photo(update, context, "gpt")
await send_text(update, context, "Напишите сообщение *ChatGPT*:")
Шаг 6. Показываем меню с командами
Давайте еще немного украсим наш Telegram-бот. Для этого мы отобразим ему снизу меню с командами. Выглядеть оно будет примерно так:
Чтобы отобразить меню, нам понадобиться всего одна функция – show_main_menu(). В нее нужно передать параметры update, context, а также список команд в фигурных скобках – так же, как мы передавали, например, в функцию sent_text_buttons()
Пример:
await show_main_menu(update, context, {
"start": "главное меню бота",
"gpt": "задать вопрос ChatGPT"
})
Слева (до знака равно) мы перечисляем именно имена команд (не режимов диалога). Каждый раз, когда пользователь кликнет на такой пункт меню, в чат отправится соответствующая команда.
Шаг 7. Отображаем наш список команд в меню
Ну и давайте сделаем наше меню красивше. Можно взять список будущих команд из файла resources\messages\main.txt Он будет таким:1. /start – главное меню бота
2. /profile – генерация Tinder-профиля 😎
3. /opener – сообщение для знакомства 🥰
4. /message – переписка от вашего имени 😈
5. /date – переписка со звездами 🔥
6. /gpt – задать вопрос чату GPT 🧠
Все смайлики отлично отображаются и в main.txt, и в коде в PyCharm и в Telegram, поэтому просто скопируйте тексты и поправьте вызов метода show_main_menu(), чтобы там были все 6 команд.
Шаг 8. Выводы
Таким образом к концу этой лекции мы можем общаться с чатом тремя способами:- нажать на команду в приветственном сообщении
- ввести команду в формате /команда
- кликнуть по меню и выбрать соответствующую команду.
- прикрутили ChatGPT
- добавили обработку команды /gpt
- добавили переключение в режим диалога
- разобрались как работать с промптами
- добавили отображение меню с командами
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ