О проекте
Команда: Apexsoft
Кейс HackAlem.ai: Торговля — Электрокомплект · ekt.kz
Стадия: Доведённый продукт
Задача кейса: AI-консультант по каталогу ekt.kz: товары, аналоги, цены, остатки, корзина
Суть
Чат-консультант по каталогу ekt.kz: поиск по названию/артикулу/задаче, разбор фото и документов, карточки с ценой и остатком, аналоги с объяснением, демо-корзина с явным подтверждением, ответы на русском и казахском.
Как устроено
FastAPI держит сессии, CSRF и индекс каталога, фоново загружаемый из read-only EKT API (BasicAuth); OpenAI (gpt-4.1-mini, Responses API со строгим JSON и вводом изображений) интерпретирует текст, фото маркировки, XLSX/DOCX/PDF-сканы. Цены и остатки берутся только из каталога, модуль analogue_matching подбирает аналоги, изменение корзины выполняет сервер после подтверждения с повторной проверкой остатка. React+TS фронт с карточками, вложениями и /cart; без ключей работает синтетический режим.
Ключевые решения
- OpenAI Responses API strict JSON
- vision (photo recognition)
- catalog indexing and search
- analogue matching
- explicit cart confirmation
- Kazakh localization
Особенности
Честно описано, почему реальная корзина ekt.kz не подключена, и что нужно от партнёра; большой набор тестов на границы данных, приватность, сессии и сбои API; распознавание казахских покупательских намерений с защитой явных команд.
Стек
Python · FastAPI · React · TypeScript · Vite · Docker · Railway · GitHub Actions
Модели
gpt-4.1-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-08ee446c-apexsoft.
README
README.mdEKT — ИИ-консультант по электротехнике
Веб-приложение для кейса ТОО «Электрокомплект» на HACKALEM AI. Помогает покупателю подобрать товары ekt.kz в одном чате: описать задачу обычными словами, приложить фото или спецификацию, проверить характеристики и наличие, выбрать количество и собрать корзину.
Текущий результат — работающий прототип с настоящими API каталога и OpenAI. Корзина демонстрационная: она не оформляет заказ в ekt.kz.
Что умеет консультант
- Ищет товары по названию, артикулу, описанию задачи и контексту диалога.
- Принимает фото JPEG/PNG, Excel XLS/XLSX, Word DOCX, текстовые и сканированные PDF. Старый DOC нужно сохранить как DOCX.
- Показывает карточки с фото, описанием, характеристиками, ценой, наличием и прямой ссылкой на товар. Сертификат доступен, если его ссылка есть в API.
- По фото определяет видимый тип, форму, бренд и читаемую маркировку, затем предлагает кандидатов из каталога. Похожие модели могут потребовать дополнительного фото этикетки: точный артикул по внешнему виду не гарантируется.
- Предлагает аналоги с объяснением совпадающих характеристик. Если доказательств совместимости мало, честно сообщает об этом.
- Отвечает об оплате, доставке и минимальной партии со ссылками на источники EKT.
- Добавляет выбранное количество только после явного подтверждения, повторно проверяет цену и остаток. Позволяет удалить позицию и перейти к текущей корзине.
- Отвечает на русском и казахском. Сохраняет переписку и черновик при обновлении текущей вкладки; прокручивает чат к новому ответу.
Пример: «Нужен светильник для офиса» → уточнение параметров → карточки → выбор количества → «Да, добавить» → ссылка на корзину.
Почему настоящая корзина ekt.kz не подключена
Партнёр предоставил BasicAuth-доступ только к чтению каталога:
GET https://ekt.kz/api/products
GET https://ekt.kz/api/products?page=2
GET https://ekt.kz/api/products/detail?id=515291
В полученном комплекте нет API корзины и оформления заказа, документации покупательской авторизации и тестовой сессии покупателя. Логин каталога позволяет читать товары; он не предоставляет подтверждённого способа изменять корзину посетителя сайта. Поэтому по переданным данным корректно реализовать запись в настоящую корзину мы не смогли.
Для демонстрации реализована отдельная корзина прототипа с проверкой остатков, количества и явного согласия. Она открывается по /cart, а её статус явно показан в интерфейсе. Она не изменяет корзину ekt.kz, не резервирует товар и не отправляет заказ или оплату. Это незакрытая внешняя интеграция, а не подключённый checkout магазина.
Чтобы подключить настоящую корзину, от партнёра нужны:
- Документация чтения, добавления, изменения количества и удаления позиций.
- Способ связывать чат с покупательской сессией и тестовая среда/учётная запись.
- Правила складов, цены, кратности, резервирования, ошибок и повторных запросов.
- Ссылка на оформление заказа и разрешённый способ встраивания чата в сайт.
Запуск за несколько шагов
Нужны Git, Python 3.12 и Node.js 22.12+ с npm. GPU и база данных для прототипа не нужны. Для клонирования приватного репозитория необходим выданный доступ.
git clone https://github.com/BAITC-Hacks/hack-08ee446c-apexsoft.git
cd hack-08ee446c-apexsoft
python -m venv .venv
Windows PowerShell:
.\.venv\Scripts\python.exe -m pip install -r requirements.lock
npm --prefix frontend ci
npm --prefix frontend run build
.\.venv\Scripts\python.exe scripts/run.py --prompt-secrets
Linux/macOS:
.venv/bin/python -m pip install -r requirements.lock
npm --prefix frontend ci
npm --prefix frontend run build
.venv/bin/python scripts/run.py --prompt-secrets
Введите логин/пароль EKT и ключ OpenAI в приглашениях терминала. Пароль и ключ вводятся скрыто и остаются в памяти процесса. Откройте http://127.0.0.1:8000.
Для демонстрации без внешних сервисов запустите без --prompt-secrets: будут использоваться явно обозначенные синтетические товары и ограниченный текстовый поиск. Полноценное понимание диалога, фото и сканов требует OpenAI.
Настройки окружения
| Переменная сервера | Назначение |
|---|---|
EKT_API_USERNAME, EKT_API_PASSWORD | Доступ к живому каталогу; без полной пары — синтетический режим |
OPENAI_API_KEY | Ключ для интерпретации текста, фото и сканов |
OPENAI_MODEL | По умолчанию gpt-4.1-mini; нужна поддержка изображений и строгого JSON в Responses API |
HOST | Локально 127.0.0.1; в облаке 0.0.0.0 |
PORT | По умолчанию 8000; в облаке — значение платформы |
EKT_SECURE_COOKIE | false для локального HTTP, true для публичного HTTPS |
EKT_INDEX_PAGES | Предел фоновой индексации, по умолчанию 1000 страниц |
.env.example показывает названия настроек. Файл .env автоматически не загружается. Передавайте переменные окружением процесса или через настройки хостинга. Не помещайте ключи в frontend, Git, аргументы команд или публичные документы.
Развёртывание на своём хостинге
Пошаговая инструкция: docs/DEPLOYMENT_RU.md.
| Платформа | Подход |
|---|---|
| Railway | Всё приложение одним сервисом из корневого Dockerfile |
| VPS / контейнерный хостинг | Тот же Docker-образ за HTTPS-прокси |
| Vercel / CDN | Интерфейс как статика, а /api/* проксируется на постоянно работающий backend в Railway или на VPS |
Для текущего прототипа нужны один серверный процесс и одна реплика: сессии, корзины и индекс находятся в оперативной памяти. Перезапуск очищает их. Полный backend в масштабируемых Functions требует общего хранилища и отдельной индексации; один только CDN серверную часть не выполняет.
Dockerfile и конфигурация Railway входят в репозиторий. Облачное развёртывание и сборка Docker-образа этой версии ещё не проверены: локальные тесты не выдаются за проверку облака. В инструкции приведена обязательная проверка после деплоя.
Проверка после запуска
- Откройте
/api/health: посмотрите режимыcatalog,ai,cart, числоindexed_productsиindex_complete. Индекс загружается в фоне.status: okподтверждает работу процесса, а не доступность внешних API. - В демо-режиме найдите
900001: ожидается отсутствующий товар и аналог900002. В живом режиме попробуйте артикул150200334_и сравните текущие данные с магазином. - Прикрепите фото маркировки или документ с артикулом. Ответ должен относиться к вложению; корзина сама не меняется.
- Выберите количество, отмените предложение, затем повторите и подтвердите. Проверьте состав по
/cartи удаление позиции. - Обновите страницу: переписка и черновик должны сохраниться. Проверьте интерфейс в мобильном размере.
Автоматические проверки не требуют внешних ключей:
.\.venv\Scripts\python.exe -m pytest -q
.\.venv\Scripts\python.exe scripts/check_secrets.py
npm --prefix frontend test -- --maxWorkers=2
npm --prefix frontend run build
На Linux/macOS используйте .venv/bin/python. Тесты проверяют подтверждения, остатки, повторные запросы, изоляцию сессий, вложения, ошибки API и интерфейс. Реальные OpenAI/EKT проверяются отдельно. Методика · Матрица требований.
Архитектура
React + TypeScript: чат, карточки, вложения, корзина
│ /api по одному домену
FastAPI: сессии, CSRF, поиск, правила подтверждения
├── OpenAI: понимание текста и изображений
├── EKT API: карточки, цены и остатки
└── память процесса: индекс, контекст, демо-корзина
ИИ интерпретирует запрос. Цены и остатки берутся из каталога; изменение корзины выполняет сервер после подтверждения. Модель самостоятельно заказ не оформляет.
backend/ — сервер; frontend/ — интерфейс; tests/ — серверные проверки; scripts/ — запуск и проверка секретов. Версии библиотек закреплены в requirements.lock и frontend/package-lock.json. Контракт API · Подробная локальная настройка.
Ограничения и данные
- Фото даёт кандидатов по видимым признакам; аналог не означает гарантированную электрическую совместимость.
- API и региональная витрина могут показывать разные цены/остатки. При недоступном источнике данные не выдумываются. Сертификат показывается только при наличии ссылки.
- Один файл — до 8 MiB. PDF — до 30 страниц, до 4 страниц со сканами/графикой распознаются как изображения; об ограничении сообщается. Автоматического пакетного заказа по спецификации нет.
- Переписка хранится в текущей вкладке; серверная сессия — до двух часов бездействия. Перезапуск сервера очищает контекст и корзину. Это не постоянная история авторизованного клиента.
- Текст и выбранные вложения передаются OpenAI с
store:false. Не отправляйте платёжные или конфиденциальные данные. Проверка платёжных форматов в тексте не является универсальным DLP изображений. - Одиночные живые запросы проверены в пределах нескольких секунд; это не SLA под нагрузкой. Промышленная установка на ekt.kz, долговременное хранилище и реальная корзина требуют дальнейшей интеграции.
Данные каталога и условий принадлежат EKT. Синтетический набор создан для воспроизводимой демонстрации; собственная языковая модель не обучалась. Сторонние библиотеки и подробные пределы.
Авторы коммитов
История коммитов
- 2026-09-23 17:58Document EKT consultant, demo cart limits and deploymentGreat-laselot-afr
- 2026-09-23 17:46Fix photo retrieval, PDF scans and verified analogue matching (#5)Great-laselot-afr
- 2026-09-23 17:45Clear photo constraints when customers change product categoryGreat-laselot-afr
- 2026-09-23 17:43Constrain cable search and refresh requirement acceptance evidenceGreat-laselot-afr
- 2026-09-23 17:42Reveal analogue search progress and results in chatamianovrisat-spec
- 2026-09-23 17:38Reveal analogue search progress and results in chatamianovrisat-spec
- 2026-09-23 17:37Fix photo and document retrieval, validate analogues and guard payment textGreat-laselot-afr
- 2026-09-23 17:30Support scanned PDF attachments with bounded in-memory renderingamianovrisat-spec
Все коммиты (67)
- 2026-09-23 17:29Guard payment credentials in chat storage and text processingGreat-laselot-afr
- 2026-09-23 17:28Support scanned PDF attachments with bounded in-memory renderingamianovrisat-spec
- 2026-09-23 17:08Fix EKT catalog coverage and show complete product cards (#4)Great-laselot-afr
- 2026-09-23 17:02Preserve chat on reload and complete budget, confirmation and cart behaviorGreat-laselot-afr
- 2026-09-23 17:01Add-independent-cart-removal-regressionGreat-laselot-afr
- 2026-09-23 16:59Verify removing one cart line preserves the other productamianovrisat-spec
- 2026-09-23 16:58Integrate-tool-type-and-price-filterGreat-laselot-afr
- 2026-09-23 16:55Keep named tool searches relevant and verify budget against fresh pricesamianovrisat-spec
- 2026-09-23 16:50Merge remote-tracking branch 'origin/agent-a/language-catalog-hotfix' into codex/catalog-coverage-bamianovrisat-spec
- 2026-09-23 16:46Integrate catalog overview and document complete background indexingGreat-laselot-afr
- 2026-09-23 16:45Merge remote-tracking branch 'origin/agent-a/language-catalog-hotfix' into codex/catalog-coverage-bamianovrisat-spec
- 2026-09-23 16:44Integrate-catalog-coverage-from-agent-BGreat-laselot-afr
- 2026-09-23 16:43Load catalog beyond first 2000 products and stop wrapped paginationamianovrisat-spec
- 2026-09-23 16:41Fix language switching and catalog browsing; show product photos, descriptions and linksGreat-laselot-afr
- 2026-09-23 16:40Keep unavailable product links absent instead of linking homeamianovrisat-spec
- 2026-09-23 16:36Add verified catalog overview across loaded categoriesamianovrisat-spec
- 2026-09-23 16:24Harden EKT assistant and expand regression coverage (#3)Great-laselot-afr
- 2026-09-23 16:22Merge commit 'b925e8ceb501340cfdabc33ecc0e53edfb1e8314' into agent-a/catalog-reliabilityGreat-laselot-afr
- 2026-09-23 16:21Document Kazakh chat, cart removal, and retry guaranteesGreat-laselot-afr
- 2026-09-23 16:21Record final Kazakh live verification and prototype delivery limitsamianovrisat-spec
- 2026-09-23 16:17Merge remote-tracking branch 'origin/agent-a/catalog-reliability' into codex/resilience-tests-bamianovrisat-spec
- 2026-09-23 16:16Merge commit '7411eaf' into agent-a/catalog-reliabilityGreat-laselot-afr
- 2026-09-23 16:16Respect unavailable clarification inputs and localized cart shortcutGreat-laselot-afr
- 2026-09-23 16:15Merge remote-tracking branch 'origin/agent-a/catalog-reliability' into codex/resilience-tests-bamianovrisat-spec
- 2026-09-23 16:14Integrate Kazakh replies with session history and explicit cart commandsamianovrisat-spec
- 2026-09-23 16:12Merge commit '167e66fb1d4746f4fb94bce7d0e4758497730fcb' into agent-a/catalog-reliabilityGreat-laselot-afr
- 2026-09-23 16:12Add Kazakh response localization with explicit-command safeguardsGreat-laselot-afr
- 2026-09-23 16:12Understand Kazakh shopping intents and explicit quantitiesGreat-laselot-afr
- 2026-09-23 16:10Document verification against the provided HackAlem requirementsamianovrisat-spec
- 2026-09-23 16:09Add Kazakh response localization with explicit-command safeguardsGreat-laselot-afr
- 2026-09-23 16:08Support explicit cart removal and replay lost chat responsesamianovrisat-spec
- 2026-09-23 16:03Test catalog and AI failures without cart authorizationamianovrisat-spec
- 2026-09-23 15:56Avoid repeated unavailable-photo prompts and document QA coverageGreat-laselot-afr
- 2026-09-23 15:50Add bounded live conversation evaluation and testing guideGreat-laselot-afr
- 2026-09-23 15:49Restore composer focus after starting a new conversationGreat-laselot-afr
- 2026-09-23 15:45fix: validate catalog and AI data boundariesGreat-laselot-afr
- 2026-09-23 15:44Reset conversation and remove attachments through the serverGreat-laselot-afr
- 2026-09-23 15:42Validate API data and recover cart errors in mobile dialogGreat-laselot-afr
- 2026-09-23 15:39Run offline regression checks in CIGreat-laselot-afr
- 2026-09-23 15:37Release consumed uploads and validate session boundariesGreat-laselot-afr
- 2026-09-23 15:28Keep submitted chat and composer in viewGreat-laselot-afr
- 2026-09-23 15:27Distinguish product models from catalogue IDsGreat-laselot-afr
- 2026-09-23 15:09Fix EKT conversation context (#2)Great-laselot-afr
- 2026-09-23 15:04Fix contextual product clarification and conversation historyGreat-laselot-afr
- 2026-09-23 14:34Merge EKT assistant prototype (#1)Great-laselot-afr
- 2026-09-23 14:24fix: keep catalog requests responsive and document verified setupGreat-laselot-afr
- 2026-09-23 14:22fix: report timeouts while reading assistant responsesamianovrisat-spec
- 2026-09-23 14:18fix: report timeouts while reading assistant responsesamianovrisat-spec
- 2026-09-23 14:03chore: keep agent coordination outside product repositoryGreat-laselot-afr
- 2026-09-23 13:56Align chat input limits with server validationamianovrisat-spec
- 2026-09-23 13:54fix: resolve model-provided articles through catalog searchGreat-laselot-afr
- 2026-09-23 13:54Align chat input limits with server validationamianovrisat-spec
- 2026-09-23 13:50feat: integrate EKT consultant frontend with serverGreat-laselot-afr
- 2026-09-23 13:49feat: implement EKT catalog assistant and confirmed session cartGreat-laselot-afr
- 2026-09-23 13:47Connect consultant UI to session API and explicit cart consentamianovrisat-spec
- 2026-09-23 13:38chore: remove organizer coordination documents from projectGreat-laselot-afr
- 2026-09-23 13:34docs: review all 18 organizer instruction PDFsGreat-laselot-afr
- 2026-09-23 13:28Build responsive EKT consultant interface foundationamianovrisat-spec
- 2026-09-23 13:26docs: define EKT case and shared API contractGreat-laselot-afr
Структура репозитория (81 файлов)
.dockerignore .env.example .github/workflows/ci.yml .gitignore DESIGN.md Dockerfile README.md backend/__init__.py backend/ai.py backend/analogue_matching.py backend/app.py backend/attachments.py backend/body_limit.py backend/browsing.py backend/catalog.py backend/clarification.py backend/data/catalog_snapshot.json backend/document_search.py backend/errors.py backend/knowledge.py backend/language.py backend/privacy.py backend/state.py backend/visual.py docs/API_CONTRACT.md docs/DEPLOYMENT_RU.md docs/LOCAL_SETUP_RU.md docs/REQUIREMENTS_REVIEW_RU.md docs/TESTING.md frontend/.gitignore frontend/README.md frontend/index.html frontend/package-lock.json frontend/package.json frontend/src/App.tsx frontend/src/api.ts frontend/src/chatStorage.ts frontend/src/components.tsx frontend/src/main.tsx frontend/src/privacy.ts frontend/src/responseValidation.ts frontend/src/styles.css frontend/src/test/AlternativesFeedback.test.tsx frontend/src/test/App.test.tsx frontend/src/test/Privacy.test.ts frontend/src/test/ProductCard.test.tsx frontend/src/test/Reload.test.tsx frontend/src/test/RetryAndRemove.test.tsx frontend/src/test/Session.test.tsx frontend/src/test/api.test.ts frontend/src/test/fixtures.ts frontend/src/test/setup.ts frontend/src/test/validation.test.ts frontend/src/types.ts frontend/tsconfig.json frontend/vite.config.ts railway.toml requirements.lock requirements.txt scripts/check_secrets.py scripts/evaluate_live.py scripts/run.py tests/test_analogue_matching.py tests/test_browsing.py tests/test_catalog_concurrency.py tests/test_catalog_coverage.py tests/test_catalog_search.py tests/test_chat_retry_and_cart_remove.py tests/test_conversation.py tests/test_core.py tests/test_data_boundaries.py tests/test_document_search.py tests/test_language.py tests/test_language_integration.py tests/test_pdf_attachments.py tests/test_privacy.py tests/test_privacy_integration.py tests/test_resilience.py tests/test_session_boundaries.py tests/test_visual.py tests/test_wire_search.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.