AAYMA
RU
Войти

EKT Assistant

Каталог и чат-консультант для ekt.kz: поиск по артикулу и характеристикам, подбор аналогов по правилам категории, предупреждения о противоречиях…

Рабочий MVP
Команда «хюмандар» 3💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: хюмандар
Кейс HackAlem.ai: Торговля — Электрокомплект · ekt.kz
Стадия: Рабочий MVP

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

Суть

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

Как устроено

React-фронтенд обращается к FastAPI. LLM-агент (OpenAI Responses, gpt-4.1-mini) вызывает инструменты поиска и получения карточек, данные берутся из снимка каталога или живого API ekt.kz с Basic Auth. Аналоги проверяются правилами категории: совпадения, различия, недостающие данные. XLSX, DOCX и PDF разбираются на сервере в редактируемый черновик, JPEG и PNG распознаёт модель. Добавление в корзину идёт через предложение и отдельное подтверждение с проверкой цены и остатка; сессии, история и корзина хранятся в SQLite, есть CSRF-защита.

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

  • function calling
  • rule-based analog matching
  • contradiction detection
  • document parsing (openpyxl/python-docx/pypdf)
  • image recognition
  • CSRF

Особенности

Доступный к продаже остаток отделён от общего quantity: пока ID складов не подтверждены, доступность считается неизвестной. Есть демо-режим с синтетическими товарами без ключа. При этом в репозитории всего 5 коммитов, по истории процесс разработки не восстановить.

Стек

Python · FastAPI · Pydantic · SQLite · httpx · TypeScript · React 19 · Vite 6 · pytest

Модели

GPT-4.1-mini


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

README

README.md

1. Название проекта

EKT Assistant — ИИ-ассистент для интернет-магазина электротехники ekt.kz.

Прототип для HackAlem AI: каталог, чат-консультант, обработка списков товаров и демонстрационная корзина.

2. Краткое описание

Покупателям электротехники нужно находить товары по артикулам и характеристикам, сравнивать варианты и собирать список покупок. Данные могут содержать противоречия, а наличие на складе не всегда означает доступность для продажи.

EKT Assistant помогает частным покупателям, монтажникам и специалистам по закупкам искать позиции обычным текстом или загружать спецификацию. Ассистент показывает сведения каталога, предупреждает о неизвестных и противоречивых характеристиках и предлагает подтвердить выбранные позиции.

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

  • Каталог с поиском, ценами в тенге, описаниями и остатками по складам.
  • Плавающий чат с ИИ: поиск по названию и артикулу, уточнение запроса, просмотр характеристик и подбор кандидатов на замену.
  • Проверка аналогов по правилам категории с указанием совпадений, различий и недостающих данных.
  • Выявление противоречий: например, у товара 027228 в источниках указаны значения тока 160 и 250 А.
  • Загрузка XLSX, DOCX и PDF с текстом; интеграция распознавания JPEG/PNG через модель с поддержкой изображений.
  • Редактируемый черновик распознанных позиций и количеств. Загрузка файла сама по себе не меняет корзину.
  • Локальная корзина: предложение → отдельное подтверждение → добавление. Повторное подтверждение не дублирует позицию.
  • Серверные сессии, CSRF-проверка, проверка цены и доступного остатка при подтверждении.
  • Явный демо-режим без ключа модели и три синтетических товара для воспроизводимого показа.

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

  1. Пользователь открывает каталог и чат, вводит запрос, выбирает товар или загружает список позиций.
  2. Сервер обрабатывает запрос; для файлов извлекает названия и количества в черновик для проверки.
  3. ИИ вызывает инструменты поиска и получения карточек. Сведения о товарах берутся из каталога.
  4. Интерфейс показывает ответ, карточки, остатки и предупреждения. При неоднозначном запросе пользователь уточняет выбор.
  5. Пользователь выбирает товар и количество. Сервер формирует предложение добавления.
  6. После отдельного подтверждения позиция появляется в локальной корзине /cart. Реальный заказ на ekt.kz не отправляется.

5. Технологии

КомпонентТехнологии
ИнтерфейсTypeScript, React 19, Vite 6, CSS, lucide-react
СерверPython, FastAPI, Uvicorn, Pydantic
ИИOpenAI Responses API, Python SDK openai, модель по умолчанию gpt-4.1-mini, вызов инструментов
КаталогAPI ekt.kz, HTTP Basic Auth, httpx, локальные JSON-снимки
ХранениеSQLite: сессии, история, предложения и демонстрационная корзина
Файлыopenpyxl, python-docx, pypdf, Pillow
Настройки и проверкиpython-dotenv, pytest, TypeScript, тесты контрактов на Node.js

Версии Python-зависимостей закреплены в requirements.txt, зависимости интерфейса — в frontend/package.json и frontend/package-lock.json.

6. Архитектура проекта

Браузер: React-каталог, чат, черновик, корзина
                     │ HTTP /api
                     ▼
                  FastAPI
         ┌───────────┼─────────────┐
         ▼           ▼             ▼
     ИИ-агент     Каталог       Обработка файлов
         │       JSON/API      текст / модель
         ▼           │
 OpenAI Responses    ▼
                   ekt.kz

FastAPI → проверка предложения и подтверждения → SQLite
  • frontend/ — интерфейс; src/services/backendApi.ts связывает его с сервером; dist/ содержит готовую сборку.
  • backend/ — HTTP API, нормализация каталога, обработка файлов и локальная корзина. Точка входа объединённого приложения — backend/server.py; отдельный ранний бэкенд команды сохранён в backend/app/.
  • agent/ — ИИ-агент, инструменты и правила подбора аналогов.
  • data/ — исходные данные, снимок каталога и синтетические товары.
  • tests/, frontend/tests/ — серверные тесты и проверки интерфейсных контрактов.
  • docs/ — дополнительные контракты и отчёты разработки.
  • var/ — создаваемая при запуске база SQLite; не включается в Git.
  • import_catalog.py — импорт каталога; start.ps1 — запуск приложения.

FastAPI раздаёт API и собранный интерфейс с одного адреса. Добавление проходит через /api/proposals и /api/proposals/{id}/confirm. Ключи внешних сервисов находятся только на сервере.

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

Нужны Python 3.11+ и интернет для установки зависимостей. Для сборки и разработки интерфейса нужны Node.js 22.12+ и npm. Если frontend/dist/ присутствует, для обычного запуска сборка не требуется. Для ответов ИИ нужен доступ к OpenAI API; без него работает демо-режим.

Команды ниже выполняются в PowerShell из корня проекта.

Шаг 1. Создать настройки, не перезаписывая существующий .env:

if (-not (Test-Path .env)) { Copy-Item .env.example .env }

В корневом .env задать:

AGENT_MODE=auto
OPENAI_API_KEY=
OPENAI_MODEL=gpt-4.1-mini
CATALOG_MODE=snapshot
EKT_CURRENCY=KZT
EKT_API_USER=
EKT_API_PASSWORD=
EKT_SELLABLE_STORE_IDS=
COOKIE_SECURE=0

Для ИИ заполнить OPENAI_API_KEY своим ключом. Для показа без модели задать AGENT_MODE=demo. Файл .env исключён из Git; ключи не размещаются в frontend или переменных VITE_*.

Шаг 2. Запустить приложение:

.\start.ps1

Скрипт создаёт .venv, устанавливает Python-зависимости, при отсутствии сборки собирает интерфейс и запускает сервер.

Альтернатива — ручной запуск:

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
# Следующие четыре команды нужны, если нет frontend/dist или интерфейс изменён:
Push-Location frontend
npm.cmd ci
npm.cmd run build
Pop-Location
.\.venv\Scripts\python.exe -m uvicorn backend.server:app --host 127.0.0.1 --port 8765

Шаг 3. Открыть приложение:

Остановка сервера — Ctrl+C. Если порт занят, сначала остановить предыдущий экземпляр.

Для разработки интерфейса запустить backend, затем в другом терминале:

cd frontend
npm.cmd ci
npm.cmd run dev

Открыть адрес, который напечатает Vite. Запросы /api проксируются на порт 8765. После изменений для обычного запуска снова выполнить npm.cmd run build из frontend. Если ограниченное окружение блокирует загрузчик конфигурации, использовать npm.cmd run build -- --configLoader runner.

8. Как проверить решение

Для проверки жюри достаточно режима CATALOG_MODE=snapshot. Основной сценарий не требует доступа к API магазина; для диалога с моделью нужен ключ OpenAI. Без ключа доступны демонстрационные сценарии.

  1. Открыть главную страницу и найти 027228. Ожидается карточка Legrand с ценой 64 920 ₸.
  2. Открыть чат и написать: «Покажи 027228». Ожидаются сведения о товаре и предупреждение о расхождении 160/250 А; совместимость не должна подтверждаться без уточнения.
  3. Написать: «Найди DEMO-B16», затем попросить добавить 2 штуки. Ожидается предложение с товаром и количеством.
  4. Нажать отдельную кнопку подтверждения и открыть /cart. В новой сессии ожидается 2 шт. DEMO-B16. Для повторного показа с пустой корзиной открыть приложение в приватном окне; «Новый диалог» корзину не очищает.
  5. Дополнительно загрузить XLSX с колонками Артикул и Количество, строкой DEMO-B16 и числом 2. Ожидается редактируемый черновик; автоматического добавления в корзину нет.
  6. При настроенном ключе загрузить JPEG/PNG с читаемым списком товаров. Проверить названия и количества вручную: качество распознавания реальных фото ещё требует отдельной оценки.

В снимке реальный товар не добавляется в корзину: актуальный доступный остаток неизвестен. Это ожидаемое поведение; для проверки подтверждения предусмотрен DEMO-B16.

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

.\.venv\Scripts\python.exe -m pytest -q
Push-Location frontend
npm.cmd ci
npm.cmd test
npm.cmd run build
Pop-Location

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

В поставку входят сохранённые карточки 40 реальных товаров и 3 синтетических демо-товара. Полный каталог не импортирован.

API ekt.kz использует Basic Auth:

  • GET https://ekt.kz/api/products — список товаров.
  • GET https://ekt.kz/api/products?page=2 — следующая страница.
  • GET https://ekt.kz/api/products/detail?id=515291 — подробная карточка.

Сервер поддерживает импорт страниц и обновление карточек. CATALOG_MODE=live включает обращения за свежими карточками; нужны EKT_API_USER и EKT_API_PASSWORD. Переключение режима само по себе не загружает весь каталог: поиск работает по импортированной выборке.

Для отдельного импорта первых двух страниц после настройки доступа:

.\.venv\Scripts\python.exe import_catalog.py --pages 2 --force

После импорта перезапустить сервер. Число страниц задаётся параметром --pages; два — ограничение примера, а не полный каталог.

Для расчёта доступного к продаже остатка отдельно задаются подтверждённые магазином ID в EKT_SELLABLE_STORE_IDS. Пока список пуст, доступность для продажи считается неизвестной. Общий остаток quantity не заменяет это подтверждение.

В исходных карточках валюта отсутствует. По настройке проекта EKT_CURRENCY=KZT такие цены обозначаются в тенге без пересчёта суммы; источник валюты отмечается как project_config. Синтетические товары используют условную единицу DEMO.

OpenAI Responses API используется для диалога и распознавания изображений. При включённом ИИ запросы пользователя, необходимые сведения каталога и загруженные для распознавания фото передаются этому сервису. Документы XLSX/DOCX/PDF сначала разбираются на сервере. Изображения товаров загружаются с ekt.kz.

10. Ограничения

  • Локальная корзина не связана с настоящими заказами ekt.kz. Оплата, резервирование, доставка и авторизация покупателей магазина не реализованы.
  • Каталог ограничен импортированными данными. Снимок не гарантирует актуальность цен и остатков; полный импорт и периодическая синхронизация требуют настройки.
  • Подтверждённый список складов для продажи и правила магазина не предоставлены. Название склада само по себе не является разрешением на продажу.
  • Некоторые характеристики противоречат друг другу; сертификаты и условия показываются только при наличии источника. Подбор аналогов не гарантирует электротехническую совместимость.
  • До 3 вложений за отправку в интерфейсе, до 5 МБ на файл. Изображения — до 12 млн пикселей. Извлечение ограничено 50 позициями на файл; большие документы следует делить.
  • Сканированный PDF без текстового слоя напрямую не распознаётся: страницы нужно загрузить как JPEG/PNG. Для фото нужен ключ модели; точность OCR на реальных материалах отдельно не оценена.
  • Работа без ключа модели ограничена демонстрационной логикой. Ответы ИИ и распознанные позиции требуют проверки пользователем.
  • Встраивание в настоящий ekt.kz и публичное развёртывание не выполнены. Текущая политика сервера запрещает внешнее iframe-встраивание. Для размещения нужны согласованные настройки HTTPS, origin и cookies.
  • Нагрузочное тестирование и подготовка к промышленной эксплуатации не выполнены. Локальный запуск подходит для демонстрации на одном компьютере.
Звёзды
⭐ 0
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
5
Авторы
3
Файлы
96
Ветки
1

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

Damir 3bizbenbilimgmail.com 1Ruslankyzy-Aldina 1

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

  • 2026-09-23 17:48feat: finalDamir
  • 2026-09-23 17:47feat: final addDamir
  • 2026-09-23 17:29feat: add backendbizbenbilimgmail.com
  • 2026-09-23 16:11front commitRuslankyzy-Aldina
  • 2026-09-23 11:05checkDamir
Структура репозитория (96 файлов)
.DS_Store
.env.example
.gitignore
README.md
agent/__init__.py
agent/analogs.py
agent/service.py
backend/.env.example
backend/.gitignore
backend/Makefile
backend/README.md
backend/VERIFICATION.md
backend/__init__.py
backend/app/__init__.py
backend/app/api/__init__.py
backend/app/api/health.py
backend/app/api/products.py
backend/app/clients/__init__.py
backend/app/clients/ekt_client.py
backend/app/config.py
backend/app/dependencies.py
backend/app/exceptions.py
backend/app/fixtures/product_515291.json
backend/app/main.py
backend/app/schemas/__init__.py
backend/app/schemas/product.py
backend/app/services/__init__.py
backend/app/services/normalization.py
backend/app/services/product_service.py
backend/attachments.py
backend/cart.py
backend/catalog.py
backend/normalize.py
backend/package-test-results.txt
backend/pytest.ini
backend/requirements.txt
backend/server.py
backend/smoke-results.json
backend/test-results.txt
backend/tests/conftest.py
backend/tests/test_api.py
backend/tests/test_config.py
backend/tests/test_ekt_client.py
backend/tests/test_normalization.py
data/catalog-cache.json
data/demo.json
data/live-detail.json
data/live-page1.json
data/page1.json
data/page2.json
docs/CONTRACT.md
docs/INTEGRATION.md
docs/VERIFICATION.md
docs/benchmark.json
docs/live-benchmark.json
frontend/.env.example
frontend/.gitignore
frontend/README.md
frontend/index.html
frontend/package-lock.json
frontend/package.json
frontend/public/embed.js
frontend/src/app/App.tsx
frontend/src/components/CartDialog.tsx
frontend/src/components/ProductCard.tsx
frontend/src/components/ProposalPanel.tsx
frontend/src/components/UploadReview.tsx
frontend/src/components/chat/ChatWidget.tsx
frontend/src/components/chat/MessageComposer.tsx
frontend/src/components/chat/MessageList.tsx
frontend/src/components/s
frontend/src/data/.gitkeep
frontend/src/data/catalog-page-1.json
frontend/src/data/catalog-page-2.json
frontend/src/data/product-515291.json
frontend/src/hooks/useChat.ts
frontend/src/main.tsx
frontend/src/pages/CartPage.tsx
frontend/src/pages/ChatPage.tsx
frontend/src/services/backendApi.ts
frontend/src/services/catalog.ts
frontend/src/services/chatApi.ts
frontend/src/services/comparison.ts
frontend/src/styles/global.css
frontend/src/styles/widget.css
frontend/src/types/chat.ts
frontend/tests/contracts.mjs
frontend/tsconfig.json
frontend/vite.config.ts
import_catalog.py
pytest.ini
requirements.txt
start.ps1
tests/benchmark.py
tests/test_frontend_integration.py
tests/test_system.py

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

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

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