AAYMA
RU
Войти

EKT Assistant

Чат-консультант по каталогу ekt.kz: поиск товаров по тексту, артикулу, спецификации (XLSX, DOCX, PDF) и фото маркировки, карточки с ценой, остатками…

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

О проекте

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

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

Суть

Чат-консультант по каталогу ekt.kz: поиск товаров по тексту, артикулу, спецификации (XLSX, DOCX, PDF) и фото маркировки, карточки с ценой, остатками и сертификатами, аналоги при нулевом остатке и локальная корзина с добавлением только после явного подтверждения.

Как устроено

FastAPI с сессиями и CSRF: модуль Dialogue определяет намерение с учётом контекста и направляет запрос в разговор, поиск, условия покупки или к менеджеру. CatalogService обращается к API EKT (Basic Auth) или к демо-каталогу, каталог фоново подгружается в JSON-снимок. OpenAI Responses API разбирает запросы, документы и изображения (OCR через vision), результат приходит структурированным JSON. Аналоги подбираются сравнением категории и технических параметров. Перед добавлением в корзину сервер заново берёт карточку и проверяет цену, остаток, минимум и кратность. Подтверждение одноразовое и действует 120 секунд.

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

  • intent detection
  • структурированный JSON
  • vision-OCR спецификаций
  • парсинг XLSX/DOCX/PDF
  • подбор аналогов по параметрам
  • одноразовое подтверждение корзины

Особенности

В README есть подробная таблица соответствия каждому пункту ТЗ со статусами «реализовано», «частично» и «внешний шаг». У модели нет инструментов менять корзину: все изменения идут через сервер после явного «да, добавь» или «иә, қос». Есть фильтр номеров карт и API-ключей в чате. Поддерживаются RU и KK.

Стек

Python · FastAPI · Uvicorn · Pydantic · httpx · SQLite · pypdf · PyMuPDF · python-docx · openpyxl · Docker · Caddy · GitHub Actions · vanilla JS

Модели

gpt-5.6-luna (OpenAI)


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

README

README.md

EKT Assistant — ИИ-консультант для покупателей ekt.kz

Проект для HackAlem AI, кейс ТОО «Электрокомплект»: единое окно чата помогает частным покупателям и закупщикам разобраться в задаче, найти электротехническую продукцию, проверить наличие и параметры, посмотреть фотографии, сравнить аналоги и подготовить корзину после явного согласия.

Решение предназначено для сокращения ожидания консультации и повторяющихся вопросов менеджерам. Изменение конверсии, оттока и нагрузки менеджеров пока не измерялось.

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

Документация сверена с кодом и тремя предоставленными PDF 23 сентября 2026 года. Повторная автоматическая проверка: 47 тестов, все прошли.

Содержание

Возможности и пользовательский сценарий

Ассистент поддерживает обычный разговор: объясняет понятия, задаёт уточняющие вопросы, учитывает контекст и помогает сформулировать задачу клиента. Поиск товаров вызывается для товарных запросов; благодарность или вопрос «чем отличается автомат от УЗО?» не должны превращаться в бессмысленный поиск по каталогу.

Основной путь пользователя:

  1. Открыть чат и написать вопрос, артикул, название либо загрузить спецификацию или фото маркировки.
  2. Получить ответ и карточки: фотография, название, артикул, цена, общий остаток, характеристики, склады, сертификаты и ссылка на товар — если эти данные есть в источнике. Фото открывается крупнее по нажатию; при отсутствии или ошибке загрузки отображается заглушка.
  3. При нулевом остатке посмотреть найденные аналоги с объяснением совпадения параметров. При неоднозначности уточнить выбор.
  4. Выбрать товар и количество. На этом этапе корзина ещё не меняется.
  5. Подтвердить предложение кнопкой или точным сообщением да, добавь / иә, қос. Сервер повторно получает карточку и проверяет цену, остаток, суммарное количество, минимум и кратность.
  6. Перейти по ссылке /cart и увидеть локальную корзину своей сессии. Заказ на ekt.kz при этом не создаётся.

Дополнительно доступны русский и казахский интерфейсы, условия покупки со ссылкой на источник, локальные аккаунты, сохранение/очистка истории, удаление аккаунта, контакты менеджера и скачивание текста запроса с контекстом разговора и корзиной. Гостевая сессия и корзина переживают перезапуск сервера в пределах срока действия сессии.

Соответствие требованиям кейса

Статусы означают: реализовано — функция есть в коде; частично — ограничения перечислены; внешний шаг — необходимы действия или данные партнёра/команды. Наличие механизма не означает завершённую интеграцию с production-сайтом.

Обязательные функции — пункт 7 PDF

№ТребованиеРеализация и статус
7.1Наличие, технические характеристики, сертификат для существующего артикулаРеализовано. Данные из каталога; сертификат показывается при наличии ссылки. DEMO-001 демонстрирует все поля; demo-сертификат явно обозначен как образец. Отсутствующий реальный документ не выдумывается.
7.2Минимум один обоснованный аналог при нулевом остаткеЧастично. Демо-сценарий DEMO-001 → DEMO-002 и тесты проходят. В live сравниваются категория и известные технические параметры, проверяется остаток. При недостаточных или противоречивых данных замена не предлагается; аналог для каждой отсутствующей позиции не гарантируется.
7.3Оплата, доставка, минимальная партияРеализовано с ограничениями источника. Справка RU/KK, ссылка и дата проверки; минимум из карточки проверяется сервером. Спорные условия доставки требуют подтверждения менеджера.
7.4Добавление только после явного согласия с учётом количества и остаткаРеализовано для локальной корзины. Отказ и предложение не добавляют товар; подтверждение одноразовое, действует 120 секунд. Проверяются свежие цена/остаток, уже добавленное количество, минимум и кратность.
7.5Прямая ссылка на актуальное состояние корзиныРеализовано для /cart. Показывает состав корзины текущей cookie-сессии. Внешняя корзина и переход к оформлению ekt.kz требуют API партнёра. Цены в локальной корзине — снимок на момент добавления, не резерв.

Остальные пункты кейса

ПунктТребованиеСостояние
1–4Консультант для частного покупателя/закупщика; единое окно; каталог, условия, выбор и подтверждениеРеализован локальный сценарий. Встраивание в CMS ekt.kz и бизнес-эффект не подтверждены.
5Свободный текст, контекст диалогаAI определяет намерение и уточняет запрос с учётом последних сообщений. Точные цифровые артикулы и demo-артикулы работают без AI.
5Excel, Word, PDF, JPEGXLS/XLSX, DOCX, текстовый PDF, PDF со сканами, JPEG/PNG. Legacy DOC не поддерживается; лимиты приведены ниже.
5Текстовый ответ, обновлённая корзина и ссылкаРеализовано в пределах локального прототипа.
5Ответ за единицы секундКэш и фоновая загрузка предусмотрены; отдельные прогретые запросы ранее проверены. Нагрузочная гарантия и SLA отсутствуют, OCR/большие файлы/холодная загрузка могут занимать дольше.
6Артикул, название, категория, параметры, сертификаты, цена, остатки по складамМодель данных поддерживает поля. Категория может выводиться из пути карточки с указанием источника. Неизвестные значения не заменяются вымышленными.
6Репрезентативная выборка; разрешены синтетические данныеЕсть live-снимок и отдельный синтетический demo-каталог. Полнота live проверяется через coverage.complete, размер выборки показывается в чате.
8Казахский язык — опциональноПереключатель RU/KK, ответы и подтверждения; AI переводит поисковый запрос. Названия и значения характеристик сохраняются как в каталоге.
8Сопутствующие товары — опциональноМеханизм явных связей и demo-пример DEMO-004. Файл реальных связей пока пуст.
8История авторизованного пользователя — опциональноЛокальная регистрация/вход, SQLite, до 100 сообщений, очистка/удаление. Это отдельная авторизация, не SSO ekt.kz.
8Эскалация менеджеру — опциональноКонтакты и скачиваемый файл запроса. Автоматической отправки в CRM или создания обращения нет.
9Не менять корзину/заказ без согласияМодель не имеет инструментов изменения корзины; мутации контролирует сервер. Оформление заказа не реализовано.
9Достоверные цена и наличиеКарточки основаны на API; перед добавлением свежая проверка. Демо помечено. Абсолютная достоверность свободного текста модели не гарантируется; необходимо проверять ответы и качество источника.
9Не запрашивать/хранить платёжные данные; приватностьПлатёжных полей нет. В чате есть фильтр сообщений, похожих на номера карт и API-ключи; это не полная DLP-защита произвольного текста/вложений. Подробности ниже.
9Защита корзины, объяснимость, совместимость, desktop/mobileCookie/CSRF, одноразовые подтверждения, лимиты; объяснения аналогов; адаптивный интерфейс. Совместимость с production-CMS и покупательской сессией требует интеграционной проверки.
10Репозиторий, README, архитектура, запуск, данныеПодготовлены локально. Публикация последней версии и сдача на платформе отдельно не подтверждены.

Полная поэлементная сверка трёх документов: docs/REQUIREMENTS.md. Контракт недостающей внешней интеграции: docs/EKT_INTEGRATION.md.

Технологии и архитектура

  • Backend: Python, FastAPI, Uvicorn, Pydantic/Pydantic Settings, httpx.
  • Frontend: HTML, CSS, JavaScript без сборщика; находится в ekt-ai-assistant/backend/app/static/. Отдельный frontend-сервер, Node.js и npm install для запуска сайта не нужны.
  • AI: OpenAI Python SDK, Responses API, структурированный JSON и обработка изображений. Модель задаётся OPENAI_MODEL; значение по умолчанию в коде — gpt-5.6-luna. Доступ к модели с нужными возможностями зависит от API-проекта.
  • Файлы: pypdf и PyMuPDF для PDF, python-docx, openpyxl, xlrd, Pillow; OCR через модель с поддержкой изображений.
  • Хранение: SQLite для аккаунтов/истории и сессий/корзин; JSON-снимок каталога.
  • Проверки: unittest, FastAPI TestClient, заглушки API; GitHub Actions.
  • Размещение: Dockerfile, Docker Compose, Caddy для HTTPS — подготовлены, сборка здесь не проверена.
Браузер: чат / карточки / фото / локальная корзина
  → FastAPI: сессия + CSRF + валидация + ограничения запросов
    → Dialogue: контекст → намерение → разговор / поиск / условия / менеджер
      → CatalogService → EKT API (Basic Auth) или DemoClient
      → OpenAI: разбор запроса, документа, фото; объяснение фактов
      → Recommendations: сравнение параметров / заданные связи товаров
    → Cart: предложение → согласие → свежий detail → сохранение корзины
    → Accounts / SessionStore → SQLite
  ↔ Фоновая загрузка каталога → var/catalog.json
README.md
start.ps1                              # запуск на Windows
compose.yaml, deploy/Caddyfile          # подготовка размещения
.github/workflows/test.yml              # CI
 docs/                                 # требования, интеграция, размещение
 ekt-ai-assistant/backend/
   .env.example                        # образец настроек без секретов
   requirements.txt, requirements.lock.txt
   Dockerfile, .dockerignore
   app/main.py                         # маршруты, middleware, фоновые задачи
   app/core/config.py                  # настройки
   app/api/chat.py, attachments.py      # чат, корзина, аккаунты, файлы
   app/models/                         # схемы данных
   app/services/                       # каталог, AI, OCR, история, сессии
   app/static/                         # весь frontend
   data/related_products.json          # согласованные сопутствующие товары
   tests/                              # автоматические проверки
   var/                                # runtime-данные, исключены из Git

Установка и локальный запуск

Рекомендуется Python 3.12. Нужен интернет для установки зависимостей и внешних API; для синтетического поиска/корзины после установки ключи не обязательны. Команды ниже выполняются из корня репозитория.

Windows / PowerShell

# Создать конфигурацию, не перезаписывая существующую:
if (-not (Test-Path ekt-ai-assistant/backend/.env)) {
    Copy-Item ekt-ai-assistant/backend/.env.example ekt-ai-assistant/backend/.env
}

# Демо-каталог, порт 8000:
.\start.ps1 -Demo

Открыть http://127.0.0.1:8000. Скрипт создаёт .runtime, проверяет доступность основных библиотек и при необходимости устанавливает зависимости. Для воспроизводимой установки всех закреплённых версий используйте ручной вариант ниже.

# Запуск с настройками .env:
.\start.ps1

# Если порт занят:
.\start.ps1 -Port 8010

Во втором случае сайт доступен по http://127.0.0.1:8010. Остановить сервер: Ctrl+C. После изменения .env перезапустить; после изменения frontend при необходимости обновить страницу через Ctrl+F5.

Ручная установка и запуск:

python -m venv .runtime
.\.runtime\Scripts\python.exe -m pip install -r ekt-ai-assistant/backend/requirements.lock.txt
cd ekt-ai-assistant/backend
..\..\.runtime\Scripts\python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 1

Если политика PowerShell запрещает запуск скрипта, используйте ручные команды. Старую .venv, перенесённую с другого компьютера, не используйте.

Linux / macOS

python3 -m venv .runtime
.runtime/bin/python -m pip install -r ekt-ai-assistant/backend/requirements.lock.txt
test -f ekt-ai-assistant/backend/.env || cp ekt-ai-assistant/backend/.env.example ekt-ai-assistant/backend/.env
cd ekt-ai-assistant/backend
../../.runtime/bin/python -m uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 1

Этот путь предусмотрен структурой проекта; текущие локальные проверки выполнялись на Windows.

Реальный каталог и AI

В ekt-ai-assistant/backend/.env установить DEMO_MODE=false, заполнить EKT_API_USER и EKT_API_PASSWORD доступами партнёра, OPENAI_API_KEY — своим ключом. Выбрать доступную модель в OPENAI_MODEL. Секреты не вставлять в код, README или frontend.

Демо-режим заменяет источник товаров и условия, но сам по себе не отключает платные AI-запросы при наличии ключа. Для проверки без AI задайте AI_DIALOGUE=false и оставьте OPENAI_API_KEY пустым. Разбор спецификаций в чате и распознавание изображений требуют OpenAI даже в демо.

Настройки

Источник: app/core/config.py. .env загружается из backend, переменные окружения имеют приоритет. Ниже перечислены все настройки приложения.

ПеременнаяПо умолчаниюНазначение
APP_NAMEEKT AI AssistantНазвание API
APP_VERSION0.1.0Версия API
DEMO_MODEtrueСинтетический каталог и demo-условия; false — EKT
COOKIE_SECUREfalseДля локального HTTP; за HTTPS установить true
PURCHASE_TERMSпустоСогласованный текст вместо встроенной справки; один текст для обоих языков
MANAGER_URLhttps://ekt.kz/about/contacts/Ссылка на контакты
AI_DIALOGUEtrueAI-диалог при наличии ключа; не выключает AI-разбор загружаемых файлов
OPENAI_TIMEOUT_SECONDS25Тайм-аут клиента OpenAI, не SLA всего запроса
OPENAI_API_KEYпустоСерверный ключ OpenAI
OPENAI_MODELgpt-5.6-lunaМодель для диалога, structured output и vision
NVIDIA_API_KEYпустоНастройка зарезервирована; вызовов NVIDIA нет
EKT_BASE_URLhttps://ekt.kzАдрес API партнёра
EKT_API_USER / EKT_API_PASSWORDпустоBasic Auth каталога
CATALOG_WARMUPtrueФоновый обход/обновление каталога в live
CATALOG_SEARCH_MAX_PAGES100Страниц за порцию live-загрузки, диапазон 1–1000
CATALOG_TOTAL_MAX_PAGES10000Защитный предел обхода, диапазон 1–50000
CATALOG_DETAIL_CANDIDATES5Максимум детальных кандидатов для сопоставления, диапазон 1–20
CATALOG_CACHE_TTL_SECONDS300Срок кэша, диапазон 0–86400 секунд
DATA_DIRbackend/varБазы SQLite и снимок каталога; путь относительно backend по умолчанию
RELATED_PRODUCTS_FILEbackend/data/related_products.jsonФайл подтверждённых связей товаров

Дополнительно для Compose нужна переменная DOMAIN с реальным доменом. Это параметр размещения, не настройка FastAPI.

Данные и внешние сервисы

Каталог EKT

В документе с данными предоставлены только 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 — детальная карточка.

Логин и пароль хранятся только в серверной конфигурации. Доступы каталога не дают методов изменения корзины, авторизации покупателя или CRM.

Live-каталог загружается порциями с параллелизмом до четырёх страниц. Снимок и курсор сохраняются в var/catalog.json; фон делает паузу 60 секунд между проходами. Полный снимок обновляется по TTL. Незавершённый обход возобновляется; после суток начинается заново. При сбое сохраняются доступные данные, при повторении страниц полнота не объявляется. Статус доступен в /api/health: products, complete, next_page, stale, limit_reached.

Количество товаров меняется во время обхода. Даже complete=true означает завершение пагинации, а не транзакционно согласованную выгрузку склада. Перед показом выбранной карточки и добавлением товара используется detail. Нулевой результат по неполной выборке не доказывает отсутствие товара во всём магазине.

Фотографии загружаются браузером по ссылкам каталога. Реальный товар 027228 / ID 515291 проверен: фото загружается; карточка имеет расхождение тока в названии и свойствах — 160 А и 250 А. Интерфейс показывает предупреждение, автоматический подбор аналога по такой карточке блокируется.

Демо и условия покупки

app/services/demo_catalog.py содержит четыре синтетических товара: отсутствующий DEMO-001, аналог DEMO-002 с остатком 12, кабель DEMO-003, аксессуар DEMO-004. Демо-цены, остатки, склады и условия не относятся к реальным предложениям EKT. demo-certificate.txt — образец для демонстрации.

Встроенная live-справка хранится в app/services/terms.py, основана на странице оплаты и доставки EKT; дата проверки в коде — 2026-09-23. Это сохранённая справка, не автоматическое ежедневное обновление. На странице были противоречивые пороги бесплатной доставки; окончательный тариф должен подтвердить менеджер. Согласованный текст можно внести в PURCHASE_TERMS.

Сопутствующие товары задаются в data/related_products.json: ключ — ID товара, значение — список объектов с product_id, reason и необязательным reason_kk. В live-файле сейчас {}; совместимость не генерируется без подтверждённых связей.

AI и передаваемые данные

OpenAI используется для определения намерения, ответа клиенту, структурирования спецификаций и распознавания маркировки/сканов. Для ответа передаются сообщение, ограниченный контекст истории и необходимые факты каталога; для файлов — извлечённый текст или изображение. Запросы используют store=False; это не обещание отсутствия обработки или любых журналов у внешнего провайдера.

Текст документов, карточек и истории обрабатывается как данные. Промпты запрещают выполнять встроенные команды и выдумывать цену/остаток. Модель не получает инструмента изменения корзины. NVIDIA в текущем приложении не используется; AI-агент Codex применялся при разработке.

Проверка для жюри

Сквозной обязательный сценарий без внешних ключей

  1. Запустить start.ps1 -Demo; для полностью детерминированной проверки отключить AI_DIALOGUE и оставить OpenAI-ключ пустым.
  2. Ввести DEMO-001: проверить нулевой остаток, технические характеристики, ссылку на demo-сертификат и аналог DEMO-002 с объяснением.
  3. У аналога указать количество 2 и нажать «Выбрать». Открытие /cart до подтверждения должно показать пустую корзину.
  4. Вернуться в чат, подтвердить добавление. Корзина должна содержать 2 единицы. Повторное подтверждение не добавляет товар повторно.
  5. Попробовать добавить ещё 11: суммарно получилось бы 13 при остатке 12, поэтому сервер отказывает. Проверить и отказ от нового предложения.
  6. Спросить «Оплата и доставка»: получить содержательный ответ с явной пометкой демонстрационных условий.
  7. Открыть приложение в приватном окне: чужая корзина недоступна. Перезапустить сервер в том же режиме и вернуться в прежнем браузере: корзина сохраняется, если часовая сессия ещё действует.

Дополнительные сценарии

  • AI-диалог: при настроенном ключе написать «Я делаю ремонт и не понимаю, с чего начать», затем уточнить вопрос. Ожидается разговор по задаче, без самовольного добавления товара.
  • RU/KK: переключить язык, задать вопрос и уточнение, проверить подтверждение на казахском.
  • Спецификация: загрузить небольшой DOCX/XLSX/PDF с артикулом и количеством. Проверить распознанные позиции и неопределённые строки; файл не меняет корзину автоматически.
  • Фото/скан: загрузить чёткую маркировку JPEG/PNG или PDF со сканом. Нечитаемые символы нужно уточнить, результат проверить вручную.
  • Live-карточка: включить live, дождаться загрузки нужной части каталога и найти 027228. Проверить фото, цену/остаток из текущего API и предупреждение о противоречии. Конкретные цена и остаток не фиксируются в сценарии, поскольку меняются.
  • История: зарегистрировать локальный аккаунт с паролем от 10 символов, отправить сообщение, выйти и войти; очистить историю или удалить аккаунт.
  • Менеджер: открыть контакты и скачать текст запроса; скачивание не означает, что менеджер уже уведомлён.
  • Сопутствующий товар: отдельный поиск DEMO-002 показывает заданный demo-аксессуар.

API

Документация: /docs, схема: /openapi.json. Swagger загружает ресурсы jsDelivr. Все URL ниже относятся к локальному приложению, а не к API сайта EKT.

Метод и маршрутНазначение
GET /, GET /cartЧат и локальная корзина
GET /api/sessionСоздать/восстановить cookie-сессию, получить CSRF-токен и настройки UI
DELETE /api/sessionОтозвать сессию и удалить её корзину/гостевой диалог
POST /api/chatJSON: message, language (ru / kk)
POST /api/chat/attachmentMultipart-поле file: распознавание и поиск
GET /api/cartПозиции текущей сессии
POST /api/cart/proposeproduct_id, quantity: предложение, без добавления
POST /api/cart/confirmproposal_id, confirmed: подтверждение или отказ
POST /api/languageСмена языка сессии
POST /api/account/register, POST /api/account/loginЛокальная регистрация/вход: username, password
DELETE /api/accountУдаление аккаунта, истории и отзыв его сессий
GET /api/history, DELETE /api/historyЧтение/очистка истории
GET /api/handoffТекстовый файл для передачи менеджеру вручную
GET /api/healthРежим, состояние каталога, признаки настройки сервисов без значений секретов
GET /api/ekt/products?page=N, GET /api/ekt/products/{id}Чтение реального API через backend
POST /api/attachments/extractИзвлечение содержимого файла
POST /api/attachments/parse-specificationСтруктурированный разбор через AI
POST /api/attachments/match-productsСопоставление файла с реальным EKT, независимо от demo-режима

Защищённые маршруты требуют cookie ekt_session; изменяющие запросы и все три API вложений — заголовок X-CSRF-Token из /api/session. При входе токен меняется. Ошибки: 400 — некорректный файл/запрос, 401 — нет действующей сессии, 403 — CSRF, 409 — конфликт подтверждения/цены/количества, 413 — размер, 422 — валидация, 429 — лимит, 502 — ошибка внешней интеграции. Точный контракт доступен в OpenAPI.

Тестирование

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

cd ekt-ai-assistant/backend
..\..\.runtime\Scripts\python.exe -m unittest discover -v

На Linux/macOS заменить путь интерпретатора на ../../.runtime/bin/python. Последний прогон при подготовке README: 47 тестов — OK.

Проверяются извлечение файлов и OCR-конвейер, точные/неоднозначные совпадения, аналоги, десятичные параметры, безопасные ссылки, диалог/контекст/сбой AI, согласие/отмена/повтор, свежая цена и остаток, минимум/кратность, CSRF, изоляция, RU/KK, история и аккаунты, лимиты, восстановление сессии из SQLite, её отзыв/истечение, продолжение каталога и поведение при сбоях/повторении страниц.

Тесты используют заглушки API и временные базы, поэтому не доказывают качество всех ответов настоящей модели. Проверка восстановления имитирует потерю памяти процесса и повторную загрузку сессии из БД. Отдельно в ходе разработки проверялись настоящие EKT/OpenAI-запросы и интерфейс в браузере, включая загрузку реального фото. Нагрузочные испытания, внешний CI и Docker-сборка здесь не подтверждены.

Workflow Backend checks подготовлен для push/pull request, Python 3.12 и запуска unittest на Ubuntu.

Безопасность и хранение данных

  • Cookie: HttpOnly, SameSite=Strict; Secure включается настройкой для HTTPS. Токен CSRF проверяется сервером. Секреты API не передаются frontend.
  • Подтверждение корзины одноразовое, TTL 120 секунд. Изменение цены или недостаточный остаток требуют нового предложения. Серверная блокировка сериализует операции корзины внутри одного процесса.
  • Сессия действует 1 час с создания. Гостевой диалог, язык, корзина и ожидающее подтверждение сохраняются в var/sessions.sqlite3; идентификатор сессии хранится в виде хеша. Фоновая очистка удаляет истёкшие записи. Удалённая сессия не восстанавливается последующим сохранением старого запроса.
  • var/accounts.sqlite3 хранит локальные аккаунты и историю до 100 сообщений. Пароль хешируется scrypt с солью. Вход меняет идентификатор и CSRF и создаёт пустую корзину. Выход удаляет сессию, но сохраняет аккаунтную историю до очистки/удаления аккаунта.
  • AI получает ограниченный контекст, обычно последние 8 записей; история не считается источником текущих цен/остатков.
  • CSP, защита от MIME-sniffing, политика referrer, запрет кэширования ответов. Товарные тексты вставляются как текст, URL проверяются по протоколу.
  • Лимиты: 30 запросов через защищённую mutation-зависимость в минуту на сессию, 120 API-запросов в минуту на адрес клиента. Это не защита от всех видов злоупотреблений.
  • Полей оплаты нет. Сообщения, распознанные фильтром как платёжные данные или ключи, не передаются модели и не входят в историю. Фильтр не покрывает все формы персональных/платёжных данных, особенно внутри вложений.
  • Приложение не создаёт постоянный архив загруженных файлов; multipart-обработка фреймворка может использовать временные файлы. Изображения перекодируются без EXIF перед отправкой AI. Пользователю показано уведомление о передаче данных провайдеру.
  • Фото товара загружается с внешнего адреса каталога, поэтому браузер обращается к серверу изображения. Для фото установлен no-referrer.
  • .env, .runtime, var, временные файлы исключены из Git. Ранее отслеживаемая .venv остаётся в индексе: .gitignore не удаляет уже отслеживаемые файлы и историю. Перед публикацией нужна проверка индекса и истории на секреты; раскрытые ключи следует отозвать и заменить.

Ограничения

ОбластьТекущая граница
Внешняя корзина / CMS / SSOНет API покупательской сессии и изменения корзины; интеграция не выполнена. Локальная корзина не резервирует остаток.
АналогиТребуются одна категория и минимум два известных технических параметра; совпасть должны все распознанные параметры исходного товара. Проверяется ограниченное число кандидатов, выводится до 3 аналогов; инженерный допуск не выдаётся.
КаталогВозможны неполнота выборки, сбой API, повтор страниц, предел обхода и изменения во время загрузки. Сертификаты/поля зависят от партнёра.
Условия покупкиСохранённая справка; актуализация и согласование спорных тарифов — отдельная задача.
AIВозможны ошибки интерпретации, OCR и текста ответа. При сбое пояснения сохраняются доступные карточки; при сбое понимания запроса предлагается повторить/указать артикул. Нужна проверка результатов человеком.
ФайлДо 10 MiB; проверка Content-Length API-запроса — 11 MiB. Это не универсальный потоковый лимит всех возможных запросов.
PDFДо 50 страниц всего; до 5 страниц без текста для OCR. Большой скан нужно разделить.
WordDOCX поддерживается, старый DOC нужно предварительно сохранить как DOCX.
ExcelXLSX: до 5 листов, 1000 строк и 50 значимых столбцов на лист. XLS: до 1000 строк и 50 столбцов на лист. Формулы XLSX не вычисляются: читаются сохранённые результаты.
DOCX/XLSXСуммарный объявленный распакованный размер ZIP — до 50 MiB.
Текст / позицииДокумент — до 50 000 символов, AI обрабатывает блоками до 20 000; чат принимает до 100 распознанных позиций на файл. Текст сообщения — до 2000 символов.
ИзображенияJPEG/PNG до 20 мегапикселей. Результат vision ограничен 20 000 символов с признаком усечения.
Сопутствующие товары / менеджерLive-связи пока отсутствуют; обращения в CRM не отправляются автоматически.
МасштабированиеОдин worker и один экземпляр. SQLite обеспечивает сохранение, но блокировки и IP-лимиты локальны процессу. Для нескольких экземпляров нужны общее хранилище и координация.
ГарантииНет нагрузочного SLA, подтверждённого бизнес-эффекта или полной гарантии отсутствия ошибок модели.

Развёртывание

Публичная deployed-версия отсутствует. Адреса 127.0.0.1 доступны только на компьютере, где запущен сервер, и не являются публичной ссылкой для жюри.

Подготовлены Dockerfile, compose.yaml, Caddyfile и инструкция размещения. Нужны сервер с Docker Compose, домен, DNS и доступные порты 80/443.

На сервере из корня проекта, после заполнения backend .env:

export DOMAIN=assistant.example.com  # заменить своим доменом
docker compose up -d --build
docker compose ps

Compose включает Secure-cookie и постоянный том assistant_data; приложение запускается без root, его порт не публикуется наружу. Caddy обслуживает HTTPS. Docker в текущей среде отсутствует: сборка, сертификат и доступность домена не проверены.

Приложение не доверяет forwarded-заголовкам. За текущим proxy IP-лимит приложения общий для посетителей; перед публичной нагрузкой нужны ограничения на ingress и согласованная настройка доверенного proxy. Подробности резервного копирования и восстановления — в docs/DEPLOYMENT.md. Не удалять тома с данными командой docker compose down -v.

Готовность к сдаче

README покрывает все 11 разделов рекомендованной структуры организаторов: название, проблему/пользователя, функции, сценарий, технологии, архитектуру, запуск, проверку, данные/сервисы, ограничения и статус deployed-версии.

Пункт инструкции участникамСтатус
1. Доступы Codex/OpenAI/NVIDIA, не публиковать ключиCodex использован, поддержка OpenAI есть. Активация личных доступов остаётся ответственностью команды. NVIDIA не интегрирована. Секреты в README не включены.
2–3. Выбрать кейс, изучить требованияВыбран кейс EKT; требования отражены в README и матрице. Отдельная оценочная рубрика в предоставленных материалах не обнаружена.
4. Распределить ролиСостав команды и распределение ролей не предоставлены; не выдумываются.
5. AI-агент и командный репозиторий платформыAI-агент применялся. Принадлежность remote репозиторию, выданному платформой, нужно подтвердить команде.
6. Реализация за 5 часов и сквозная проверкаПрототип и проверки есть; соблюдение пятичасового интервала не подтверждено. Ограничения must-have явно перечислены выше.
7–8. README и рекомендованная структураВыполнено. Документы служат источником требований, а не разрешением на публикацию или передачу данных.
9. Отправить последнюю версию в GitHubПубликация финального состояния этой доработки не подтверждена.
10. «Сдать решение», название/описание, обновления до дедлайнаВнешний шаг команды на платформе; здесь не выполнен.

Перед сдачей:

  • Подтвердить командный репозиторий, роли и дедлайн на платформе.
  • Проверить Git-индекс и историю на секреты/окружения; заменить ранее раскрытые ключи.
  • Повторить demo-сценарий и тесты на чистой установке; при live проверить доступность модели и каталога.
  • Зафиксировать известные ограничения внешней корзины, аналогов, данных партнёра и менеджерской интеграции.
  • При размещении проверить HTTPS, cookie, лимиты, сохранение данных и резервную копию; добавить фактический публичный URL в README.
  • Отправить финальную версию в командный GitHub, дождаться CI и сдать решение на платформе с названием и описанием.

Исходные документы сверки: «Инструкция_для_участников_HackAlem_AI.pdf», «HackAlem AI_ ИИ-ассистент для чата на сайте ekt.kz.pdf», «ИИ-ассистент для чата на сайте ekt.kz ДАННЫЕ.docx.pdf». Они предоставлены отдельно; файл с доступами не следует публиковать в открытом репозитории.

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

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

Islam 7Alihan 2khamza 2

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

  • 2026-09-23 17:25READMEAlihan
  • 2026-09-23 17:14finalIslam
  • 2026-09-23 17:02final touchesIslam
  • 2026-09-23 16:29Front and AI responsesIslam
  • 2026-09-23 15:26AlikhanAlihan
  • 2026-09-23 15:15khamza half projectkhamza
  • 2026-09-23 14:24POSTIslam
  • 2026-09-23 13:58FirstIslam
Все коммиты (11)
  • 2026-09-23 13:44Initial project structureIslam
  • 2026-09-23 12:34tIslam
  • 2026-09-23 12:26testingkhamza
Структура репозитория (44 файлов)
README.md
ekt-ai-assistant/.gitignore
ekt-ai-assistant/backend/.dockerignore
ekt-ai-assistant/backend/.env.example
ekt-ai-assistant/backend/Dockerfile
ekt-ai-assistant/backend/app/__init__.py
ekt-ai-assistant/backend/app/api/__init__.py
ekt-ai-assistant/backend/app/api/attachments.py
ekt-ai-assistant/backend/app/api/chat.py
ekt-ai-assistant/backend/app/core/__init__.py
ekt-ai-assistant/backend/app/core/config.py
ekt-ai-assistant/backend/app/main.py
ekt-ai-assistant/backend/app/models/__init__.py
ekt-ai-assistant/backend/app/models/catalog.py
ekt-ai-assistant/backend/app/models/specification.py
ekt-ai-assistant/backend/app/services/__init__.py
ekt-ai-assistant/backend/app/services/accounts.py
ekt-ai-assistant/backend/app/services/attachment_service.py
ekt-ai-assistant/backend/app/services/catalog_service.py
ekt-ai-assistant/backend/app/services/demo_catalog.py
ekt-ai-assistant/backend/app/services/dialogue.py
ekt-ai-assistant/backend/app/services/ekt_client.py
ekt-ai-assistant/backend/app/services/i18n.py
ekt-ai-assistant/backend/app/services/pdf_ocr.py
ekt-ai-assistant/backend/app/services/recommendations.py
ekt-ai-assistant/backend/app/services/session_store.py
ekt-ai-assistant/backend/app/services/specification_parser.py
ekt-ai-assistant/backend/app/services/terms.py
ekt-ai-assistant/backend/app/services/vision.py
ekt-ai-assistant/backend/app/static/app.js
ekt-ai-assistant/backend/app/static/demo-certificate.txt
ekt-ai-assistant/backend/app/static/i18n.js
ekt-ai-assistant/backend/app/static/index.html
ekt-ai-assistant/backend/app/static/style.css
ekt-ai-assistant/backend/data/related_products.json
ekt-ai-assistant/backend/requirements.lock.txt
ekt-ai-assistant/backend/requirements.txt
ekt-ai-assistant/backend/tests/__init__.py
ekt-ai-assistant/backend/tests/test_backend.py
ekt-ai-assistant/backend/tests/test_catalog_sync.py
ekt-ai-assistant/backend/tests/test_chat.py
ekt-ai-assistant/backend/tests/test_conversation.py
ekt-ai-assistant/backend/tests/test_features.py
ekt-ai-assistant/backend/tests/test_persistence.py

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

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

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