О проекте
Команда: Kzen
Кейс HackAlem.ai: Логистика — Электрокомплект · ekt.kz
Стадия: Рабочий MVP
Задача кейса: Автоматический расчёт заказов поставщикам для пополнения склада, с утверждением менеджером
Суть
Сервис для закупщика Электрокомплекта: из Excel-выгрузок 1С (ИЭК, Systeme Electric) считает рекомендуемые заказы поставщикам с пошаговым обоснованием, ручными правками, согласованием руководителем и выгрузкой XLSX/CSV для 1С.
Как устроено
Отчёты 1С связываются по коду товара в помесячную историю; разовые накладные (≥10× медианы) и всплески свыше трёх ожидаемых уровней очищаются, сезонные пики сохраняются. Спрос оценивается с учётом тренда, сезонности и месяцев с нулевым остатком; из потребности на срок поставки + период пересмотра вычитаются свободный остаток и поставки в пути (с учётом ETA), результат округляется по минимуму и кратности. Агент закупщика с tools, trace и what-if задержки поставки; LLM только пишет текст объяснения с проверкой чисел, без ключа используется шаблон. Clean architecture (api/application/domain/infrastructure), версии заказа и журнал в памяти.
Ключевые решения
- очистка выбросов по медиане накладных
- сезонность и тренд спроса
- lead time + review period
- округление по MOQ/кратности
- what-if задержки поставки
- agent tools с trace
- LLM-обоснование с проверкой чисел
- workflow согласования
Особенности
Жёсткое разделение: количество считает детерминированное расчётное ядро, LLM лишь формулирует объяснение и проверяется на совпадение чисел; экран «Проверки» с пятью сценариями ТЗ и скрипт оценки бизнес-эффекта по ассортименту.
Стек
Python 3.11 · FastAPI · Pydantic · openpyxl · Redis · React 19 · TypeScript · Vite · Docker Compose · nginx
Модели
gpt-4o-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-9cbdba26-kzen.
README
README.mdKZen — рекомендации заказов поставщикам
KZen помогает менеджеру закупок ТОО «Электрокомплект» превратить выгрузки 1С в понятный заказ поставщикам. Сервис рассчитывает количество по каждому товару, показывает причины рекомендации и даёт человеку проверить заказ перед выгрузкой.
Что умеет сервис
- Загружает Excel-выгрузки ИЭК и Systeme Electric; без файлов запускается на демонстрационных данных.
- Учитывает продажи, остатки, товар в пути, сезонность, тренд и условия отгрузки. Показывает рекомендации по поставщикам, срочность и расчёт по шагам.
- Позволяет искать товары, менять параметры расчёта и вручную исправлять количество с указанием причины.
- Даёт менеджеру отправить заказ на согласование, руководителю — утвердить его, а затем скачать XLSX или CSV для 1С.
- Показывает пять проверок требований технического задания на отдельном экране.
Как получается рекомендация
Сервис связывает отчёты по коду 1С и собирает историю товара по месяцам. Разовая накладная становится кандидатом на исключение, если она не менее чем в 10 раз больше медианной накладной товара и составляет не менее 50% доступной истории накладных. Месячный всплеск свыше трёх ожидаемых уровней заменяется ожидаемым спросом; повторяющийся сезонный пик сохраняется.
Расчёт оценивает спрос за месяцы с нулевым или пустым начальным остатком, затем учитывает тренд и сезонность. Из потребности на срок поставки и период пересмотра вычитаются свободный остаток и поступления, которые успеют прийти; заказ округляется по минимуму и кратности отгрузки. Оценки отсутствия товара нужно сверять с исходными остатками.
ИИ может только сформулировать текст объяснения: рекомендуемое количество считает расчётное ядро. Без ключа OpenAI показывается локальный шаблон.
Технологии и архитектура
- Интерфейс: React 19, TypeScript, Vite.
- Сервер и расчёт: Python 3.11, FastAPI, Pydantic, openpyxl. Redis используется для кэша в Docker.
- Необязательное текстовое объяснение: OpenAI-совместимый API, по умолчанию модель
gpt-4o-mini.
Интерфейс обращается к REST API. В сервере маршруты api вызывают сценарии
application, расчётные правила находятся в domain, а чтение Excel, кэш,
экспорт и вызов ИИ — в infrastructure. Обучать модель для запуска не нужно.
Запуск
Понадобятся Git и Docker с Docker Compose. На Windows сначала запустите Docker Desktop. В терминале:
git clone https://github.com/BAITC-Hacks/hack-9cbdba26-kzen.git
cd hack-9cbdba26-kzen
docker compose up --build -d
Откройте интерфейс. Документация API доступна по адресу
localhost:3000/docs. Первый запуск может занять
несколько минут из-за сборки образов. Для остановки выполните
docker compose down.
Файлы партнёра не входят в репозиторий, поэтому чистый клон работает на синтетическом демо-наборе. Для реальных расчётов загрузите Excel-файлы на экране «Данные»: первый импорт поставщика требует все шесть отчётов 1С с именами и колонками партнёра, дальше можно загружать любой поднабор. После импорта версии расчёта и ручные правки сбрасываются, потому что считались по старым данным.
Для необязательного текста ИИ создайте в корне .env по образцу .env.example,
укажите NARRATOR_BACKEND=openai и свой OPENAI_API_KEY, затем снова выполните
docker compose up -d. Файл .env исключён из Git.
Как проверить
- Откройте localhost:3000. На экране «Данные» нажмите «Рассчитать рекомендации». Для проверки достаточно демо-данных.
- Перейдите в «Рекомендации», откройте товар и посмотрите историю, прогноз и шаги расчёта.
- В карточке товара измените количество, укажите причину и сохраните правку.
- На экране «Согласование» отправьте версию на согласование. Переключите демонстрационную роль на «Руководитель», утвердите версию и скачайте файл для 1С.
- На экране «Проверки» убедитесь, что пять сценариев ТЗ пройдены.
Данные и ограничения
Источники — Excel-отчёты 1С двух поставщиков: продажи, остатки, детализация продаж, товар в пути, условия отгрузки и сезонность. Результат выгружается в XLSX или CSV; прямого подключения к 1С и автоматической отправки поставщикам нет.
- Нулевой или пустой начальный остаток служит признаком возможного отсутствия товара, но не подтверждает его. У ИЭК нет отдельного текущего снимка свободного остатка: используется начальный остаток последнего месяца. Эти оценки нужно проверить до утверждения заказа.
- Импорт понимает текущие форматы отчётов партнёров; ручного сопоставления колонок нет.
- Роли демонстрационные, полноценной авторизации нет. Версии заказа и журнал хранятся в памяти процесса и пропадают после перезапуска.
- Хронологический бэктест ещё не реализован.
Авторы коммитов
История коммитов
- 2026-09-23 17:55Revert "Импорт принимает любой поднабор файлов: недостающие берутся из текущего набора"Aldiyar Amantay
- 2026-09-23 17:55Revert "Редизайн интерфейса под product design: дизайн-система, шаги процесса, статусы цветом"Aldiyar Amantay
- 2026-09-23 17:49README: абзац про импорт корочеAldiyar Amantay
- 2026-09-23 17:49Таблица рекомендаций: при равном покрытии крупные заказы выше; README про частичный импортAldiyar Amantay
- 2026-09-23 17:47Импорт принимает любой поднабор файлов: недостающие берутся из текущего набораAldiyar Amantay
- 2026-09-23 17:46Write concise jury READMEteriyaki0
- 2026-09-23 17:41Merge origin/main and fix import dependencyteriyaki0
- 2026-09-23 17:37Clean Markdown docs and update READMEteriyaki0
Все коммиты (75)
- 2026-09-23 17:35Редизайн интерфейса под product design: дизайн-система, шаги процесса, статусы цветомAldiyar Amantay
- 2026-09-23 17:35narrate: убрана неиспользуемая переменная, тест импортов отсортирован под ruffAldiyar Amantay
- 2026-09-23 17:33Fix Redis cache initializationMikhail
- 2026-09-23 17:32Изменение докер файлаMikhail
- 2026-09-23 17:29Загрузка выгрузок 1С через интерфейс: импорт по поставщику в фоне, отчёт о качестве, сброс версийAldiyar Amantay
- 2026-09-23 17:24Merge remote-tracking branch 'origin/main'teriyaki0
- 2026-09-23 17:23Distinguish zero stock from restored demandteriyaki0
- 2026-09-23 17:23Avoid false OpenAI narrative fallbacksteriyaki0
- 2026-09-23 17:17README по требованияиMikhail
- 2026-09-23 17:14Show OpenAI narrative source in SKU screenteriyaki0
- 2026-09-23 17:09Reject unsupported LLM adjustment claimsteriyaki0
- 2026-09-23 17:02Merge remote-tracking branch 'origin/main'teriyaki0
- 2026-09-23 17:02Show tiny forecast value beside SKU chartteriyaki0
- 2026-09-23 17:01Переменные и адаптер нарратора переименованы под OpenAIAldiyar Amantay
- 2026-09-23 16:59Merge remote-tracking branch 'origin/main'teriyaki0
- 2026-09-23 16:59Use Russian decimals in demand explanationsteriyaki0
- 2026-09-23 16:58Нарратор переключён на OpenAI (gpt-4o-mini): провайдер задаётся адресом в .envAldiyar Amantay
- 2026-09-23 16:55Show fractional demand accurately in SKU detailsteriyaki0
- 2026-09-23 16:54Clarify low-demand SKU history chartteriyaki0
- 2026-09-23 16:46Не выдавать нулевые месяцы за прогноз без историиteriyaki0
- 2026-09-23 16:45Показать отсутствие истории вместо пустого прогнозаteriyaki0
- 2026-09-23 16:41Указать допущение в источнике остатка ИЭКteriyaki0
- 2026-09-23 16:40Предупредить о неподтверждённом остатке ИЭК в карточкеteriyaki0
- 2026-09-23 16:38Разрешить локальный адрес API для Viteteriyaki0
- 2026-09-23 16:31Уточнить объяснение восстановления спроса по пустым остаткамteriyaki0
- 2026-09-23 16:30Показать фактические продажи и оценку отдельно на графикеteriyaki0
- 2026-09-23 16:22Исправить высоту столбцов истории и прогнозаteriyaki0
- 2026-09-23 16:16Обновлять шапку и рекомендации между экранамиteriyaki0
- 2026-09-23 16:16Синхронизировать согласование и журнал с APIteriyaki0
- 2026-09-23 16:16Подключить обоснование и шаги агента в карточке позицииteriyaki0
- 2026-09-23 16:16Подключить пагинацию и сценарии экрана рекомендацийteriyaki0
- 2026-09-23 16:16Уточнить контракт API для экранов фронтаteriyaki0
- 2026-09-23 16:05Уточнить структуру экрана данных по прототипуteriyaki0
- 2026-09-23 16:01Merge remote-tracking branch 'origin/main'teriyaki0
- 2026-09-23 16:00Исправить сброс сессии на экране данныхteriyaki0
- 2026-09-23 15:59LLM-обоснование с проверкой чисел, срочность и обоснование в выгрузке, приоритет разбора у агентаAldiyar Amantay
- 2026-09-23 15:58Merge remote-tracking branch 'origin/main'teriyaki0
- 2026-09-23 15:57Уточнить экран рекомендаций по эталонному макетуteriyaki0
- 2026-09-23 15:54Посчитать бизнес-эффект по всему ассортиментуMikhail
- 2026-09-23 15:50Merge remote-tracking branch 'origin/main'teriyaki0
- 2026-09-23 15:47Перенести экран проверок ТЗ из прототипаteriyaki0
- 2026-09-23 15:45Перенести проверку заказа и экспорт из прототипаteriyaki0
- 2026-09-23 15:43Перенести экран объяснения SKU из прототипаteriyaki0
- 2026-09-23 15:42Перенести экран рекомендаций из прототипаteriyaki0
- 2026-09-23 15:41Перенести экран данных и общую оболочку из прототипаteriyaki0
- 2026-09-23 15:27Учесть ETA партий в расчёте заказаMikhail
- 2026-09-23 15:27Добавить факты для защиты по выбросам и ETAMikhail
- 2026-09-23 15:26Цифры для защиты и демо-сценарий; тост расчёта считает «к заказу» как таблицаAldiyar Amantay
- 2026-09-23 15:25bench.py меряет ручки закупщика вместо /predict из каркасаAldiyar Amantay
- 2026-09-23 15:22Карточка, what-if и агент чистят историю так же, как расчётAldiyar Amantay
- 2026-09-23 15:21Connect frontend API client to real backendteriyaki0
- 2026-09-23 15:20pitch_notes: кейс, находки в данных, агент и рабочий процесс, вопросы жюриAldiyar Amantay
- 2026-09-23 15:19Короткая формула в таблице рекомендаций: потребность − свободно − путьAldiyar Amantay
- 2026-09-23 15:11Слияние: категория в расчёте (Миша) поверх восстановленной историиAldiyar Amantay
- 2026-09-23 15:09Восстановлена история main после force push; фронтенд сохранёнAldiyar Amantay
- 2026-09-23 15:08Учесть категорию в расчёте и описать очистку выбросовMikhail
- 2026-09-23 15:05Add React TypeScript frontend with 5 screens and design systemteriyaki0
- 2026-09-23 15:05Initial commit: hackathon ML service skeletonteriyaki0
- 2026-09-23 14:57API фронта: убраны неработающие настройки, выгрузка по колонкам, полный сброс сессииAldiyar Amantay
- 2026-09-23 14:52API под контракт фронта (FRONTEND_DATA.md), демо-набор, согласование заказаAldiyar Amantay
- 2026-09-23 14:44реализованы функции для работы с эксель, тесты самих функцийMikhail
- 2026-09-23 14:44Первая фича готова, но без адекватного апиMikhail
- 2026-09-23 14:38Экспорт для 1С: срочность и обоснование по п. 5 ТЗ; сверка чеклиста с кейсомAldiyar Amantay
- 2026-09-23 14:35Чеклист команды и документация по агенту, версиям и экспорту в 1СAldiyar Amantay
- 2026-09-23 14:32Агент закупщика: tools, ветвления, trace, what-if задержки поставки, xlsx для 1СAldiyar Amantay
- 2026-09-23 14:03Рабочий процесс закупщика: версии расчёта, корректировки, утверждение, экспортAldiyar Amantay
- 2026-09-23 13:25Initial commit: hackathon ML service skeletonteriyaki0
Структура репозитория (131 файлов)
.dockerignore .env.example .gitignore CASE.md Makefile README.md backend/Dockerfile backend/app/__init__.py backend/app/api/__init__.py backend/app/api/deps.py backend/app/api/errors.py backend/app/api/middleware.py backend/app/api/routes/__init__.py backend/app/api/routes/agent.py backend/app/api/routes/drafts.py backend/app/api/routes/health.py backend/app/api/routes/imports.py backend/app/api/routes/orders.py backend/app/api/routes/ui.py backend/app/api/schemas/__init__.py backend/app/api/schemas/common.py backend/app/api/schemas/drafts.py backend/app/api/schemas/orders.py backend/app/application/__init__.py backend/app/application/use_cases/__init__.py backend/app/application/use_cases/agent.py backend/app/application/use_cases/drafts.py backend/app/application/use_cases/imports.py backend/app/application/use_cases/narrate.py backend/app/application/use_cases/replenishment.py backend/app/application/use_cases/selfcheck.py backend/app/application/use_cases/ui.py backend/app/application/use_cases/workspace.py backend/app/core/__init__.py backend/app/core/config.py backend/app/core/container.py backend/app/core/logging.py backend/app/core/presets.py backend/app/domain/__init__.py backend/app/domain/assessment.py backend/app/domain/demand.py backend/app/domain/entities.py backend/app/domain/exceptions.py backend/app/domain/ports.py backend/app/domain/workflow.py backend/app/infrastructure/__init__.py backend/app/infrastructure/cache/__init__.py backend/app/infrastructure/cache/memory.py backend/app/infrastructure/cache/redis_cache.py backend/app/infrastructure/export/__init__.py backend/app/infrastructure/export/onec_xlsx.py backend/app/infrastructure/export/table.py backend/app/infrastructure/forecasting/__init__.py backend/app/infrastructure/forecasting/baseline.py backend/app/infrastructure/forecasting/smoothed.py backend/app/infrastructure/llm/__init__.py backend/app/infrastructure/llm/openai_compat.py backend/app/infrastructure/llm/template.py backend/app/infrastructure/storage/__init__.py backend/app/infrastructure/storage/data_quality.py backend/app/infrastructure/storage/demo_data.py backend/app/infrastructure/storage/draft_store.py backend/app/infrastructure/storage/excel_loader.py backend/app/infrastructure/storage/excel_normalizer.py backend/app/infrastructure/storage/memory_repo.py backend/app/main.py backend/requirements.txt docker-compose.yml docs/CHECKLIST.md docs/FRONTEND_AGENT_TRACE.md docs/design/METHODOLOGY.md docs/design/README (1).md docs/design/prototype.html docs/design/prototype_source.dc.html docs/design/styles.css docs/methodology.md frontend/.gitignore frontend/.oxlintrc.json frontend/Dockerfile frontend/index.html frontend/nginx.conf frontend/package-lock.json frontend/package.json frontend/public/favicon.svg frontend/public/icons.svg frontend/src/App.css frontend/src/App.tsx frontend/src/api/client.ts frontend/src/assets/hero.png frontend/src/assets/react.svg frontend/src/assets/vite.svg frontend/src/components/ImportPanel.tsx frontend/src/components/layout/ContextBar.tsx frontend/src/components/layout/TopNav.tsx frontend/src/index.css frontend/src/main.tsx frontend/src/mock/data.ts frontend/src/screens/DataScreen.tsx frontend/src/screens/RecommendationsScreen.tsx frontend/src/screens/ReviewScreen.tsx frontend/src/screens/SkuScreen.tsx frontend/src/screens/ValidationScreen.tsx frontend/src/styles/components.css frontend/src/styles/globals.css frontend/src/styles/tokens.css frontend/src/types/index.ts frontend/tsconfig.app.json frontend/tsconfig.json frontend/tsconfig.node.json frontend/vite.config.ts metrics.json ml/__init__.py ml/notebooks/eda_template.ipynb ml/src/__init__.py ml/src/config.py pyproject.toml run_config.json scripts/bench.py scripts/business_effect.py tests/conftest.py tests/test_agent_api.py tests/test_demand.py tests/test_drafts_api.py tests/test_excel_loader.py tests/test_health.py tests/test_imports_api.py tests/test_narrative.py tests/test_orders_api.py tests/test_replenishment_core.py tests/test_ui_api.py uv.lock
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.