AAYMA
RU
Войти

EKT AI

AI-консультант для покупателей ekt.kz: чат с агентом, поиск по названию и артикулу, карточки с характеристиками и остатками, серверная демо-корзина…

Прототип
Команда «Avengers» 1💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: Avengers
Кейс HackAlem.ai: Торговля — Электрокомплект · ekt.kz
Стадия: Прототип

Задача кейса: AI-консультант по каталогу ekt.kz: товары, аналоги, цены, остатки, корзина

Суть

AI-консультант для покупателей ekt.kz: чат с агентом, поиск по названию и артикулу, карточки с характеристиками и остатками, серверная демо-корзина и встраиваемый виджет.

Как устроено

React-фронт отправляет сообщение и историю в POST /api/chat; агент на OpenAI Responses API (gpt-5-mini) вызывает инструмент search_products, который ищет по каталогу EKT (HTTP Basic Auth, кеш 60 с, ранжирование по числу совпавших слов). Карточки подгружаются отдельно через endpoint деталей; корзина в памяти процесса проверяет остаток перед добавлением. Отдельный виджет в Shadow DOM ищет по каталогу без AI.

Ключевые решения

  • function calling
  • ранжирование по совпадению слов
  • кеш каталога
  • Shadow DOM виджет

Особенности

Встраиваемый чат-виджет с изоляцией стилей через Shadow DOM, который можно вставить на страницу магазина. README честно описывает ограничения: общая корзина на процесс, AI не подключён к виджету.

Стек

Python · FastAPI · React · Vite · JavaScript · unittest

Модели

gpt-5-mini (OpenAI)


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-3b719372-avengers.

README

README.md

EKT AI — AI-консультант по электротехническим товарам

Хакатон-прототип помощника для покупателей ekt.kz: консультация на естественном языке, поиск товаров по названию или артикулу, просмотр характеристик и добавление выбранных позиций в демонстрационную корзину.

Проект помогает покупателю сформулировать требования к электротехническому товару и найти варианты в подключённом каталоге. В репозитории есть веб-интерфейс, HTTP API, AI-агент и отдельно собираемый виджет для встраивания на страницу.

Статус: прототип. Серверная корзина общая для всех пользователей одного процесса; оформление заказа не реализовано. AI подключён в основном чате, но не в плавающем виджете.

Репозиторий: BAITC-Hacks/hack-3b719372-avengers.

Описание проверено 23 сентября 2026 года по исходникам архива hack-3b719372-avengers-main.zip, совпадающим с кодом коммита 08ea0d3 без учёта переводов строк. Значения секретов из .env не использовались в документе.

Что реализовано

ВозможностьРеализация и границы
AI-консультацияОсновной чат отправляет сообщение и историю на /api/chat. Агент использует OpenAI Responses API и модель gpt-5-mini.
Поиск для AIМодели доступен инструмент search_products, вызывающий поиск backend по каталогу.
Поиск в интерфейсеОтдельная форма поиска по названию или артикулу; карточки дополняются данными из endpoint деталей товара.
Карточки товаровНазвание, артикул, цена в ₸, наличие, изображение при наличии URL, доступные характеристики, складские остатки и ссылка на товар.
ФильтрацияВ основной странице — фильтр «Только в наличии» и сортировка полученных результатов по цене.
КорзинаДобавление после подтверждения, проверка остатка на backend, просмотр количества и суммы. API также поддерживает изменение количества, удаление и очистку.
Встраиваемый виджетПоиск по каталогу, карточки, подтверждение количества перед добавлением, просмотр серверной корзины. Стили изолированы через Shadow DOM.
Обработка ошибокТайм-ауты запросов, сообщения о недоступности сервисов, повтор поиска/отправки через интерфейс.
Демо без backendОсновная страница умеет искать по трём встроенным тестовым товарам и хранить локальную корзину в браузере. Ограничение демочата описано ниже.

Системный промпт предписывает агенту отвечать на языке покупателя, уточнять параметры, не выдумывать товары, цены и наличие и показывать не более трёх вариантов. Это инструкции модели, а не программная гарантия корректности ответа.

Основания: основная страница, виджет, агент, промпт.

Как работает решение

  1. Покупатель открывает основную страницу и пишет, например: «Найди автомат на 16 А».
  2. Frontend передаёт текст и историю диалога в POST /api/chat.
  3. Backend вызывает AI-агента. При вызове моделью search_products агент получает товары через модуль поиска backend.
  4. Backend запрашивает страницы каталога EKT с HTTP Basic Auth. Поиск сопоставляет слова запроса с названием и артикулом и ранжирует товары по числу совпадений.
  5. Агент передаёт результат поиска модели и получает текстовый ответ. Backend возвращает answer и обновлённую history.
  6. Для просмотра карточек покупатель использует отдельную форму поиска либо плавающий виджет. Frontend дополнительно запрашивает детали найденных товаров.
  7. После нажатия «В корзину» и подтверждения backend проверяет количество по данным каталога и обновляет свою демо-корзину.

Текст AI и карточки — разные потоки: ответ /api/chat сам по себе не заполняет панель карточек. Плавающий виджет обращается к поиску напрямую и не вызывает AI.

Технологии

СлойИспользуемые технологии
FrontendJavaScript, React, React DOM, Vite, CSS, lucide-react, браузерный Fetch API
BackendPython, FastAPI, Pydantic, Uvicorn, Requests, python-dotenv
AIPython SDK openai, Responses API, модель gpt-5-mini, function calling
ДанныеВнешний HTTP API каталога EKT; кеш каталога и серверная корзина в памяти процесса
Проверкиunittest, unittest.mock, сборки Vite

В frontend/package-lock.json зафиксированы React/React DOM 19.3.0, Vite 8.3.0, @vitejs/plugin-react 6.1.1 и lucide-react 1.47.0. В package.json зависимости указаны как latest, поэтому для воспроизводимой установки используется npm ci.

Python-зависимости не закреплены по версиям. В backend/requirements.txt перечислены fastapi, uvicorn, requests, python-dotenv; ai/requirements.txt пуст. Пакет openai, импортируемый приложением, необходимо установить отдельно.

Основания: package.json, package-lock.json, backend/requirements.txt.

Архитектура

Основная страница React
  ├─ AI-чат → POST /api/chat → ai.agent → OpenAI Responses API
  │                              └─ search_products → backend.products
  ├─ Поиск → GET /api/search ────────────────────────────┘
  ├─ Карточки → GET /api/products/{id} → backend.ekt_api → API EKT
  └─ Корзина → /api/cart... → backend.cart → память процесса

Плавающий виджет React / Shadow DOM
  └─ Поиск, детали и корзина → те же HTTP endpoints backend

backend.products → кеш на 60 секунд → backend.ekt_api → API EKT
ai/
  agent.py                 # OpenAI-клиент, инструмент поиска, консольный чат
  prompts.py               # Инструкции консультанта
  tools.py                 # Связь AI с поиском backend
  requirements.txt         # Пока пуст
backend/
  main.py                  # FastAPI, маршруты, обработка ошибок
  ekt_api.py               # Запросы к внешнему каталогу
  products.py              # Поиск, ранжирование, кеш
  cart.py                  # Общая корзина в памяти
  models.py                # Пока пуст
  test_reliability.py       # Тесты кеша и ошибок чата
  requirements.txt
frontend/
  src/main.jsx             # Основная страница
  src/api.js               # Запросы AI-чата
  src/catalog.js           # Поиск и загрузка деталей
  src/widget/              # Виджет, карточки, корзина, выбор вложений
  vite.widget.config.js    # Отдельная сборка widget.js
  package.json
  package-lock.json

AI — модуль того же Python-приложения, а не отдельный HTTP-сервис. База данных, векторное хранилище и очередь задач в прикладном коде не подключены.

Установка и запуск

1. Подготовить окружение

Нужны Git для клонирования, Python, Node.js и npm, а для полноценной демонстрации — доступ к OpenAI и API каталога EKT.

  • Для повторения исходного окружения можно использовать Python 3.12: включённое в репозиторий окружение было создано на 3.12.3. Формальный диапазон поддерживаемых версий Python проект не задаёт.
  • Для frontend используйте Node.js 22.12 или новее. В lock-файле Vite и его React-плагин требуют ^20.19.0 || >=22.12.0.
  • Не используйте включённый в архив backend/venv: он содержит пути к компьютеру автора. Создайте новое окружение.

Ниже команды для Windows PowerShell. Если команда py -3.12 сообщает No suitable Python runtime found, сначала установите Python 3.12; наличие .venv не устанавливает отсутствующий интерпретатор. Доступные версии показывает py --list.

git clone https://github.com/BAITC-Hacks/hack-3b719372-avengers.git
cd hack-3b719372-avengers
py -3.12 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r backend/requirements.txt
.\.venv\Scripts\python.exe -m pip install openai

При работе с ZIP распакуйте его и откройте терминал в папке с ai, backend и frontend; вместо клонирования выполните команды начиная с создания .venv. Активация окружения не нужна: команды используют его интерпретатор напрямую.

2. Настроить доступ к сервисам

Локально создайте или отредактируйте ai/.env:

OPENAI_API_KEY=YOUR_OPENAI_API_KEY

Локально создайте или отредактируйте backend/.env:

EKT_API_URL=https://your-catalog-api.example/base
EKT_API_USERNAME=YOUR_EKT_USERNAME
EKT_API_PASSWORD=YOUR_EKT_PASSWORD

Это заполнители, не рабочие учётные данные. Адрес базового API и доступ выдаёт владелец интеграции. EKT_API_URL укажите без завершающего /: код добавляет /products и /products/detail самостоятельно. Для OpenAI нужен ключ с доступом к используемой модели и доступной квотой.

ПеременнаяГде используется
OPENAI_API_KEYOpenAI SDK; ai/agent.py загружает ai/.env
EKT_API_URLБазовый URL каталога; backend/ekt_api.py
EKT_API_USERNAMEИмя пользователя для HTTP Basic Auth
EKT_API_PASSWORDПароль для HTTP Basic Auth
VITE_API_URLАдрес backend для frontend (локальный или публичный), задаётся при запуске/сборке Vite

Секреты должны оставаться на стороне backend. Не помещайте ключ OpenAI или пароль EKT в переменные VITE_*, HTML или исходники frontend. В поставке уже присутствуют .env; не переносите их значения в README и не публикуйте свои ключи. Если находящиеся в Git значения действующие, их следует заменить у провайдера. frontend/.gitignore не защищает файлы в соседних ai/ и backend/ и содержит маркеры конфликта слияния.

3. Запустить backend

Из корня проекта:

.\.venv\Scripts\python.exe -m uvicorn backend.main:app --host 127.0.0.1 --port 8000 --reload

OpenAI-клиент создаётся при импорте приложения, поэтому без OPENAI_API_KEY запуск может завершиться ошибкой ещё до обращения к чату. Успешный /health подтверждает работу приложения, но не проверяет доступность EKT или OpenAI.

4. Запустить frontend

Во втором терминале, из корня проекта:

cd frontend
npm ci
$env:VITE_API_URL = "http://127.0.0.1:8000"
npm run dev -- --host 127.0.0.1 --port 5173

Откройте адрес, напечатанный Vite; при свободном порте это http://127.0.0.1:5173. Оставьте оба терминала работающими: закрытие процесса backend или frontend остановит соответствующую часть приложения.

Вместо переменной терминала можно создать frontend/.env.local с VITE_API_URL=http://127.0.0.1:8000. После изменения настройки перезапустите Vite. Если адрес пуст, основная страница переходит в деморежим, а виджет не выполняет реальный поиск.

5. Собрать frontend и виджет

В каталоге frontend, с настроенным VITE_API_URL:

npm run build
npm run build:widget
npm run preview -- --host 127.0.0.1 --port 4173

Основная сборка попадает в frontend/dist, отдельный виджет — в frontend/dist-widget/widget.js. preview предназначен для локальной проверки основной сборки; backend запускается отдельно.

Пример подключения виджета после размещения widget.js на своей странице:

<script
  src="/widget.js"
  data-ekt-widget
  data-api-base="http://127.0.0.1:8000"
></script>

Это пример локальной интеграции. Адрес backend для отдельного виджета задаётся во время загрузки через data-api-base. Основная страница уже монтирует виджет сама.

Основания: настройка API, frontend API, точка входа виджета, конфигурация сборки.

Как проверить решение жюри

Сценарий с подключёнными сервисами

  1. Запустите backend и frontend по инструкции выше.
  2. Проверьте /health: ожидается {"status":"healthy"}.
  3. В отдельной форме каталога найдите товар по известному артикулу из доступного каталога. Если артикула нет, попробуйте короткий запрос «автомат». Конкретные результаты зависят от данных API и охваченных поиском страниц.
  4. Откройте «Характеристики и склады» у результата. Проверьте отображение цены, наличия и доступных параметров. Отсутствующие сведения не должны восприниматься как подтверждённые.
  5. Выберите доступный товар с указанной ценой, нажмите «В корзину», подтвердите добавление и откройте корзину. Должны появиться позиция, количество и сумма. Реальный заказ при этом не создаётся.
  6. В основном AI-чате отправьте «Найди автомат на 16 А», затем уточните запрос. Ожидается текстовый ответ от модели; точное содержание заранее не фиксируется.
  7. Откройте плавающий «Помощник EKT» и выполните поиск по артикулу. Это проверка отдельного поискового виджета, а не ещё одного AI-чата.

Без доступа к внешним сервисам можно проверить только демопоиск основной страницы: уберите VITE_API_URL из окружения и .env.local, перезапустите Vite и найдите Schneider. Результат берётся из встроенных тестовых данных. Демо-корзина хранится в localStorage; её цены и наличие не являются данными EKT.

Проверка HTTP API

Invoke-RestMethod "http://127.0.0.1:8000/health"
$query = [uri]::EscapeDataString("автомат")
Invoke-RestMethod "http://127.0.0.1:8000/api/search?q=$query"

$payload = @{ message = "Найди автомат на 16 А"; history = @() } | ConvertTo-Json -Depth 10
Invoke-RestMethod -Method Post -Uri "http://127.0.0.1:8000/api/chat" -ContentType "application/json; charset=utf-8" -Body ([System.Text.Encoding]::UTF8.GetBytes($payload))

Для следующего сообщения передайте массив history из предыдущего ответа. Endpoint чата возвращает answer и history, а не массив карточек товаров.

Автоматические проверки

Из корня проекта, после установки Python-зависимостей:

$env:OPENAI_API_KEY = "test-placeholder"
.\.venv\Scripts\python.exe -m unittest backend.test_reliability -v
Remove-Item Env:OPENAI_API_KEY

Запускайте этот блок в отдельном тестовом терминале. Временное значение нужно только для создания OpenAI-клиента при импорте; тесты подменяют сетевые зависимости и не требуют настоящего ключа. Удаление переменной позволяет при следующем запуске прочитать ключ из ai/.env.

В файле три тестовых метода: совместное использование кеша при параллельном поиске и ранжирование, обновление кеша после истечения срока и ошибки, безопасные HTTP-ошибки чата. Это не полная проверка приложения: тесты не проверяют реальную сеть, качество ответов модели или браузерный сценарий. В package.json нет команды test; доступны команды сборки.

При подготовке этого README выполнено статическое изучение исходников и сравнение архива с GitHub. Установка зависимостей, сборки, тесты и сквозной запуск с реальными ключами в рамках подготовки документа не выполнялись; приведённые команды не являются отчётом об успешном прогоне.

Основание: backend/test_reliability.py.

HTTP API

МетодПутьНазначение
GET/Статус backend и сообщение
GET/healthСтатус процесса
GET/api/products?page=1Страница внешнего каталога
GET/api/products/{product_id}Детали товара
GET/api/search?q=...Поиск; ответ содержит query, count, products
POST/api/chatJSON с message и history; ответ с answer и history
GET/api/cartКорзина: items, total, items_count
POST/api/cart/add?product_id=...&quantity=1Добавить товар
PATCH/api/cart/{product_id}?quantity=...Изменить количество; 0 удаляет позицию
DELETE/api/cart/{product_id}Удалить позицию
DELETE/api/cartОчистить общую корзину

Параметры добавления и изменения количества передаются в query string, а не JSON. Изменения корзины затрагивают общую демо-корзину текущего процесса.

Для чата предусмотрены ответы 504 при тайм-ауте, 503 при лимите/квоте OpenAI, 502 при ошибке внешней зависимости и 500 при неожиданной ошибке. Это поведение маршрута, не результат проверки доступности конкретных сервисов.

Основание: backend/main.py.

Данные и интеграции

  • Каталог EKT: backend обращается к ${EKT_API_URL}/products?page=... и ${EKT_API_URL}/products/detail?id=... с HTTP Basic Auth. Подключённый адрес определяется локальной настройкой; домен ekt.kz сам по себе не является подтверждённым адресом этого API.
  • OpenAI: агент отправляет историю диалога, а при поиске — также найденные записи каталога, в Responses API. Модель указана в коде как gpt-5-mini.
  • История: frontend хранит её в состоянии React и передаёт с каждым запросом. Постоянное серверное хранилище диалогов не реализовано.
  • Кеш: поисковый каталог хранится в памяти на 60 секунд. Обновление страниц выполняется пулом до пяти потоков с блокировкой одновременного обновления.
  • Тестовые данные: три товара в frontend/src/main.jsx используются только в демопоиске. TEST_PRODUCTS в ai/tools.py не используется текущей функцией поиска и не служит резервным каталогом при ошибке API.

Основания: поиск и кеш, AI-инструмент, загрузка деталей на frontend.

Ограничения текущей версии

  1. Корзина не персональная и не постоянная. Она хранится в глобальном словаре Python, общая для запросов одного процесса и теряется при перезапуске. Несколько процессов будут иметь разные корзины. Авторизация пользователей и сессионное разделение не реализованы.
  2. Нет оформления заказа. Backend не отправляет корзину в магазин; платёжные, заказные и доставочные endpoints отсутствуют.
  3. AI не управляет корзиной. Единственный инструмент агента — search_products. Отдельного инструмента получения деталей товара у модели также нет. Упоминание подтверждения корзины в промпте не добавляет эту возможность.
  4. Поиск ограничен. По умолчанию загружаются первые 10 страниц; возвращается максимум 20 результатов. Это совпадение слов по подстрокам названия и артикула, без семантического поиска, морфологии и проверки технической совместимости. Пустой результат не доказывает отсутствие товара во всём каталоге.
  5. AI-ответ и карточки не синхронизированы автоматически. Карточки формируются отдельным поиском; виджет не подключён к /api/chat.
  6. Редактирование серверной корзины ограничено в UI. Основная страница отключает изменение количества и удаление при подключённом backend, хотя соответствующие API-маршруты есть. Виджет позволяет выбрать количество при добавлении и просмотреть корзину.
  7. Вложения не отправляются. Виджет проверяет расширение и размер до 10 МБ для JPEG, PDF, Excel и Word, показывает предпросмотр JPEG, но загрузка и обработка файлов отсутствуют. Выбранное вложение блокирует отправку текста до удаления.
  8. Демочат содержит несогласованность полей. Демоответ создаётся с полем message, а вывод читает answer, поэтому без backend ответ может отображаться пустым. Демо следует показывать через поиск тестовых товаров, не как работающую AI-консультацию.
  9. Нет полной изоляции и защиты публичного сервиса. CORS разрешает все origins, собственная авторизация и ограничение частоты запросов отсутствуют. Перед публичным запуском это требует доработки. Ошибки маршрутов каталога включают строку исключения внешнего запроса.
  10. Окружение требует подготовки. Python-зависимости не закреплены, openai отсутствует в requirements, в поставке есть виртуальное окружение и .env, а frontend/.gitignore содержит маркеры конфликта. Установка в чистое окружение обязательна для корректной проверки переносимости.
  11. Нет подтверждённых метрик качества. В исходниках нет результатов оценки точности рекомендаций, нагрузочных измерений или доказательства работы всей цепочки на реальных сервисах. История диалога не ограничивается по длине на backend.

Основания: корзина, вложения, а также исходники frontend, агента и API, указанные выше.

Развёрнутая версия и локальная демонстрация

Подтверждённая публичная ссылка на работающую версию проекта в проверенных исходниках не найдена. Для демонстрации используйте локальный запуск. ekt.kz — целевой магазин, а не подтверждённый deployment этого прототипа.

Для запуска на своём компьютере хостинг не нужен: frontend и backend запускаются локально по инструкции выше. Для реального каталога и AI-консультации необходимы интернет и настроенные доступы к EKT и OpenAI.

В общей «Инструкции для участников HackAlem AI» (стр. 1–2) ссылка на развёрнутую версию запрашивается «если она есть». Общая инструкция требует разместить итоговый код в выданном команде GitHub-репозитории, подготовить README и сдать решение через платформу; обязательный публичный хостинг в ней не указан. Дополнительные требования конкретного кейса EKT необходимо сверить с его заданием.

Звёзды
⭐ 0
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
23
Авторы
6
Файлы
33
Ветки
3

Авторы коммитов

Yerbol Alikhan 10alikhanov0 4Agadil 3nurlybekuly 3dias23nuly 2agadil 1

История коммитов

  • 2026-09-23 17:40Update README.mddias23nuly
  • 2026-09-23 17:34Update README.mdagadil
  • 2026-09-23 17:31Delete ai/.envalikhanov0
  • 2026-09-23 17:31Delete backend/.envalikhanov0
  • 2026-09-23 17:30Merge branch 'main' of https://github.com/BAITC-Hacks/hack-3b719372-avengersYerbol Alikhan
  • 2026-09-23 17:29Added readme, deleted filesYerbol Alikhan
  • 2026-09-23 17:24Delete ai/.envalikhanov0
  • 2026-09-23 17:23Delete backend/.envalikhanov0
Все коммиты (23)
  • 2026-09-23 17:20Add files via uploaddias23nuly
  • 2026-09-23 17:04Integrate backend AI and frontendYerbol Alikhan
  • 2026-09-23 16:54Fix product image overflow in catalog and cartAgadil
  • 2026-09-23 16:32last buildYerbol Alikhan
  • 2026-09-23 16:18Add embeddable chat widget, product details and server cartAgadil
  • 2026-09-23 15:56little changesYerbol Alikhan
  • 2026-09-23 15:56Merge remote-tracking branch 'origin/ai-agent'Yerbol Alikhan
  • 2026-09-23 15:49added endpointsYerbol Alikhan
  • 2026-09-23 14:58Merge main into ai-agentnurlybekuly
  • 2026-09-23 14:52backend main filesYerbol Alikhan
  • 2026-09-23 14:37Add AI product search toolnurlybekuly
  • 2026-09-23 14:34Add frontend storefront, AI chat and cartAgadil
  • 2026-09-23 14:31lcYerbol Alikhan
  • 2026-09-23 14:25Add initial AI agentnurlybekuly
  • 2026-09-23 13:58basic architecture, first filesYerbol Alikhan
Структура репозитория (33 файлов)
README.md
ai/__init__.py
ai/agent.py
ai/prompts.py
ai/requirements.txt
ai/tools.py
backend/__init__.py
backend/cart.py
backend/ekt_api.py
backend/main.py
backend/models.py
backend/products.py
backend/requirements.txt
backend/test_reliability.py
frontend/.env.example
frontend/.gitignore
frontend/WIDGET.md
frontend/index.html
frontend/package-lock.json
frontend/package.json
frontend/src/api.js
frontend/src/catalog.js
frontend/src/improvements.css
frontend/src/main.jsx
frontend/src/store.css
frontend/src/styles.css
frontend/src/widget/ChatWidget.jsx
frontend/src/widget/ProductDetails.jsx
frontend/src/widget/attachment.js
frontend/src/widget/cart.js
frontend/src/widget/entry.jsx
frontend/src/widget/widget.css
frontend/vite.widget.config.js
Ветки (3)

Обсуждение 0 комментариев

Войдите, чтобы комментировать

Пока нет комментариев — будьте первым.