Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
В данной статье мы рассмотрим бизнес-применение моделей от OpenAI. Я расскажу о том, как можно подключить ChatGPT ко внешней базе данных, а также как можно заставить его взаимодействовать с телеграмом (отправлять кнопки, к примеру).
Задумка
В данной статье мы рассмотрим следующее:
Есть телеграм бот. Нужен он для того чтобы узнавать ответы на те или иные вопросы. У нас есть база со "знаниями". Когда человек пишет боту, система должна дать ему ответ на его вопрос опираясь на это базу.
Для того, чтобы это реализовать, необходимо:
Запустить файн-тюнинг для модели gpt-3.5-turbo-1106 используя специальный датасет;
Написать парсер для ответов модели;
Написать скрипт для бота.
Реализация
1. Взаимодействие с моделью
Отправляем модели сообщение с вопросом «Как заблокировать карту?», модель смотрит есть ли такая ситуация в списке возможных, и если есть, начинает искать ответ в базе чтобы затем объяснить пользователю то, что он хотел сделать или узнать.
Мы не можем написать огромную инструкцию для модели т. к. это будет пустой расход токенов, так что желательно системное сообщение должно выглядеть так:
[Как заблокировать карту?|A]
[Как разблокировать карту?|B]
[Как закартировать разблокировку|C]
И если к примеру модель получит вопрос «Как заблокировать карту?», то в ответ она просто отправит одну нужную букву или комбинацию, в данном случае это A. Затем её ответ прочтёт скрипт и посмотрит есть ли в базе информация с тегом A, и если она там есть, – скрипт отправит модели нужную информацию, если нет, – отправит ничего или прочерк.
Если в инструкции нет нужного кейса, то модель заместо комбинации отправит сообщение о том, что не может помочь конкретно с этим кейсом, но может помочь с другими. В начало этого сообщения модель поставит ! (как и во все другие сообщения которые должны быть доставлены пользователю).
Нам также нужно дать возможность модели прикреплять кнопки к сообщениям в том случае когда пользователь может задать доп. вопрос. Для этого модель сможет помещать в конец сообщений подобные конструкции: [[Текст кнопки]]. Их автоматически спарсит и вырежет отдельный скрипт.
Этот самый парсер для кнопок напишем прямо сейчас:
Получившийся рабочий код:
function parseMessage(message) {
const buttonRegex = /\[\[(.*?)\]\]/g;
let match;
const buttons = [];
while ((match = buttonRegex.exec(message)) !== null) {
buttons.push(match[1]);
}
const text = message.replace(buttonRegex, '').trim();
return {
text,
buttons
};
}
"База знаний" будет у нас в виде матрицы (список в списке), где первый элемент – тег, а второй – содержание.
Пишем код для поиска:
Получившийся рабочий код:
function filterData(tags, data) {
// Сплитуем строку тегов через пробел
let tagArray = tags.split(' ');
// Фильтруем данные
let filteredData = data.filter(row => {
// Проверяем каждый тег
for (let i = 0; i < tagArray.length; i++) {
// Если первый элемент строки совпадает с тегом, возвращаем true
if (row[0] === tagArray[i]) {
return true;
}
}
// Если ни один тег не совпал, возвращаем false
return false;
});
return filteredData;
}
2. Fine-tuning
Нам нужно составить датасет, который сможет объяснить модели как себя вести. Там должно быть видно следующее:
Если кейс есть в системном сообщении, модель ищет информацию по нужному/нужным тегам;
Если кейса нет, пишет что помочь не может;
Если пользователь может задать доп. вопросы, модель добавляет кнопки;
Её поведение в случае если пользователь пишет не по теме.
В датасете вдобавок должно быть видно то, что количество кейсов не фиксировано. Также мы укажем модели на то, что в системном сообщении может быть и другая полезная информация помимо кейсов.
Вот пример некоторых диалогов из датасета (всего их там будет 27 штук):
{
"messages": [
{
"role": "system",
"content": "[Яблоко|BC][Что делать если я родился в 1988 году?|N]\n\nДлина текста внутри [[]] не более 16 символов!\n\nПредназначение: Помогать людям"
},
{
"role": "user",
"content": "как правильно есть яблоки?"
},
{
"role": "assistant",
"content": "BC"
},
{
"role": "user",
"content": "BC: Яблоки нельзя есть – они ядовитые"
},
{
"role": "assistant",
"content": "!Увы, но яблоки есть нельзя – они ядовитые