Кратко: как новичку создать чат-бот с Gradio и ChatGPT?

cd4949604c6228293dc8f70319a8093e.png

Хотя подключение GPT к интерфейсу Gradio кажется тривиальной задачей, у некоторых новичков возникают трудности, поэтому мы максимально подробно расписали весь процесс создания простейшего чат-бота. 

Gradio — библиотека с открытым исходным кодом. Ее плюс — можно быстро писать свои веб-приложения для ML-моделей, генерировать API. Поэтому тут не нужны никакие навыки работы с Java Script или CSS — всё пишем на Питоне. 

Gradio — это целая экосистема библиотек Python и JavaScript… Внутри библиотеки можно поработать с JS и обратиться к загруженному приложению на Hugging Face по имени, например. 

Gradio чаще используют для демонстрационных моделей, чтобы протестировать нейронку с адекватным интерфейсом. Но двумя окошечками  ответов и запросов утилита не ограничивается. В библиотеке есть и классы для гибкой настройки внешнего вида: при помощи класса «gr.Blocks» можно поиграться с обработкой сложных потоков данных, управлением отображения компонентов. 

Но сегодня мы ограничимся простым функционалом. 

Задача простая: создать чат-бот с привязкой к самой популярной LLM — GPT

Работать будем с классом gr.ChatInterface (predict).launch (), который создает базовый интерфейс для работы нейронки. 

Predict — функция предсказания, отвечающая за входные данные, которые будет получать OpenAI и на ее основе генерировать наш ответ. Сюда мы поместим историю всех сообщений для контекста и сам запрос пользователя. 

Для начала импортируем Gradio и утилиту для работы с API OpenAI, предварительно установив нужное через pip. 

!pip install openai gradio

Дополнительно загружаем getpass для работы с паролями. 

from openai import OpenAI # для работы с API OpenAI
import gradio as gr
import getpass 

Мы пользуемся функцией getpass.getpass () для безопасного ввода API-ключа OpenAI. Тут же подключаем клиент. 

# Запрос ввода ключа от OpenAI
api_key = getpass.getpass("Введите OpenAI API Key:") 

# Создание клиента к API OpenAI
client = OpenAI(api_key=api_key)

Ключ можно забрать у себя в профиле после регистрации на сайте компании. Напоминаем, что использовать российские номера OpenAI запретила — для получения ключа придется купить аккаунт или пройти верификацию с иностранным номером. 

0d50b2df06c0d92983d756f6ea237e6f.png

Все готово для создания нашего чат-бота. Теперь нам нужно задать функцию predict, которая будет принимать входные данные. 

Чтобы наш GPT учитывал не только сообщения пользователя — нужно добавить историю сообщений. Так GPT сгенерирует ответы, рассматривая контекст. 

Соответственно функция predict будет принимать два параметра: message (текущее сообщение пользователя) и history (история предыдущих сообщений в чате). 

def predict(message, history):

Давайте попробуем прописать возвращаемые данные в аргумент history, пропишем логику пополнения «контекста» LLM.  

Чтобы наша «история» заработала, сперва ее нужно отформатировать под экосистему OpenAI. Для этого внутри функции мы создаем пустой список history_openai_format, куда и будут попадать сообщения в обработанном виде.  

history_openai_format = [] # список сообщений в формате пригодном для OpenAI

Дальше нужно разделить данные между запросами пользователя и ответами GPT. Content — сообщения от нейронки или человека. 

User — запросы пользователя,  

Assistent — ответы чат-бота. 

Благодаря циклу for программа последовательно запишет все запросы пользователя и ответы GPT в историю сообщений и заполнит наш пустой отформатированный список. 

 for human, assistant in history: # перебираем все сообщения
        # Указываем для каждого сообщения роль
        history_openai_format.append({"role": "user", "content": human }) # наши запросы
        history_openai_format.append({"role": "assistant", "content": assistant}) # ответы чат-бота 

Важно. Нейронка должна учитывать не только прошедшую историю, но и нынешний запрос, который мы только что ввели… Поэтому добавляем в контекст/историю сообщений аргумент message

# Наше последнее сообщение для чат-бота
    history_openai_format.append({"role": "user", "content": message})

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

history = [
    ("Hello, who are you?", "I am a virtual assistant."),
    ("Can you help me with my homework?", "Of course, what do you need help with?")
]

С действительным сообщением message = «I need help with my math assignment.»

Тогда и отформатированная история пропишется по ролям:

  history_openai_format = [
    {"role": "user", "content": "Hello, who are you?"},
    {"role": "assistant", "content": "I am a virtual assistant."},
    {"role": "user", "content": "Can you help me with my homework?"},
    {"role": "assistant", "content": "Of course, what do you need help with?"},
    {"role": "user", "content": "I need help with my math assignment."}
]

Теперь создадим сам запрос к чат-боту через response с вызовом всей истории переписки, обозначая точность ответов и выбранную модель. 

 #  Формируем запрос к чат-боту со всей историей переписки
    response = client.chat.completions.create(
        model='gpt-4o',                   # используемая модель
        messages= history_openai_format,  # список форматированных сообщений с ролями
        temperature=1.0                   # точность ответов модели
                                              

Возвращаем результат предсказания.

 return response.choices[0].message.content 

И запускаем интерфейс.

# Запуск интерфейса чат-бота с функцией предсказания
gr.ChatInterface(predict).launch()

Весь код выглядит так:

from openai import OpenAI # для работы с API OpenAI
import gradio as gr
import getpass # для работы с паролями


# Запрос ввода ключа от OpenAI
api_key = getpass.getpass("Введите OpenAI API Key:")


# Создание клиента к API OpenAI
client = OpenAI(api_key=api_key)


# Функция предсказания с двумя параметрами
#  message - текущее сообщение
#  history - история сообщений с чат-ботом
def predict(message, history):
    history_openai_format = [] # список сообщений в формате пригодном для OpenAI
    for human, assistant in history: # перебираем все сообщения
        # Указываем для каждого сообщения роль
        history_openai_format.append({"role": "user", "content": human }) # наши запросы
        history_openai_format.append({"role": "assistant", "content": assistant}) # ответы чат-бота
    # Наше последнее сообщение для чат-бота
    history_openai_format.append({"role": "user", "content": message})


    #  Формируем запрос к чат-боту со всей историей переписки
    response = client.chat.completions.create(
        model='gpt-4o',                   # используемая модель
        messages= history_openai_format,  # список форматированных сообщений с ролями
        temperature=1.0                   # точность ответов модели
                                              )


    return response.choices[0].message.content # возвращаем результат предсказания


# Запуск интерфейса чат-бота с функцией предсказания
gr.ChatInterface(predict).launch()

Мы считаем, что с подключением GPT разберется даже школьник. Такой вариант — минимум для реализации чат-бота. В следующем посте мы расскажем, как создать своего простого менеджера HR-отдела. 

© Habrahabr.ru