Сделай Сам: ИИ-ассистент за пару дней на коленке для себя и бизнеса. Часть №1
Готовы за пару дней сконструировать собственного виртуального ИИ-помощника на базе документации компании, который будет отвечать на вопросы, помогать с ответами и легко дополняться? Я покажу, как это сделать!
Кому это будет интересно?
В первую очередь статья будет интересна разработчикам, которые начали погружаться в тему Natural Language Processing или которых захватил ChatGPT, Claude или Gemeni (про Сайгу, Орку, Мистраль и зоопарк других моделей мы поговорим немного позже) и они в поиске способов интегрировать LLM в бизнес или заказчикам. Так же будет интересно поиграться с результатом и начинающим разработчикам - от использования в чат-ботах до умного поиска на сайтах, группах и каналах.
Начнем с конца
В результате нашей с вами совместной работы должен получиться продукт - открытый или закрытый, который можно использовать в качестве ИИ-ассистента или ИИ-консультанта по любой документации, которую вы ему "скормите". Некоторые моменты буду опускать и не вдаваться в подробности реализации, но не настолько, чтобы терялся смысл и у вас возникли сложности с восстановлением логических цепочек по примерам.
По ходу реализации проекта буду раскрывать подробности тех или иных нюансов и давать вам пищу для размышлений и изучения.
Если же вы хотите получить готовый проект или исходные коды рабочего представленного проекта за разумную цену, то можете написать мне в телеграм @aashmig.
Несколько скриншотов того, что получилось у меня (сразу скажу, что если делать без интерфейса, например, открывая только публичный API, то это может сильно сократить общее время реализации проекта - именно так мы с вами и поступим в этой статье):
Ингредиенты для приготовления
Использовавшиеся мной в проекте выше:
- NodeJS;
- VueJS;
- Vuetify;
- RabbitMQ;
- ElasticSearch;
- MySQL 8;
- Transformers.js;
- Puppeteer;
- Socket.IO;
- ONNX Runtime;
То, что будем использовать сейчас:
- NodeJS;
- RabbitMQ;
- ElasticSearch;
- MySQL 8;
- Transformers.js;
- ONNX Runtime;
Если вы испугались таких длинных списков, то спешу вас успокоить - установка и базовая настройка этого всего будет значительно проще, если следовать пошаговым инструкциям.
Теперь немного о каждом из используемых ингредиентов:
- NodeJS: потому что мне она нравится. Будем делать базовый REST API для получения, добавления, удаления информации. В этой статье мы обойдёмся без авторизаций, регистраций, восстановлений паролей и другой связанной функциональщиной, которая отнимет у нас много времени;
- RabbitMQ: работа с очередями. Удобный инструмент управления очередями и сообщениями. Используем для того, чтобы (а) не хранить их в памяти в каком-то глобальном объекте NodeJS; (б) не хранить в базе данных MySQL; (в) не писать свою логику обработки сообщений и все связанное с этим.
- ElasticSearch: лексический и семантический поиск. Будем использовать в качестве главного компонента поиска текста по запросу, как по ключевым словам, так и по смыслу.
- MySQL: база данных, не требует отдельного представления. Нужна будет нам для хранения истории диалогов с пользователями (предпочитаю такое хранить в реляционных БД по многим причинам, а не в ElasticSearch);
- Transformers.js: библиотека от парней из Hugging Face для работы с моделями, токенайзерами и прочими около МЛ штуками. Она нам понадобится в момент добавления данных в ElasticSearch и в момент обработки пользовательского запроса.
- ONNX Runtime: использовать напрямую не будем, но без неё не сможем запустить @cointegrated/rubert-tiny2. ONNX Runtime позволяет запускать модельки под большим количеством платформ, например, под NodeJS или даже в браузере (привет WASM и WebGPU!).
Теперь пора подняться на пару уровней выше и понять, как все эти компоненты будут между собой взаимодействовать:
- Администратор платформы публикует новые документы или статью во внутренней wiki;
- Где-то внутри Wiki отправляет запрос к ИИ-ассистенту на добавление новой информации (REST API);
- ИИ-ассистент полученный блок текста разбивает, очищает, векторизует и сохраняет в ElasticSearch;
- Пользователь открывает некий интерфейс UI в виде чата или текстового поля и вводит туда свой запрос, нажимает кнопку Отправить или Получить ответ;
- Где-то внутри отправляется запрос к ИИ-ассистенту с запросом пользователя;
- Запрос пользователя очищается, векторизуется и отправляется в ElasticSearch для смешанного поиска - лексического (по ключевым словам, словосочетаниям, фразам) и семантического (по смыслу), результат поиска - набор отрывков из статей для последующей подачи LLM на вход;
- LLM получает данные из базы знаний и с учетом заранее настроенного промпта и истории диалога с пользователем генерирует ответ (сообщение), которое мы потом и возвращаем пользователю;
Шаг №1: выбираем ОС
Долгими были мои мучения при работе с CentOS 7-8, а когда коллеги из Oracle обрадовали новостью о прекращении поддержки и развития, то пришлось выдохнуть и начать присматриваться к какому-то другому дистрибутиву для работы.
Выбор пал на Ubuntu 22 по чистой случайности и подписи "Machine Learning" + LTS. За рекламу мне Selectel не платит, а мог бы 💁
Радости моей не было предела, когда вся настройка и конфигурация была завершена без танцев с бубнами за пару часов.
На тест и демо-проект нам будет достаточно 1-2 vCPU и 4+ GB RAM. Можем взять SSD на 15 GB и этого тоже должно хватить на первые тестовые запуски и проверки. Если планируете запускать проект в массы, то обратите внимание, что Elastic и RabbitMQ очень любят кушать память и её нужно будет увеличить, а так же изменить ряд настроек по-умолчанию для Elastic с её прожорливой JVM.
ОС поставили. Рекомендую выполнить все стандартные шаги для обновлений:
С первым шагом закончили.
Шаг №2: настройка и установка Nginx
Nginx - потрясающий инструмент. Использовал у себя в качестве proxy, а сейчас его поставим и настроим на тот случай, если захотите раздавать во вне API проекта.
Устанавливаем Nginx:
Чтобы Nginx заработал корректно и с портами не было проблем стоит воспользоваться новой утилитой в Ubuntu - ufw.
Получим список заранее известных утилите конфигураций с которыми она умеет работать из коробки:
Вывод будет похож примерно на такой:
Что они значат:
- Nginx Full: открыть 80 и 443 порты;
- Nginx HTTP: открыть только 80 порт;
- Nginx HTTPS: открыть только 443 порт;
Нам нужен первый вариант - это с учетом того, что сервис будем вешать на какой-то домен и на него же потом ставить SSL сертификат через Lets Encrypt или любой другой сервис.
Проверяем статус:
И получаем примерно такой вывод:
Проверим статус Nginx:
Вывод примерно такой:
Nginx работает и настроен из коробки.
Теперь найдём конфигурационный файл в `/etc/nginx/nginx.conf` и приведём его к вот такому виду (за исключением всего, что касается SSL - этот дополнительный код сгенерировал cert-bot при установке и настройке SSL-сертификата от Lets Encrypt):
Можем закинуть в нашу root-директорию index.html файл для проверки и открыть http://[наш IP адрес]. Если страница открывается - отлично, всё сделано правильно. Если страница не открывается - перепроверяем настройки, пути, код ошибки.
Шаг №3: установка и настройка NodeJS v20
Оптимальный вариант производить установку NodeJS через nvm (node version manager) - позволит удобно управлять версиями используемой node, удалять, переустанавливать.
Устанавливаем nvm:
Применяем:
Проверим список доступных версий:
И установим нужную нам:
Чтобы убедиться, что установка прошла корректно и мы установили 20 версию:
Если всё прошло без ошибок, то установленную версию сделаем версией по-умолчанию:
Шаг №4: установка и настройка RabbitMQ
В этот раз идём на официальный сайт RabbitMQ и находим вот этот раздел со способами установки RabbitMQ - Installing on Debian and Ubuntu. Нас интересует подраздел Cloudsmith Quick Start Script.
Продублирую его полностью ниже:
Его необходимо сохранить в какой-то *.sh скрипт и запустить на выполнение. После установки проверим статус сервера командой:
И в ответе будет что-то подобное:
Сервер успешно запущен и работает.
Ссылка по-умолчанию для подключения к серверу:
Шаг №5: установка и настройка ElasticSearch
Если мы в РФ и наивно решим скачать ElasticSearch с официального сайта без VPN или proxy, то нас ждёт разочарование:
Добрые ребята (ссылки, к сожалению, не помню) скачали все версии и выложили на своём сайте, а я делюсь с вами ссылкой на Яндекс.Диске - ElasticSearch 8.11.2.deb пакет.
Установка из deb пакета оказалась идеальным вариантом, если учитывать тот факт, что все другие способы были заблокированы.
Спасибо ElasticSearch за то, что доступ к документации оставили без proxy или vpn.
Установка ElasticSearch из deb пакета:
Ссылка по-умолчанию для подключения к серверу:
Для проверки корректной установки можно выполнить две команды:
или воспользоваться curl и отправить запрос на адрес подключения:
Получив примерно такой ответ:
Шаг №6: установка и настройка MySQL 8
Установка MySQL 8 никаких трудностей не составляет:
Проверяем статус:
После установки необходимо произвести конфигурацию:
В процессе конфигурации будут заданы несколько вопросов про root, пароль, временные таблицы - внимательно читаем вопросы и отвечаем. Пароль сохраняем себе, не теряем.
В этой части я опущу создание выделенного пользователя с ограниченным набором прав - для нашего примера это не критично.
Шаг №7: устанавливаем всё для NodeJS
На этом шаге наша с вами задача подготовить окружение NodeJS таким образом, чтобы мы могли обрабатывать запросы, выполнять над ними действия, подключаться к RabbitMQ и ElasticSearch, вычислять эмбеддинги и прочее.
Приведу свой package.json файл:
Некоторая часть из этого списка нам не нужна будет, оставляем только то, что пригодится для этого демо-проекта. Результат будет таким:
Выполняем команду установки в директории, которой находится package.json:
После установки в этой же директории появятся node_modules и package-lock.json
🙌 Примечание: если вы знаете, что такое PM2, то можете его установить и настроить через файл ecosystem.conf для запуска приложения. Если не знаете, то можете поискать в Google или спросить ChatGPT.
Конец первой части.
Во второй части мы с вами:
- Напишем несколько API методов для работы с данными - сохранение, удаление, поиск;
- Погрузимся в механизм подготовки больших данных (текстов) для оптимизации последующего лексического и семантического поиска - очистка, chunking, эмбеддинги;
- Научимся портировать модели и конвертировать их в ONNX формат;
- Протестируем модель @cointegrated/rubert-tiny2 на тестовых данных;
- Научимся сохранять контекст диалога и получим первый ответ от LLM по нашим данным из базы знаний.
Если подобные серии статей вам интересны, то обязательно ставьте лайк и подписывайтесь на мой блог на vc.ru
Возможно у вас есть идея или задача в бизнесе, которую, как вам кажется, может решить ИИ-консультант / ИИ-ассистент / ИИ-всезнайка и вы хотите такое решение видеть у себя - напишите мне в телеграм @aashmig и мы обсудим подробности реализации и условия.
Берегите себя и свои модели 🫶
Ваш, Разработчик в бизнесе 👨🏻💻
Комментарий удалён модератором
Марк, пожалуйста 👌
В следующей части будет уже больше деталей и, почти, готовый продукт для внутреннего или внешнего использования.
Очень интересная статья/информация . С нетерпением ожидаю вторую часть повествования об ИИ в деле. Автору в карму плюс! Подписался с удовольствием :+₽
Благодарю за обратную связь ☺️ Поищу время на публикацию второй части с конкретной реализацией, может даже и на гитхаб код выложу сразу.
Первая часть статьи - просто шикарная! Автор молодец
Благодарю! Подписывайтесь, чтобы вторую часть не пропустить. 🤝
Андрей, спасибо за первую часть ! Заинтригован, жду вторую ! И еще идея, а что если к LLM подключить возможность управлять чем-либо, скрипты например запускать, страницы подгугливать .. Короче каких-нибудь агентов, которые бы могли расширять ее возможности. Возможно такое уже есть, но я просто не знаю