Бот на Python с ChatGPT 3.5 Turbo для Telegram: запоминаем контекст общения [Гайд]
В данной статье мы рассмотрим улучшенный способ взаимодействия с пользователями, который позволяет сохранять контекст общения. Это означает, что ChatGPT теперь может запоминать имя пользователя и их предыдущие сообщения.
Если вы хотите выразить благодарность автору сайта, статей и курса по Django, вы можете сделать это по ссылке ниже:
Мы будем использовать новую модель 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:
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. По желанию мы можем обучить бота тому, кем мы являемся, например новичками в программировании, это выглядело бы так:
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
.
Проверка работы бота
Вот что получилось у меня в ходе тестирования данного бота: