API ChatGPT от OpenAI: Telegram-бот на Python и AIOGram

API ChatGPT от OpenAI: Telegram-бот на Python и AIOGram

Недавно меня просили рассказать про ChatGPT и вот время настало. Нейросети используются в разных областях, например, в поисковиках, чтобы предлагать подходящие варианты поиска, в чат-ботах на сайтах, а также в играх. Список применений нейросетей можно продолжать долго.

Как работают нейросети и ChatGPT

Что такое искусственный интеллект (ИИ) — это область науки и технологии, которая создает системы для выполнения задач, требующих интеллектуальных усилий. ИИ используется в медицине, науке, финансах, производстве, транспорте и других областях. Если сильно утрировать, то можно приставить как огромную конструкцию if … else.

У нас есть n-ное количество входных данных, дальше мы производим с ними различные манипуляции в скрытых слоях. Допустим делим, умножаем и все в таком ключе. И на выходе получаем n-ное количество данных. В данном случае один «выход». Если вам интересно познакомиться с этой технологий, то предлагаю посмотреть этот ролик.

Надеюсь, у вас появилось хоть какое-то представление, что такое нейронная сеть. Теперь можно переходить к проекту.

Регистрация в OpenAI и получение токена GPT

Мы сделаем бота в Telegram, который будет отвечать на наши вопросы осмысленным и связным текстом. А также добавим возможность вести с нами диалог на основе предыдущих сообщений.

Анонсы всех видео, статей и полезностей - в нашем Telegram🔥
Присоединяйтесь, обсуждайте и автоматизируйте!

Чтобы вы могли использовать натренированную модель ИИ от OpenAI (создатели ChatGPT), вам нужен API токен для обращения. Для начала необходимо зарегистрироваться на сайте https://chat.openai.com/. От вас потребуются: адрес электронной почты, имя пользователя, пароль, а также номер телефона.

Пользователи из России должны заходить на сайт с включённым VPN. Не рекомендуется указывать при регистрации почты на домене .ru. На сайте OpenAI вас спросят номер телефона, вы можете приобрести временный номер тут: https://onlinesim.ru/. Будьте внимательны - не все номера и страны работают правильно. Вбивайте в поиск "OpenAI" и выбирайте номера именно под этот сервис.

После регистрации переходим в пункт «View API keys»:

Дальше нажимаем «Create new secret key»:

В открывшемся окошке копируйте ваш API токен:

Установка библиотек Python

Для Windows 10:

pip install openai aiogram

Или для MacOS:

python pip install openai aiogram

Пишем Telegram бота для общения с ChatGPT

Что ж, мы закончили с прелюдиями, теперь можно переходить к коду.

Структура проекта:

+---article_openai_bot
|   +---handlers
|   |   +---users
|   |   |   +---__init__.py
|   |   |   |---ai.py
|   |   |   |---help.py
|   |   |   \---start.py
|   |   \---__init__.py
|   +---states
|   |   +---talk.py
|   |   \---__init__.py
|   +---utils
|   |   \---set_bot_commands.py
|   +---.env
|   |---app.py
|   \---loader.py

Loader.py

from aiogram import Bot, Dispatcher, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
import environs

Импортируем модули: Bot, Dispatcher и types из aiogram, а также MemoryStorage из aiogram.contrib.fsm_storage.memory и Env из environs.

env = environs.Env()
env.read_env()
token = env.str("BOT_TOKEN")
openai_token = env.str("OPENAI_API_KEY")

Далее создается объект env типа Env, который используется для чтения переменных окружения из файла .env. В этом коде он используется для получения токенов бота и OpenAI API.

bot = Bot(token=token, parse_mode=types.ParseMode.HTML)
storage = MemoryStorage()
dp = Dispatcher(bot, storage=storage)

Затем создаются объекты Bot и MemoryStorage, которые передаются соответствующим параметрам конструктора. Объект Bot используется для общения с Telegram Bot API и передачи сообщений, а объект MemoryStorage используется для хранения состояний пользователей во время работы с ботом.

Далее создается объект dp типа Dispatcher, в который также передается Bot и MemoryStorage. Dispatcher используется для обработки входящих сообщений и вызова соответствующих обработчиков.

App.py

from aiogram import executor

from loader import dp
import handlers
from utils.set_bot_commands import set_default_commands

Сначала импортируются необходимые модули: executor из aiogram, dp из loader и handlers, а также функция set_default_commands из utils.

async def on_startup(dispatcher):
    # Устанавливаем дефолтные команды
    await set_default_commands(dispatcher)

if __name__ == '__main__':
    executor.start_polling(dp, on_startup=on_startup)

Функция on_startup определена для установки дефолтных команд бота. В этом коде эта функция вызывается при запуске бота.

В блоке if name == 'main': происходит запуск бота с помощью функции start_polling() из модуля executor. Аргументами этой функции являются объект dp (Dispatcher) из модуля loader, который управляет обработкой входящих сообщений, и функция on_startup, которая будет вызываться при запуске бота.

В целом, этот код является базовым скелетом для создания Telegram-бота на Python с использованием библиотеки aiogram и может быть дополнен обработчиками команд и другой функциональностью.

AI.py

Мы не будем затрагивать другие файлы, чтобы не растягивать и без того объемную статью. С ними вы сможете ознакомиться на странице проекта в GitHub.

from aiogram import types
from aiogram.dispatcher import FSMContext
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton

from loader import dp
from states.talk_state import AI
import openai

from aiogram import types - импортирует модуль types из библиотеки Aiogram. Types содержит все типы сообщений, которые можно отправить или получить в Telegram боте, такие как текстовые сообщения, фото, видео и т.д.

from aiogram.dispatcher import FSMContext - импортирует модуль FSMContext из библиотеки Aiogram. FSMContext используется для хранения состояний пользователя в Telegram боте и предоставляет возможность переключения между состояниями.

from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton - импортирует классы InlineKeyboardMarkup и InlineKeyboardButton из библиотеки Aiogram. Эти классы используются для создания интерактивных кнопок в сообщениях, которые позволяют пользователю взаимодействовать с ботом.

from loader import dp - импортирует объект dp из модуля loader. DP (Dispatcher) является главным объектом в Aiogram и используется для обработки сообщений и событий.

from states.talk_state import AI - импортирует объект AI из модуля talk_state. Объект AI используется для управления состоянием диалога с ботом.

import openai - импортирует модуль openai, который позволяет работать с сервисами OpenAI, такими как GPT-3.

@dp.callback_query_handler(text='start')
async def chat_start(call: types.CallbackQuery, state: FSMContext):
    kb = InlineKeyboardMarkup(row_width=1,inline_keyboard=[[InlineKeyboardButton(text="Закончить чат", callback_data="start"), InlineKeyboardButton(text="Стереть память", callback_data="start")]])

    await call.message.answer("Отправть сообщение, чтобы начать переписку", reply_markup=kb)
    await AI.talk.set()
    await state.update_data(history=[{"question": None, "answer": None}])

Первая функция в коде – chat_start – вызывается при нажатии пользователем на кнопку "Начать чат с ИИ". Она создает объект InlineKeyboardMarkup с двумя кнопками – "Закончить чат" и "Стереть память". Затем бот отправляет сообщение пользователю с запросом на ввод сообщения для начала диалога, а также устанавливает состояние AI.talk и обновляет данные состояния.

@dp.message_handler(state=AI.talk)
async def chat_talk(message: types.Message, state: FSMContext):
    data = await state.get_data()
    data = data.get('history')
    kb = InlineKeyboardMarkup(row_width=1, inline_keyboard=[
        [InlineKeyboardButton(text="Закончить чат", callback_data="back"),
         InlineKeyboardButton(text="Стереть память", callback_data="clear")]])
    await message.answer("ИИ думает...", reply_markup=kb)

    history = []
    if len(data) > 1:
        for index in range(0, len(data)):
            if data[index].get('question') is None:
                data[index]['question'] = message.text
                d = {"role": "user", "content": data[index]['question']}
                history.append(d)
            else:
                d = [{"role": "user", "content": data[index]['question']}, {"role": "assistant", "content": data[index].get('answer')}]
                history += d
    else:
        data[0]['question'] = message.text
        d = {"role": "user", "content": data[0].get('question')}
        history.append(d)
    print(history)
    request = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=history,
        max_tokens=500,
        temperature=1,
    )
    resp_ai = request['choices'][0]['message']['content']
    data[-1]['answer'] = resp_ai.replace('\n', '')
    text = f"{message.from_user.username}\nQ:{data[-1]['question']}\nA:{data[-1]['answer']}"
    data.append({"question": None, "answer": None})
    if len(data) > 10:
        await state.update_data(history=[{"question": None, "answer": None}])
    await state.update_data(history=data)
    await message.answer(resp_ai)

Вторая функция – chat_talk – вызывается при получении сообщения от пользователя в состоянии AI.talk. Она получает текущие данные состояния и создает объект InlineKeyboardMarkup с двумя кнопками – "Закончить чат" и "Стереть память". Затем бот формирует текстовую историю диалога на основе предыдущих вопросов и ответов и использует API от OpenAI для получения ответа на текущий вопрос. Полученный ответ добавляется в историю диалога, и состояние AI.talk обновляется с новой историей.

@dp.callback_query_handler(text='back', state='*')
async def back(call: types.CallbackQuery, state: FSMContext):
    kb = InlineKeyboardMarkup(row_width=1,inline_keyboard=[[InlineKeyboardButton(text="Начать чат с ИИ", callback_data="start")]])
    await call.message.answer(f"Привет, {call.from_user.full_name}! Этот бот написан для статьи. Он предоставит доступ к ChatGPT.", reply_markup=kb)
    await state.finish()

Третья функция – back – вызывается при нажатии пользователем на кнопку "Закончить чат". Она отправляет сообщение пользователю о завершении диалога и заканчивает текущее состояние бота.

@dp.callback_query_handler(text='clear', state='*')
async def clear(call: types.CallbackQuery, state: FSMContext):
    await call.message.answer('Память ИИ стерта')
    await state.update_data(history=[{"question": None, "answer": None}])

Четвертая функция – clear – вызывается при нажатии на кнопку " Стереть память ". Она очищает история переписки, передавая пустое значение question и answer в историю переписки.

Заключение

ChatGPT – очень интересная технология, для решения рутинных задач и применения во многих областях. Уверен, что в скором времени такие помощники будут распространены больше. Предлагаю Вам найти собственной применение ИИ от OpenAI.

Полезные ссылки

Документация OpenAI: https://openai.com/api/docs/
Документация Aiogram: https://docs.aiogram.dev/en/latest/
Ссылка на GitHub проекта: https://github.com/Redkomel56/article_openai_bot 

Комментарии