О проекте
Команда: Solution
Кейс HackAlem.ai: Торговля — Электрокомплект · ekt.kz
Стадия: Доведённый продукт
Задача кейса: AI-консультант по каталогу ekt.kz: товары, аналоги, цены, остатки, корзина
Суть
AI-консультант по каталогу ekt.kz: поиск товаров по ID, артикулу и описанию, живые цены и остатки из API EKT, подбор аналогов, сборка комплектов, разбор спецификаций (CSV/XLSX/DOCX/PDF/фото), чат на русском и казахском и локальная корзина с отдельным подтверждением. Есть демо-режим без ключей и встраиваемый виджет.
Как устроено
Каталог синхронизируется из ekt.kz API (BasicAuth на сервере) в локальный JSON-индекс, поиск идёт через RapidFuzz. Маршрутизатор моделей делит запросы: DIRECT (точный ID и корзина без модели), CHEAP, MEDIUM, STRONG (сложный комплект), VISION (изображения). Весь каталог в модель не передаётся. Модель сравнивает реальные карточки, сервер проверяет ID и поля и сам считает разницу цен (grounding). Изменение корзины идёт только через одноразовый токен подтверждения на 120 с с повторной проверкой цены, остатка и кратности. Файлы парсятся в изолированном дочернем процессе.
Ключевые решения
- model routing by complexity
- fuzzy search (RapidFuzz)
- grounding verification
- confirmation tokens
- document parsing (PDF/DOCX/XLSX)
- vision model for photos
- spend limits
- embeddable widget
Особенности
Многоуровневый роутинг моделей по сложности запроса с лимитами MAX_MODEL_CALLS и MODEL_SPEND_LIMIT_USD. Корзина защищена от случайных действий: одноразовый токен на 120 с и перепроверка цены и остатка. Команда честно пишет, что штатную корзину EKT подключить не удалось, и изолирует её за CartProvider. Около 90 тестов.
Стек
Python · FastAPI · Pydantic · HTTPX · RapidFuzz · openpyxl · xlrd · python-docx · PyMuPDF · Pillow · HTML/CSS/JavaScript
Модели
gpt-6-luna · gpt-5.4-mini · gpt-6-sol · NVIDIA (optional)
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-40c312ea-solution.
README
README.mdEKT AI Engineer · HackAlem MVP
Консультант и помощник закупщика для ekt.kz: от запроса или спецификации до проверенной подборки и подтверждённой локальной корзины. Интерфейс работает на русском и казахском, на компьютере и телефоне.
Репозиторий: BAITC-Hacks/hack-40c312ea-solution, основная ветка main. Публичная развёрнутая версия пока не опубликована. После запуска: http://127.0.0.1:8000 — ссылка работает на компьютере с запущенным сервером.
Быстрый запуск для организаторов — без ключей
Требуется Python 3.11+. Скачайте ZIP ветки main и распакуйте либо клонируйте репозиторий с доступом к BAITC-Hacks. Выполняйте команды в папке с run.py и requirements.txt.
python -m venv .venv
Windows PowerShell:
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe run.py --demo
macOS / Linux:
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python run.py --demo
Откройте http://127.0.0.1:8000. --demo использует явно подписанные вымышленные товары DEMO, не вызывает EKT и платные модели. Доступны каталог, поиск, русский/казахский чат, текстовые файлы, подтверждение количества и локальная корзина. Фото требуют vision-модели в live-режиме. python run.py тоже включает демо, если пароль EKT отсутствует или равен replace_me.
Реальный каталог EKT
- Скопируйте
.env.exampleв.env. - Укажите выданные партнёром
EKT_USER,EKT_PASSWORDиDEMO_MODE=0. - Запустите
python run.pyиз созданного окружения. - При первом запуске дождитесь синхронизации. Поиск по ID доступен сразу; последующие запуски используют локальный индекс. Цены и остатки выбранных товаров читаются из API заново.
Ключи и пароли не включены в репозиторий. Для проверки со смартфона в доверенной общей сети можно запустить python run.py --host 0.0.0.0 и открыть адрес компьютера. Для публикации нужен HTTPS-хостинг.
Реализованные возможности
- Каталог с изображениями, ID/артикулом, поиском, категориями и страницами; живые цена/остаток; карточки с характеристиками, складами и сертификатом, если API предоставляет ссылку.
- Русский и казахский интерфейс и ответы, контекст текущего товара, условия оплаты/доставки, уточнение параметров. Исходные названия и характеристики сохраняются как в каталоге.
- Аналоги отсутствующих товаров по известному назначению, току и полюсам с объяснением; при нехватке данных — уточнение и менеджер.
- Предварительный комплект для сложной задачи; режимы «Дешевле», «В наличии», «Лучшее совпадение», предпочтительный бренд через диалог. Совместимость без достаточных данных не гарантируется.
- CSV, XLS/XLSX, DOCX, текстовый PDF, JPG/JPEG/PNG, первая страница сканированного PDF. Предпросмотр и исправление распознанных строк/количеств перед подбором. Отдельное согласие на передачу изображения ИИ.
- Локальная корзина: добавление, изменение и удаление только после отдельного подтверждения. Повторно проверяются цена, остаток, выбранный склад и кратность. Токен привязан к сессии и действует 120 секунд; повторное использование не добавляет товар снова.
- Прямая ссылка
/cartоткрывает текущее содержимое локальной корзины в той же вкладке/сессии. Заказ не отправляется и товар не резервируется. - Реальные
tel:, WhatsApp и email менеджера EKT с официального сайта. Пользователь сам звонит/отправляет сообщение; история автоматически не передаётся. Старый API демозаявки сохранён, CRM не подключена. - Полноэкранный мобильный чат, адаптивные карточки и окна подтверждения, история текущей анонимной сессии, очистка данных и отказ от дополнительных рекомендаций.
- Встраиваемый виджет, проверка источника запросов, изоляция сессий и обработка документов в ограниченном дочернем процессе.
Пример проверки
В деморежиме откройте товар 900005, укажите 2 единицы и нажмите добавление. До отдельного подтверждения корзина пуста; после него /cart содержит 2 единицы. Превышение остатка отклоняется.
В чате: 900005 → добавь 2 в корзину → отдельное да, добавь. На казахском: Маған 900005 керек → себетке 2 қос → иә, қос. Загрузите examples/demo_spec.csv, проверьте количества и подтвердите подбор: загрузка сама не меняет корзину. Кнопка «Менеджер» показывает действительные контакты, для теста звонить не нужно. /embed-demo демонстрирует виджет.
В live-режиме: 33723 — пример Schneider; 515291 — пример противоречия 160/250 A в исходных данных, которое вызывает предупреждение. Запросы: автомат Schneider 3P 32A, сделай дешевле, Нужно собрать защиту двигателя 11 кВт, 380 В. Цены и остатки меняются; числа из скриншотов не являются тестовой фикстурой.
Технологии и архитектура
Python, FastAPI/Pydantic, HTTPX, RapidFuzz; обычные HTML/CSS/JavaScript без сборщика frontend. Для файлов: openpyxl, xlrd, python-docx, PyMuPDF, Pillow. Сессии в памяти и локальный JSON-индекс.
flowchart TD
A[Витрина / чат RU и KK / мобильный виджет] --> B[FastAPI и сессия]
B --> C[Требования / разбор файла]
C --> D[Маршрутизатор моделей]
D --> E[Индекс каталога и поиск]
E --> F[Живые карточки EKT]
F --> G[Подборка / аналоги / ограничения]
G --> H[Отдельное подтверждение]
H --> I[Повторная проверка цены и остатка]
I --> J[CartProvider: локальная корзина /cart]
B --> K[Контакты менеджера EKT]
Папки: app/ — API, агент, провайдеры, парсеры и безопасность; static/ — витрина/чат/виджет; tests/ — автономные проверки; examples/ — спецификация; docs/ — интеграция; qa/ — отчёты команды. run.py — единая точка запуска. Маршруты: /, /cart, /engine (исходный интерфейс), /embed-demo, /openapi.json (описание API), /api/integration.
Данные, модели и внешние сервисы
EKT: https://ekt.kz/api/products?page=N, https://ekt.kz/api/products/detail?id=ID; BasicAuth только на сервере. Схема: id, article, name, price, image, url; detail добавляет quantity, stores, properties, description. Каталог читается до повторения первой страницы или заданного лимита. Условия покупки и контакты проверены 23.09.2026. Индивидуальный ETA и общая минимальная сумма заказа не выдумываются.
OpenAI/NVIDIA опциональны: OPENAI_API_KEY, NVIDIA_API_KEY; CHEAP_MODEL, MEDIUM_MODEL, STRONG_MODEL, VISION_MODEL и *_PROVIDER задаются в .env. В текущем окружении проверены gpt-6-luna, gpt-5.4-mini, gpt-6-sol; доступность зависит от аккаунта. NVIDIA без ключа не тестировалась.
DIRECT — точный ID/артикул, условия, корзина без модели. CHEAP — короткий запрос; MEDIUM — сравнительный; STRONG — сложный комплект; VISION — изображение. Весь каталог в модель не передаётся. Если провайдер недоступен, текстовый поиск продолжает работать с явным fallback. MAX_MODEL_CALLS и MODEL_SPEND_LIMIT_USD ограничивают использование; model_usage.json содержит оценку, а не выписку биллинга. Для неизвестных моделей стоимость может быть не определена.
Проверки
Обновление достоверности и скорости: qa/grounding-report.md. Актуальный набор: 90 тестов. Модель сравнивает реальные карточки и выбирает подтверждающие поля; сервер проверяет ID/поля и сам рассчитывает разницу цен. Добавлены «подороже», предложения дополнений после подтверждения, помощь менеджера при отсутствии фактов и общий предел 18 секунд для обычного ответа. Неизвестный ETA не заменяется обещанием доставки.
python -m unittest discover -s tests -v
python tests/test_agent_behavior.py
Первый набор проверяет актуальное поведение. Второй сохраняет исходные ожидания QA: интеграция с удалённой корзиной EKT остаётся незакрытой, а его JPEG-фикстура содержит некорректные байты и отклоняется новой проверкой файла. Подробности — qa/acceptance-report.md; исходные отчёты команды сохранены.
Совместимость и известные ограничения
См. docs/INTEGRATION.md. На сайте наблюдаются ресурсы /bitrix/. Виджет подключается одним script; backend можно разместить отдельно или за reverse proxy. Проверка в шаблоне и cookie-сессии EKT требует доступа партнёра.
Штатная корзина и внутренняя БД EKT не подключены. Выданный API даёт чтение каталога. CartProvider изолирует локальную реализацию; EKT должен предоставить разрешённый контракт корзины, связь с посетителем и тестовый контур. Официальная ссылка не переносит локальные позиции. Требование полноценного оформления на ekt.kz пока реализовано только на уровне локального прототипа.
Сессии живут в памяти до 30 минут бездействия и теряются при перезапуске; запускайте MVP одним процессом. История авторизованных пользователей и CRM не подключены. Файл — до 10 МБ/12 строк; скан PDF — первая страница. Электрическая совместимость предварительная. Если подходящего аналога с подтверждёнными свойствами нет, замена не гарантируется. Задержка зависит от EKT и ИИ, сложный комплект может занимать больше нескольких секунд.
История сохраняет коммит DamiMura / Damitov Murat c6dd771 и QA-коммиты ent1tyyyy. Репозиторий приватный внутри BAITC-Hacks: организаторам нужны права на него; для автономного демо секреты не требуются.
Проверка презентационного сценария (23 сентября)
- Открыть чат: «мне нужны лампы для кафешки».
- Включить ДЕМО доставки и выбрать город (Алматы / Астана / Шымкент / Караганда).
- «Мне нужны максимально дешевые варианты и чтобы доставка в Алмату была в быстрый срок».
- «Добавь самую первую лампу мне в корзину» → проверить состав → «да, добавь».
- В корзине изменить количество → «Изменить» → проверить переход
1 → 3→ подтвердить. Обновлённая корзина открывается автоматически.
DEMO_LOGISTICS=1 включает виртуальную логистику по умолчанию; в .env.example она выключена. Переключатель действует в текущей сессии. Демосроки и виртуальные остатки по городам не являются данными EKT, показываются отдельно и не используются для проверки допустимого количества в корзине. При запросе скорости сортировка: допустимые товары в реальном наличии → меньший демосрок → меньшая цена. При выключенном режиме индивидуальные сроки не обещаются.
Фотографии корзины берутся из API. Категории имеют отдельное состояние выбора, фильтр действует и на поиск. Названия моделей и провайдеров в клиентском интерфейсе скрыты; технические маршруты остаются в диагностических ответах API. Сертификаты показываются только при наличии ссылки в данных; поддерживаются вложенные поля и относительные ссылки EKT. В проверенной выборке 23 товаров сертификатов API не предоставил — доступен запрос менеджеру, документы не подделываются.
Актуальная проверка: qa/presentation-report.md.
Разбор свободного текста и заказа ИИ
Подключённая модель нормализует запрос клиента, затем сравнивает реальные карточки и выбирает подтверждённые характеристики для объяснения. Для выбора из показанного списка отдельный короткий ИИ-вызов извлекает товар и количество: например, «беру пару из второго варианта» формирует предпросмотр двух штук второй позиции. Модель не имеет операции подтверждения: добавление выполняется только после отдельного согласия пользователя, повторной проверки цены/остатка и проверки серверного токена. Неизвестные ID, неправильные количества и несоответствие категории отбрасываются.
Простые точные запросы и подтверждения обходятся без модели. При недоступности провайдера сохраняется ограниченный поиск по каталогу и явным командам. Нормализация разговорных названий (лампочки, розеточки, проводочки, кабельки, автоматики) работает и без ИИ; она не заменяет технические параметры. Отказ от покупки распознаётся как целое высказывание, поэтому «мне нужно» больше не совпадает с «не нужно».
Регрессии и реальные замеры: qa/semantic-dialog-report.md.
Авторы коммитов
История коммитов
- 2026-09-23 17:52Match in-stock technical analogues for absent catalog articlesVULVERNAUT
- 2026-09-23 17:47Fix positive request parsing and colloquial search; interpret order selections with AIVULVERNAUT
- 2026-09-23 17:39Fix selection and cart flow, add labeled demo logistics and presentation checksVULVERNAUT
- 2026-09-23 16:38Merge pull request #3 from BAITC-Hacks/featureDamitov Murat
- 2026-09-23 16:37Merge main into feature: reconcile README and preserve QA documentationDamitov Murat
- 2026-09-23 16:25feat: add bilingual storefront, consent workflows, privacy and guided salesDamitov Murat
- 2026-09-23 17:23Generalize product purpose checks across electrical categoriesVULVERNAUT
- 2026-09-23 17:15Ground product advice in verified facts, fix lamp retrieval and bound chat latencyVULVERNAUT
Все коммиты (45)
- 2026-09-23 16:55Finalize mobile bilingual EKT MVP, verified manager contacts and portable demoVULVERNAUT
- 2026-09-23 16:28Merge pull request #2 from BAITC-Hacks/docs/ent1tyyyy-readme-qaent1tyyyy
- 2026-09-23 16:00Document QA baseline, data flow and test setupent1tyyyy
- 2026-09-23 15:55Merge pull request #1 from BAITC-Hacks/qa/ent1tyyyy-baseline-testsent1tyyyy
- 2026-09-23 15:51Add baseline QA tests and reproducible findingsent1tyyyy
- 2026-09-23 15:24Complete verified chat/cart flow in README.mdVULVERNAUT
- 2026-09-23 15:24Complete verified chat/cart flow in static/app.jsVULVERNAUT
- 2026-09-23 15:23Complete verified chat/cart flow in app/engine.pyVULVERNAUT
- 2026-09-23 15:23Complete verified chat/cart flow in app/main.pyVULVERNAUT
- 2026-09-23 15:11Update app/__init__.py for verified MVPVULVERNAUT
- 2026-09-23 15:11Update demo_spec.csv for verified MVPVULVERNAUT
- 2026-09-23 15:11Update .gitignore for verified MVPVULVERNAUT
- 2026-09-23 15:11Update .env.example for verified MVPVULVERNAUT
- 2026-09-23 15:11Update requirements.txt for verified MVPVULVERNAUT
- 2026-09-23 15:11Update static/conditions.js for verified MVPVULVERNAUT
- 2026-09-23 15:11Update static/style.css for verified MVPVULVERNAUT
- 2026-09-23 15:10Update static/index.html for verified MVPVULVERNAUT
- 2026-09-23 15:10Update static/app.js for verified MVPVULVERNAUT
- 2026-09-23 15:10Update app/files.py for verified MVPVULVERNAUT
- 2026-09-23 15:10Update app/ekt.py for verified MVPVULVERNAUT
- 2026-09-23 15:10Update README.md for verified MVPVULVERNAUT
- 2026-09-23 15:10Update static/upload.js for verified MVPVULVERNAUT
- 2026-09-23 15:10Update static/cart.js for verified MVPVULVERNAUT
- 2026-09-23 15:10Update app/engine.py for verified MVPVULVERNAUT
- 2026-09-23 15:09Update app/model_router.py for verified MVPVULVERNAUT
- 2026-09-23 15:09Update app/main.py for verified MVPVULVERNAUT
- 2026-09-23 15:09Add app/agent.py for verified MVPVULVERNAUT
- 2026-09-23 14:19Polish compatibility evidence and scanned-PDF fallbackVULVERNAUT
- 2026-09-23 14:18Polish compatibility evidence and scanned-PDF fallbackVULVERNAUT
- 2026-09-23 14:12Add model routing, verified conditions and BOM orderingVULVERNAUT
- 2026-09-23 14:11Add model routing, verified conditions and BOM orderingVULVERNAUT
- 2026-09-23 13:59Verify technical constraints and document MVPVULVERNAUT
- 2026-09-23 13:58Verify technical constraints and document MVPVULVERNAUT
- 2026-09-23 13:56Add specification ingestion and complete catalog syncVULVERNAUT
- 2026-09-23 13:55Add specification ingestion and complete catalog syncVULVERNAUT
- 2026-09-23 13:50Add runnable EKT AI Engineer scaffoldVULVERNAUT
- 2026-09-23 13:49Add runnable EKT AI Engineer scaffoldVULVERNAUT
Структура репозитория (54 файлов)
.env.example .gitignore FEATURES.md README.md app/__init__.py app/advisor.py app/agent.py app/cart_actions.py app/cart_provider.py app/demo.py app/ekt.py app/engine.py app/features.py app/files.py app/grounding.py app/i18n.py app/integration.py app/logistics.py app/main.py app/model_router.py app/order_intent.py app/query_text.py app/security.py app/upload_guard.py app/upload_worker.py demo_spec.csv docs/INTEGRATION.md examples/demo_spec.csv qa/acceptance-report.md qa/baseline-report-ca57662b.md qa/baseline-results-ca57662b.json qa/grounding-report.md qa/presentation-report.md qa/semantic-dialog-report.md requirements.txt run.py static/app.js static/cart.js static/conditions.js static/embed-demo.html static/enhancements.js static/index.html static/responsive.css static/store.css static/store.html static/store.js static/style.css static/upload.js static/widget.js tests/test_agent_behavior.py tests/test_cart_confirmation.py tests/test_grounding.py tests/test_mvp_acceptance.py tests/test_store_features.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.