Бот на Python с ChatGPT 3.5 Turbo для Telegram: запоминаем контекст общения [Гайд]
Нейросети

Бот на Python с ChatGPT 3.5 Turbo для Telegram: запоминаем контекст общения [Гайд]

Razilator

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

Мы будем использовать новую модель GPT-3.5 Turbo вместо Text-Davinci-003, а также библиотеку Aiogram для создания бота.

Обычный вариант бота ChatGPT без сохранения контекста общения

Как получить токен для бота и ChatGPT вы можете узнать из этой статьи.

Создаём проект с ботом

Открываем IDE редактор, например PyCharm либо VSCODE. Я открою через VSCODE и создам новое виртуально окружение в папке проекта, которую назвал telegramgpt, далее открою терминал, в котором напишу следующую команду для создания виртуального окружения: py -m venv venv, также я создам файл main.py.

Получиться должно вот так
Получиться должно вот так

Активируем наше виртуальное окружение, в терминале введем: cmd, а далее cd venv/Scripts && activate

Запущенное виртуальное окружение
Запущенное виртуальное окружение

Отлично. Перейдем к установке необходимых пакетов.

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

Установим две библиотеки с помощью следующей команды: pip install openai aiogram.

Результат установки:

Терминал
>>> (venv) C:\Users\Razilator\Desktop\Projects\telegramgpt\venv\Scripts>pip install openai aiogram
Collecting openai
  Using cached openai-0.27.2-py3-none-any.whl (70 kB)
Collecting aiogram
  Using cached aiogram-2.25.1-py3-none-any.whl (203 kB)
Collecting requests>=2.20
  Using cached requests-2.28.2-py3-none-any.whl (62 kB)
Collecting tqdm
  Using cached tqdm-4.65.0-py3-none-any.whl (77 kB)
Collecting aiohttp
  Using cached aiohttp-3.8.4-cp311-cp311-win_amd64.whl (317 kB)
Collecting Babel<2.10.0,>=2.9.1
  Using cached Babel-2.9.1-py2.py3-none-any.whl (8.8 MB)
Collecting certifi>=2021.10.8
  Using cached certifi-2022.12.7-py3-none-any.whl (155 kB)
Collecting magic-filter>=1.0.9
  Using cached magic_filter-1.0.9-py3-none-any.whl (9.3 kB)
Collecting attrs>=17.3.0
  Using cached attrs-22.2.0-py3-none-any.whl (60 kB)
Collecting charset-normalizer<4.0,>=2.0
  Using cached charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl (96 kB)
Collecting multidict<7.0,>=4.5
  Using cached multidict-6.0.4-cp311-cp311-win_amd64.whl (28 kB)
Collecting async-timeout<5.0,>=4.0.0a3
  Using cached async_timeout-4.0.2-py3-none-any.whl (5.8 kB)
Collecting yarl<2.0,>=1.0
  Using cached yarl-1.8.2-cp311-cp311-win_amd64.whl (55 kB)
Collecting frozenlist>=1.1.1
  Using cached frozenlist-1.3.3-cp311-cp311-win_amd64.whl (32 kB)
Collecting aiosignal>=1.1.2
  Using cached aiosignal-1.3.1-py3-none-any.whl (7.6 kB)
Collecting pytz>=2015.7
  Using cached pytz-2023.3-py2.py3-none-any.whl (502 kB)
Collecting idna<4,>=2.5
  Using cached idna-3.4-py3-none-any.whl (61 kB)
Collecting urllib3<1.27,>=1.21.1
  Using cached urllib3-1.26.15-py2.py3-none-any.whl (140 kB)
Collecting colorama
  Using cached colorama-0.4.6-py2.py3-none-any.whl (25 kB)
Installing collected packages: pytz, urllib3, multidict, magic-filter, idna, frozenlist, colorama, charset-normalizer, certifi, Babel, attrs, async-timeout, yarl, tqdm, requests, aiosignal, aiohttp, openai, aiogram
Successfully installed Babel-2.9.1 aiogram-2.25.1 aiohttp-3.8.4 aiosignal-1.3.1 async-timeout-4.0.2 attrs-22.2.0 certifi-2022.12.7 charset-normalizer-3.1.0 colorama-0.4.6 frozenlist-1.3.3 idna-3.4 magic-filter-1.0.9 multidict-6.0.4 openai-0.27.2 pytz-2023.3 requests-2.28.2 tqdm-4.65.0 urllib3-1.26.15 yarl-1.8.2

[notice] A new release of pip available: 22.3 -> 23.0.1
[notice] To update, run: python.exe -m pip install --upgrade pip

Перейдем к написанию кода для бота.

Создание бота на aiogram и GPT 3.5 Turbo

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

Можем приступать к написанию кода в main.py:

main.py
import openai

from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor

telegram_token = 'Токен от телеграмм бота'
openai.api_key = 'Токен от OpenAI ChatGPT'
max_token_count = 4096

bot = Bot(token=telegram_token)
dp = Dispatcher(bot)

messages = [
    {
        "role": "system",
        "content": "You are a programming assistant at Proghunter.ru, helping users with Python and JavaScript programming with popular frameworks."
    }
]


def update(messages, role, content):
    """
    Функция обновления списка сообщений
    """
    messages.append({"role": role, "content": content})


def reset_messages():
    """
    Функция очистки истории сообщений контекста, чтобы избежать ошибки с токенами
    """
    messages.clear()
    messages.append({
        "role": "system",
        "content": "You are a programming assistant at Proghunter.ru, helping users with Python and JavaScript programming with popular frameworks."
    })


@dp.message_handler()
async def send(message: types.Message):
    try:
        update(messages, 'user', message.text)
        response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=messages,
            max_tokens=max_token_count,
        )
        if response['usage']['total_tokens'] >= max_token_count:
            await message.answer(
                f'В данный момент вы использовали максимум токенов в рамках контекста: {response["usage"]["total_tokens"]}, будет произведена очистка памяти')
            reset_messages()
        await message.answer(response['choices'][0]['message']['content'], parse_mode="markdown")
    except OpenAIError as ex:
        await message.answer(ex.error)


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

Этот код является примером простого бота для Telegram, который использует OpenAI ChatGPT для обработки сообщений пользователей. Давайте разберем его по частям:

Определение токенов:

  • telegram_token - токен, выданный Telegram для вашего бота. Он используется для установления связи между ботом и Telegram API.
  • openai.api_key - токен, выданный OpenAI для использования ChatGPT. Он используется для установления связи между кодом и OpenAI API.

Импорты:

  • from aiogram import Bot, Dispatcher, types, executor - импорт необходимых модулей из библиотеки aiogram, которая упрощает работу с Telegram API.

Инициализация бота и диспетчера:

  • bot = Bot(token=telegram_token) - создает экземпляр класса Bot с использованием telegram_token.
  • dp = Dispatcher(bot) - создает экземпляр класса Dispatcher и связывает его с ботом bot.

Создание начального списка сообщений:

  • messages - список сообщений, который будет использоваться для взаимодействия с моделью ChatGPT. В данном случае, в списке уже есть одно системное сообщение, которое представляет собой вступительную фразу о том, что бот является ассистентом программиста на Proghunter.ru.

Вспомогательные функции:

  • update(messages, role, content) - функция для обновления списка сообщений. Принимает роль (role) и содержимое (content) сообщения пользователя, и добавляет их в список messages.
  • reset_messages() - функция для сброса списка сообщений. Очищает список messages и добавляет в него системное сообщение о том, что бот является ассистентом программиста.

Обработчик сообщений:

  • @dp.message_handler() - декоратор, который указывает, что функция send будет обрабатывать все входящие сообщения.
  • async def send(message: types.Message) - определение функции обработки сообщений. Она получает объект message, который представляет входящее сообщение от пользователя.

Внутри функции:

  • update(messages, 'user', message.text) - добавляет сообщение пользователя в список messages с ролью user.
  • response = openai.ChatCompletion.create(...) - отправляет список сообщений messages в OpenAI API, чтобы получить ответ от модели ChatGPT.
  • if response['usage']['total_tokens'] >= max_token_count - проверяет, достигнуто ли максимальное количество токенов max_token_count в рамках контекста. Если да, то происходит сброс списка сообщений с помощью вызова функции reset_messages().
  • await message.answer(...) - отправляет ответ пользователю через Telegram API. Ответ берется из поля content первого варианта ответа в response['choices'].
  • except OpenAIError as ex: - обрабатывает исключение OpenAIError, которое может возникнуть при взаимодействии с OpenAI API. В этом случае, бот отправит сообщение об ошибке пользователю.

Запуск бота:

  • if __name__ == '__main__': - проверяет, что код запускается как самостоятельный скрипт (а не импортируется в другой модуль).
  • executor.start_polling(dp, skip_updates=True) - запускает бота, который начинает получать и обрабатывать входящие сообщения через Telegram API с помощью диспетчера dp. В итоге, этот код создает Telegram-бота, который использует модель ChatGPT Turbo 3.5 и отвечает на сообщения пользователей о программировании на Python и JavaScript с популярными фреймворками. Бот поддерживает длинные диалоги, контекстное обучение и обрабатывает ошибки при взаимодействии с API OpenAI.

В сообщение с ролью системы мы наделили ChatGPT ролью помощника программиста с сайта proghunter. По желанию мы можем обучить бота тому, кем мы являемся, например новичками в программировании, это выглядело бы так:

main.py
messages  = [
    {"role": "system", "content": "You are a programming assistant at Proghunter.ru, helping users with Python and JavaScript programming with popular frameworks."},
    {"role": "user", "content": "I am a beginner web developer interested in projects in Python, Django and telegram bots."},
    {"role": "system", "content": "Okay, I got you! I will help you with the code if needed."}
]

Запускать бота мы будем следующей командой: py main.py.

Проверка работы бота

Вот что получилось у меня в ходе тестирования данного бота:

Скриншот общения 1
Скриншот общения 1
Скриншот общения 2
Скриншот общения 2
Скриншот чистки контекста
Скриншот чистки контекста
;