О проекте
Команда: SherkhanDev
Кейс HackAlem.ai: Торговля — Электрокомплект · ekt.kz
Стадия: Рабочий MVP
Задача кейса: AI-консультант по каталогу ekt.kz: товары, аналоги, цены, остатки, корзина
Суть
AI-консультант по каталогу ekt.kz с чатом. Ищет товары по артикулу и параметрам, проверяет остатки по складам, подбирает технические аналоги и добавляет товары в корзину с подтверждением пользователя.
Как устроено
FastAPI-сервис с AgentService на OpenAI Responses API. Модель вызывает инструменты CatalogService (SQLite с fixture-каталогом или живой HTTP API EKT), ConditionsService (get_purchase_conditions: минимальная партия, доставка, оплата) и CartService. Аналоги подбираются алгоритмически по номиналам, полюсам и характеристике срабатывания. Добавление в корзину идёт в две фазы: сервер создаёт Pending Action с таймером, пользователь явно подтверждает, повторное подтверждение идемпотентно. Корзину можно открыть по read-only ссылке с токеном. Фронтенд на Vanilla JS, двухколоночный интерфейс «чат + склад и корзина».
Ключевые решения
- function calling
- OpenAI Responses API
- two-phase commit корзины
- алгоритмический подбор аналогов
- read-only токен просмотра
Особенности
LLM только предлагает действие с корзиной, а применяет его сервер после явного подтверждения (Pending Action с TTL, идемпотентность), что защищает от галлюцинаций. Отдельно различаются «нет на складе» и «остаток неизвестен», проверяется кратность отгрузки. 45 тестов, включая тест конкурентного доступа к корзине.
Стек
Python · FastAPI · SQLite · Pydantic Settings · Vanilla JS · HTML/CSS · pytest
Модели
OpenAI (Responses API)
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-84dbe8eb-sherkhandev.
README
README.mdEKT AI — Интеллектуальный B2B-консультант по каталогу электротоваров
Интеллектуальная система подбора электротехнической продукции, проверки складских остатков в реальном времени и безопасного формирования заказа.
Быстрый старт • Демо-сценарии • Архитектура • Веб-интерфейс • Тестирование
📌 О проекте
EKT AI — это прототип специализированного AI-консультанта для специалистов по закупкам, электриков и инженеров. Сервис объединяет в одном окне:
- Умный диалог: поиск по артикулу, названию и техническим параметрам.
- Точную валидацию остатков: различия между отсутствием на складе и неизвестным остатком, проверка кратности и шага отгрузки.
- Алгоритмический подбор аналогов: техническое сопоставление номиналов, характеристик срабатывания и отключающей способности.
- Безопасное добавление в корзину (Two-Phase Commit): подготовка проверяемого сервером предложения (Pending Action) с таймером действия и явное подтверждение пользователем.
- Защищённый просмотр заказа: генерация временной ссылки только для чтения (
read-only token) без передачи секретных токенов сессии.
⚡ Быстрый старт за 1 минуту
1. Клонирование и виртуальное окружение
cd backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt
2. Запуск в учебном режиме (Fixture)
Учебный режим работает автономно с локальной SQLite-базой и демонстрационным каталогом:
# Применение базовых настроек
set -a && source .env.example && set +a
# (Опционально) Установка ключа OpenAI для живого чата с моделью:
export OPENAI_API_KEY="sk-..."
# Запуск FastAPI сервера (один worker для SessionStore в памяти процесса)
python -m uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 1 --no-access-log
- 🌐 Интерфейс: http://127.0.0.1:8000/
- 📖 Swagger API Docs: http://127.0.0.1:8000/docs
- 🩺 Healthcheck: http://127.0.0.1:8000/health
[!NOTE] Без ключа OpenAI интерфейс, выбор складов и API корзины полноценно работают. При прямом запросе в чат возвращается HTTP
503 LLM_UNAVAILABLE, что позволяет проверить доступность всех сервисов бэкенда без сторонних ключей.
🖥️ Новый веб-интерфейс
Интерфейс спроектирован по стандартам современных корпоративных рабочих пространств (B2B Copilot):
┌────────────────────────────────────────────────────────────────────────┐
│ ⚡ EKT AI [B2B Copilot] ● Live-каталог подключён │
├─────────────────────────────────────────┬──────────────────────────────┤
│ 💬 ЧАТ-КОНСУЛЬТАНТ │ 🏬 РАБОЧИЙ СКЛАД │
│ │ [ Учебный склад ▼ ] │
│ ✦ Здравствуйте! Чем могу помочь? │ │
│ 👤 DEMO-001, 2 шт. ├──────────────────────────────┤
│ ✦ AI обрабатывает запрос... ● ● ● │ 🛒 КОРЗИНА ЗАКАЗА [1] │
│ │ • DEMO-001 (2 шт.) 2 400 ₸ │
│ ┌───────────────────────────────────┐ │ ──────────────────────────── │
│ │ ⚡ Карточка подтверждения │ │ Итого к оплате: 2 400 ₸ │
│ │ [✓ Подтвердить добавление] │ │ [Открыть ссылку просмотра ↗] │
│ └───────────────────────────────────┘ │ │
│ ├──────────────────────────────┤
│ [🛒 DEMO-001] [🔍 Поиск] [⚡ Аналоги] │ 💡 ПАМЯТКА │
│ ┌───────────────────────────┬─────────┐ │ • Двухэтапное подтверждение │
│ │ Введите артикул или вопрос│Отправить│ │ • Валидация остатков в реальном│
│ └───────────────────────────┴─────────┘ │ времени │
└─────────────────────────────────────────┴──────────────────────────────┘
Главные особенности UX:
- Двухколоночный макет (Split Workspace): постоянный контроль корзины и склада в правой панели во время диалога.
- Чипсы быстрых команд (Prompt Chips): интерактивные кнопки быстрого старта над полем ввода для проверки типовых кейсов в 1 клик.
- Индикатор Thinking: анимированный статус
AI обрабатывает запроспри обращении к серверу. - Информативные карточки товаров: наглядные теги характеристик, цена в KZT с разделителями, статус источника (
данные EKT/synthetic) и ссылки на сертификаты. - Адаптивность: корректное отображение на экранах от мобильных (360px) до ультрашироких мониторов.
🎯 Сценарии демонстрации для жюри
Сценарий 1: Сквозной цикл формирования заказа (End-to-End)
- Откройте http://127.0.0.1:8000/. В правой панели отобразится «Учебный склад».
- Нажмите быстрый чипс
🛒 DEMO-001, 2 шт.или отправьте это сообщение. - Сервер сформирует предложение на добавление с расчётом суммы (
2 шт. × 1200 KZT = 2400 KZT) и сроком действия (5 минут). - Нажмите кнопку «✓ Подтвердить добавление в корзину».
- Товар отобразится в корзине в правой панели с суммой
2 400 KZT. - Повторный клик подтверждения идемпотентен: позиция не дублируется.
- Нажмите «Безопасная ссылка просмотра» — откроется read-only страница корзины.
Сценарий 2: Подбор аналогов при нулевом остатке
- Нажмите чипс
⚡ Аналоги DEMO-002. - Исходный товар
DEMO-002имеет нулевой остаток на учебном складе. - Система сравнивает технические параметры (полюса, ток, характеристику) и предлагает
DEMO-003как совместимый аналог с положительным остатком, явно сообщая о различиях.
Сценарий 3: Проверка сертификатов
- Нажмите
📄 Сертификат DEMO-001. - В карточке товара отображается безопасная ссылка на локальный сертификат соответствия.
Сценарий 4: Условия закупки и доставки
- Нажмите
🚚 Условия доставки. - Модель вызывает инструмент
get_purchase_conditionsи возвращает правила минимальной партии, доставки и оплаты.
🏗️ Архитектура решения
flowchart TD
subgraph Frontend["Веб-интерфейс (Vanilla HTML / CSS / JS)"]
UI[Двухколоночный Shell]
Chat[Диалог и быстрые чипсы]
Sidebar[Панель склада и живой корзины]
end
subgraph Backend["FastAPI Backend (один worker)"]
API[HTTP API & Session Middleware]
Agent[AgentService / Responses API]
Catalog[CatalogService]
Conditions[ConditionsService]
Cart[CartService]
end
subgraph Storage["Хранилище данных"]
MemSession[(Память процесса: Сессии & Locks)]
CatDB[(SQLite: Каталог товаров)]
CartDB[(SQLite: Корзины & Предложения)]
JSONData[JSON: Fixture & Условия]
end
subgraph External["Внешние интеграции"]
OpenAI[OpenAI LLM API]
EKTAPI[EKT Live HTTP API]
end
UI --> API
Chat --> API
Sidebar --> API
API --> MemSession
API --> Agent
API --> Cart
Agent <--> OpenAI
Agent --> Catalog
Agent --> Conditions
Agent --> Cart
Catalog --> CatDB
Catalog --> JSONData
Catalog -.->|в режиме live| EKTAPI
Conditions --> JSONData
Cart --> CartDB
Cart -->|Валидация цен и остатка| Catalog
Структура проекта
.
├── backend/
│ ├── app/
│ │ ├── main.py # Запуск FastAPI, lifespan, статика
│ │ ├── config.py # Конфигурация Pydantic Settings
│ │ ├── contracts.py # Строгие DTO-модели (extra='forbid')
│ │ ├── dependencies.py # Инъекция зависимостей FastAPI
│ │ ├── sessions.py # Сессии в памяти и блокировки Lock
│ │ ├── agent/ # Интеграция с OpenAI Responses API
│ │ ├── api/ # HTTP-роутеры (chat, cart, sessions, health)
│ │ ├── catalog/ # Каталог: SQLite, Fixture и Live адаптер EKT
│ │ ├── conditions/ # Справочник условий покупки
│ │ └── cart/ # Предложения, подтверждения и генерация view-ссылок
│ ├── data/
│ │ ├── catalog/fixture.json # Демо-каталог учебных товаров
│ │ ├── conditions/ # JSON-файлы условий закупки
│ │ └── certificates/ # Демо-сертификаты
│ ├── scripts/
│ │ └── import_catalog.py # Скрипт импорта реальных карточек EKT
│ └── tests/ # 45 автоматических тестов (pytest)
└── web/
├── index.html # Разметка интерфейса
└── assets/
├── app.css # Стили, переменные, сетка и адаптивность
└── app.js # Клиентская логика, API-клиент и виджеты
🔌 Спецификация API
| Метод | Путь | Описание | Авторизация |
|---|---|---|---|
GET | / | Главный веб-интерфейс | Нет |
GET | /health | Статус приложения и активный режим каталога | Нет |
POST | /api/v1/sessions | Создание сессии и выдача session_token | Нет |
GET | /api/v1/warehouses | Список доступных складов | Bearer Token |
POST | /api/v1/chat | Отправка сообщения AI-консультанту | Bearer Token |
GET | /api/v1/cart | Получение содержимого корзины сессии | Bearer Token |
POST | /api/v1/cart/actions/{id}/confirm | Подтверждение добавления товара | Bearer Token |
GET | /cart/view/{view_token} | Read-only HTML-просмотр корзины | Токен в URL |
GET | /demo-certificates/{name} | Просмотр демонстрационного сертификата | Нет |
🔄 Режимы работы каталога
1. Учебный режим (CATALOG_MODE=fixture)
- Использует готовый датасет fixture.json.
- Доступны 3 синтетических автомата:
DEMO-001(1 200 KZT, остаток: 5 шт., есть сертификат).DEMO-002(1 300 KZT, остаток: 0 шт., для проверки подбора аналогов).DEMO-003(1 500 KZT, остаток: 10 шт., аналог для DEMO-002).
2. Live-режим с EKT API (CATALOG_MODE=live)
Для подключения реальных данных EKT с авторизацией Basic Auth:
export CATALOG_MODE=live
export EKT_DATA_DIR=/tmp/ekt-ai-live
export EKT_API_USERNAME='<логин_ekt>'
export EKT_API_PASSWORD='<пароль_ekt>'
# Импорт карточки товара по реальному ID EKT
python -m scripts.import_catalog --product-id 515291
# Запуск сервера с live-каталогом
python -m uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 1 --no-access-log
🧪 Тестирование и верификация
Набор тестов полностью изолирован от внешних сервисов и проверяет все уровни приложения:
# Запуск всех 45 тестов
PYTHONPATH=backend ./backend/.venv/bin/pytest backend/tests
# Запуск только сквозного интеграционного теста
PYTHONPATH=backend ./backend/.venv/bin/pytest backend/tests/integration/test_full_flow.py -v
Что проверяется:
- Инструменты агента: корректный парсинг аргументов, запрет вызова незарегистрированных функций.
- Каталог и склады: валидация DTO с
extra='forbid', отсутствие утечки внутренних полей. - Корзина и транзакции: идемпотентность подтверждения, проверка кратности и наличия остатков, генерация и коммит токена ссылки просмотра сразу в момент подтверждения.
- Параллелизм: защита от race conditions при одновременных подтверждениях.
🛡️ Безопасность и надёжность
- Защита от подмены: модель не имеет инструмента прямого изменения корзины. Действие фиксируется через строгий серверный
PendingActionс криптографическимaction_id. - Изоляция токенов:
session_tokenхранится только в памяти браузера, никогда не попадает в промпты LLM и не логируется. - Безопасные ссылки: сертификаты проверяются функцией валидации схемы (
isSafeCertUrl), предотвращая XSS. - Отключение URL-логов: флаг
--no-access-logисключает попадание одноразовых токенов корзины в журналы веб-сервера.
Разработано для хакатона HackAlemAI • 2026
Авторы коммитов
История коммитов
- 2026-09-23 17:52fix3Museki
- 2026-09-23 17:46designfixMuseki
- 2026-09-23 17:32fix2Museki
- 2026-09-23 17:14ReadmeNewMuseki
- 2026-09-23 17:00fixMuseki
- 2026-09-23 15:47BakhadyrcommitZendik-lab
- 2026-09-23 16:13Implement friend 3 taskErnur
- 2026-09-23 14:51v1.3Zendik-lab
Все коммиты (12)
- 2026-09-23 14:48Version 1.3Zendik-lab
- 2026-09-23 15:14Add EKT AI projectMuseki
- 2026-09-23 14:27Create v 1.2Yernurqz
- 2026-09-23 13:55v.1Museki
Структура репозитория (62 файлов)
.gitignore README.md backend/.env.example backend/app/__init__.py backend/app/agent/__init__.py backend/app/api/__init__.py backend/app/api/cart.py backend/app/api/catalog.py backend/app/api/chat.py backend/app/api/errors.py backend/app/api/health.py backend/app/api/sessions.py backend/app/cart/__init__.py backend/app/cart/service.py backend/app/catalog/__init__.py backend/app/catalog/fixture.py backend/app/catalog/live.py backend/app/catalog/normalize.py backend/app/catalog/service.py backend/app/catalog/storage.py backend/app/conditions/__init__.py backend/app/conditions/service.py backend/app/config.py backend/app/contracts.py backend/app/dependencies.py backend/app/main.py backend/app/sessions.py backend/data/catalog/fixture.json backend/data/certificates/DEMO-CERT-001.html backend/data/conditions/fixture/delivery.json backend/data/conditions/fixture/minimum_order.json backend/data/conditions/fixture/payment.json backend/data/conditions/live/delivery.json backend/data/conditions/live/minimum_order.json backend/data/conditions/live/payment.json backend/pytest.ini backend/requirements-dev.txt backend/requirements.txt backend/scripts/__init__.py backend/scripts/import_catalog.py backend/tests/agent/test_agent.py backend/tests/agent/test_contracts.py backend/tests/api/test_http.py backend/tests/api/test_sessions.py backend/tests/cart/__init__.py backend/tests/cart/test_cart_concurrency.py backend/tests/cart/test_cart_service.py backend/tests/catalog/__init__.py backend/tests/catalog/test_api.py backend/tests/catalog/test_catalog.py backend/tests/catalog/test_live.py backend/tests/conditions/__init__.py backend/tests/conditions/test_conditions.py backend/tests/integration/__init__.py backend/tests/integration/test_full_flow.py docs/catalog.md docs/demo.md v 1.2 v1.3 web/assets/app.css web/assets/app.js web/index.html
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.