AAYMA
RU
Войти

Atlas

Рабочее место менеджера по закупкам: детерминированный расчёт заказов поставщикам, которым управляет AI-агент с ограниченными инструментами.

Доведённый продукт
Команда «Atlas» 23💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: Atlas
Кейс HackAlem.ai: Логистика — Электрокомплект · ekt.kz
Стадия: Доведённый продукт

Задача кейса: Автоматический расчёт заказов поставщикам для пополнения склада, с утверждением менеджером

Суть

Рабочее место менеджера по закупкам: детерминированный расчёт заказов поставщикам, которым управляет AI-агент с ограниченными инструментами. Менеджер редактирует ревизии, утверждает их и выгружает CSV.

Как устроено

Импортированный нормализованный набор данных сохраняется неизменяемым снимком в PostgreSQL. Агент на OpenAI Agents SDK (GPT-4.1) вызывает три инструмента в фиксированном порядке: inspectDemand, classifyEvents и calculateOrders. Количества считает только backend. Крупные разовые продажи классифицирует отдельный GPU-специалист (Qwen2.5-1.5B на llama.cpp CUDA, Brev NVIDIA L4); если GPU недоступен, система честно переходит в degraded-режим с обязательным подтверждением. Менеджер правит строки с указанием причины (с защитой от устаревшей ревизии), подтверждает предупреждения, утверждает ревизию и выгружает CSV.

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

  • OpenAI Agents SDK tool calling
  • детерминированный расчёт спроса и пополнения
  • классификация аномальных продаж LLM-специалистом
  • ревизии с optimistic concurrency
  • Zod-контракты
  • аудит действий

Особенности

Чёткое разделение ролей: модель управляет последовательностью tool calls, но не может задать количество заказа. Отдельный приватный GPU-сервис с честным degraded-статусом. Human-in-the-loop утверждение конкретной ревизии; CSV выгружается только для утверждённых строк.

Стек

TypeScript · Next.js · React · Node.js · Fastify · PostgreSQL · Drizzle ORM · Zod · pnpm workspaces · Docker Compose · Brev GPU · llama.cpp CUDA

Модели

OpenAI GPT-4.1 · Qwen2.5-1.5B (llama.cpp)


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

README

README.md

Atlas — расчёт пополнения запасов с проверяемым AI-агентом

Atlas помогает менеджеру по закупкам подготовить, проверить и утвердить заказ на пополнение склада. Количества рассчитывает детерминированный backend; AI-агент вызывает реальные инструменты системы и объясняет ход обработки, а решение об утверждении остаётся за человеком.

Проблема

В кейсе «Электрокомплект» менеджеры вручную сводят продажи, остатки, поставки и сезонность, часто в таблицах. Из-за этого медленно обнаруживаются дефицит и избыток, а крупная разовая продажа может исказить оценку регулярного спроса. Ошибка в количестве связывает оборотный капитал или приводит к отсутствию нужных компонентов. Для расчёта важно видеть и результат, и данные, на которых он основан.

Решение

Atlas принимает нормализованный набор данных, проверяет его и сохраняет снимок. Затем агент изучает спрос и события через ограниченные инструменты, а backend детерминированно рассчитывает рекомендации. Менеджер видит основания и предупреждения, редактирует черновик, подтверждает предупреждения, утверждает конкретную ревизию и выгружает утверждённые строки в CSV.

Данные → анализ → вызовы инструментов → расчёт backend → сохранённый черновик → проверка человеком → утверждённая ревизия → CSV.

Это не чат, который только предлагает текст: агент вызывает операции над данными приложения, а бизнес-результат создаётся и проверяется кодом backend. Система не отправляет заказ поставщику.

Демонстрационный сценарий

  1. Менеджер выбирает демонстрационный набор данных, склад и категорию.
  2. Запускает расчёт пополнения.
  3. Агент проверяет спрос, классифицирует крупные события и вызывает расчёт заказов.
  4. Backend сохраняет результат и ревизию; интерфейс показывает рекомендации по поставщикам, количества, основания, события и статусы OpenAI/GPU.
  5. Менеджер при необходимости меняет количество с указанием причины. Изменение создаёт новую ревизию; запрос со старой ревизией отклоняется.
  6. Менеджер подтверждает необходимые предупреждения и утверждает актуальную ревизию.
  7. Скачивает CSV и может повторно открыть тот же утверждённый результат.

Seed содержит синтетическую историю за 24 месяца и шесть SKU. Демонстрационные данные не являются данными партнёра.

Реализованные возможности

  • Импорт проверенного нормализованного JSON с сохранением неизменяемого снимка набора данных.
  • Детерминированный расчёт спроса и рекомендаций по пополнению с объяснениями.
  • OpenAI Agents SDK с реальными ограниченными инструментами анализа и расчёта.
  • Частная граница GPU-специалиста для классификации крупных событий; при недоступности GPU статус честно переходит в degraded-режим с подтверждением предупреждения человеком.
  • Черновики заказов по поставщикам, редактирование количеств с причиной и защита от устаревшей ревизии.
  • Подтверждение предупреждений, утверждение ревизии и аудит действий.
  • CSV только для утверждённой ревизии; интерфейс и объяснения поддерживают русский и английский языки.
  • Повторяемый синтетический seed и локальный браузерный end-to-end сценарий.

Архитектура AI-агента

Агент реализован в packages/ai на OpenAI Agents SDK. В подтверждённом live-запуске использовался OpenAI GPT-4.1; модель задаётся конфигурацией. Агент получает ограниченные наблюдения, а не прямой доступ к базе или произвольным API. Он вызывает три backend-инструмента в фиксированном порядке:

  • inspectDemand — получить агрегированное представление спроса;
  • classifyEvents — обработать события продаж через specialist boundary;
  • calculateOrders — запросить детерминированный расчёт backend.

Инструменты не принимают от модели произвольные количества заказа. Количества, проверки и сохранение принадлежат backend. AI возвращает структурированное решение и ссылки на результаты инструментов; интерфейс показывает события выполнения, не скрытые рассуждения модели. Вызовы ограничены по времени, числу ходов и повторов.

GPU-специалист — отдельный приватный сервис, вызываемый только AI-адаптером. В записанном сквозном прогоне использовался Brev с NVIDIA L4 и Qwen2.5-1.5B через llama.cpp CUDA. При отсутствии проверенной GPU-вычислительной активности система не выдаёт фиктивный результат: специалист и GPU-доказательство отсутствуют, а соответствующее предупреждение требует подтверждения.

Архитектура системы

flowchart LR
    U[Менеджер] --> W[Next.js workbench]
    W -->|same-origin /api/v1| A[Fastify API]
    A --> C[Общие Zod-контракты]
    A <--> D[(PostgreSQL через Drizzle)]
    A --> R[AI runner / Agents SDK]
    R <--> O[OpenAI API]
    R --> T[Ограниченные backend tools]
    T --> I[Детерминированный калькулятор]
    T --> G[Приватный GPU specialist]
    I --> A
    G --> R
    A --> D
    A --> W

Структура репозитория

apps/
  api/                 Fastify routes, валидация, расчёт и workflow заказов
  web/                 Next.js workbench, локализация и браузерный E2E
packages/
  ai/                  OpenAI agent, tools и GPU client boundary
  contracts/           Общие строгие Zod-схемы и выведенные типы
  db/                  Drizzle schema, миграции, seed и persistence
infra/brev/            Конфигурация и доказательства GPU deployment
docs/                  Кейс, спецификации, контракты и отчёты проверок

Технологии

УровеньТехнологииНазначение
FrontendNext.js, React, TypeScriptРабочее место менеджера и локализованный workflow
BackendNode.js, Fastify, TypeScriptHTTP API, бизнес-проверки, расчёты и ревизии
AIOpenAI Agents SDK, OpenAI APIУправление последовательностью реальных ограниченных tool calls
GPU specialistBrev GPU, NVIDIA L4, llama.cpp CUDA, Qwen2.5-1.5BКлассификация крупных событий в проверенном live-запуске
DatabasePostgreSQL, Drizzle ORMСнимки данных, расчёты, строки заказов и аудит
КонтрактыZod, @atlas/contractsЕдиная runtime-валидация запросов, данных и ответов
ТестированиеNode test runner через tsx, Playwright-подобный локальный Chrome harnessПроверки пакетов и браузерный сквозной сценарий
Инфраструктураpnpm workspaces, Docker ComposeМонорепозиторий и локальный запуск web/API/PostgreSQL

API и контракты инструментов

Браузер обращается к same-origin /api/v1; web проксирует запросы в Fastify API. API и пакеты используют общие строгие Zod-схемы из packages/contracts. AI-инструменты ограничены бизнес-операциями backend и не имеют SQL-доступа.

Основные маршруты:

  • GET/POST /api/v1/datasets — список и импорт нормализованных наборов данных;
  • POST /api/v1/runs и GET /api/v1/runs/:id — запуск и чтение расчёта;
  • PATCH /api/v1/runs/:id/lines — изменение строки с проверкой ревизии;
  • POST /api/v1/runs/:id/approve — утверждение актуальной ревизии;
  • GET /api/v1/runs/:id/export?revision=…&locale=… — CSV утверждённой версии.

Контракты подробно описаны в docs/api.md и docs/ai-contract.md. Партнёрский формат 1С не подтверждён, поэтому CSV не следует считать совместимым с конкретной конфигурацией 1С.

Запуск

Требования

  • Node.js 22.16.x;
  • pnpm 11.15.1;
  • Docker с Docker Compose;
  • Google Chrome нужен только для локального браузерного E2E.

Локальный базовый Compose запускает PostgreSQL 16.9, API и web на http://localhost:3000. GPU specialist настраивается отдельно и не требуется для честного degraded-режима.

Установка и окружение

git clone https://github.com/BAITC-Hacks/hack-801b451b-atlas.git
cd hack-801b451b-atlas
pnpm install --frozen-lockfile
cp .env.example .env

В PowerShell вместо последней команды: Copy-Item .env.example .env.

Установите непустой POSTGRES_PASSWORD. Для живого запуска агента добавьте OPENAI_API_KEY и задайте OPENAI_MODEL (в проверенном прогоне применялся gpt-4.1-2025-04-14). API-ключ хранится только на серверной стороне в .env; не помещайте его в NEXT_PUBLIC_* переменные. Без ключа нельзя считать live-вызов OpenAI проверенным. GPU-поля оставьте настроенными только для соответствующего GPU deployment; пустая/недоступная GPU должна отображаться как degraded, а не как успех.

ПеременнаяНужна локальноНазначение
POSTGRES_PASSWORDДаПароль PostgreSQL в Docker Compose; задайте локальное значение
DATABASE_URLДля запуска пакетов вне ComposeПодключение к PostgreSQL; внутри Compose API получает URL из конфигурации сервиса
OPENAI_API_KEYДля live AIСерверный ключ OpenAI; не публиковать и не коммитить
OPENAI_MODELДля live AIИдентификатор используемой модели
GPU_SERVICE_URLТолько для GPU deploymentВнутренний адрес GPU specialist
GPU_MODEL_IDТолько для GPU deploymentИдентификатор модели specialist
GPU_VERIFICATION_PATHТолько для GPU deploymentПуть к проверочным данным runtime
API_HOSTОбычно значение .env.exampleАдрес привязки API
WEB_ORIGINОбычно значение .env.exampleРазрешённый origin браузерного приложения
API_INTERNAL_URLОбычно значение .env.exampleАдрес API, используемый web-контейнером
DEMO_OPERATORНет, есть значение по умолчаниюИмя локального оператора для demo-аудита; не является аутентификацией

Запуск сервисов и базы

docker compose up --build -d
docker compose exec -T api pnpm --filter @atlas/db migrate
docker compose exec -T api pnpm --filter @atlas/db seed

Откройте http://localhost:3000. Seed идемпотентен и создаёт синтетический набор данных. Для остановки: docker compose down. Команда docker compose down -v удалит локальный том базы.

В корне нет общего pnpm dev; для разработки web при уже доступных API и БД существует команда:

pnpm --filter @atlas/web dev

Сборка и тесты

Команды из корня репозитория:

pnpm -r --if-present typecheck
pnpm -r --if-present build

pnpm --filter @atlas/contracts exec tsx --test test/contracts.test.ts
pnpm --filter @atlas/db exec tsx --test test/persistence.test.ts
pnpm --filter @atlas/ai exec tsx --test test/config.test.ts test/openai.test.ts test/gpu.test.ts test/run.test.ts
pnpm --filter @atlas/api exec tsx --test test/import.test.ts test/calculation.test.ts test/runs.test.ts test/orders.test.ts
pnpm --filter @atlas/web exec tsx --test test/transport.test.ts

Пакетные тесты проверяют контракты, persistence, AI/GPU статусы, импорт, расчёт, изменения/утверждения и web transport. Отдельного полного набора E2E для всех внешних партнёрских интеграций в проекте нет.

Браузерный E2E запускается на работающем Compose stack, с seed, Chrome и настроенным ключом OpenAI:

$env:ATLAS_BASE_URL = 'http://localhost:3000'
pnpm --filter @atlas/web e2e:local

Если Chrome находится не по стандартному пути, задайте ATLAS_CHROME_PATH. Сценарий проверяет расчёт, редактирование, конфликт устаревшей ревизии, подтверждение предупреждений, утверждение, скачивание CSV и повторное чтение сохранённого состояния. GPU может быть недоступна: тест принимает только честный degraded-статус.

Пример выполнения агента

Запрос менеджера: рассчитать пополнение выбранного склада
  → inspectDemand()
  → classifyEvents() → GPU specialist либо честный degraded-результат
  → calculateOrders() → детерминированный расчёт backend
  → сохранение черновика и ревизии в PostgreSQL
  → менеджер проверяет строки и предупреждения
  → edit / acknowledge / approve
  → CSV утверждённой ревизии

Агент не утверждает заказ и не отправляет его поставщику. Все количественные результаты принадлежат backend.

Инженерные решения

  • Разделение рассуждения и исполнения: LLM координирует ограниченные инструменты, бизнес-количества считает обычный backend-код.
  • Общие контракты: строгие Zod-схемы используются на границах пакетов и HTTP API.
  • Защита ревизий: правка и утверждение привязаны к конкретной версии; устаревшая запись не должна незаметно перезаписать новую.
  • Проверяемый аудит: действия по строкам и утверждению сохраняются вместе с актором и временем.
  • Честный GPU fallback: недоступность или непроверенность GPU не маскируется локальной имитацией inference.
  • Подтверждение человеком: менеджер проверяет изменения и предупреждения до утверждения заказа.

Ограничения

  • Импорт принимает нормализованный JSON, а не произвольные CSV/XLSX-выгрузки.
  • Seed синтетический; прогнозная эвристика replenishment-v1 не откалибрована по истории партнёра, её точность и экономический эффект не измерены.
  • Идентичность оператора локальная и не заменяет аутентификацию или роли.
  • CSV — предлагаемый обменный формат. Нет подтверждённого образца/спецификации 1С и успешного импорта в систему партнёра.
  • Утверждение сохраняет локальное состояние и не создаёт документ закупки в 1С, не отправляет заказ и не подтверждает поставку.
  • Записанный GPU live-run подтверждает конкретную конфигурацию и запуск; GPU-экземпляр после проверки остановлен. Для нового запуска нужны доступная инфраструктура и свежая проверка runtime.

Дальнейшая работа

Следующие практические шаги — получить реальные обезличенные выгрузки и согласовать импорт, проверить формат CSV с партнёром в тестовой 1С, добавить серверную аутентификацию и роли, а затем измерить качество расчёта на исторических данных без утечки будущих наблюдений. Эти интеграции и измерения не заявлены как готовые.

Хакатон

  • Событие: HACKALEM AI (название сохранено в проектных материалах).
  • Трек: Логистика.
  • Команда: название и список участников в репозитории не указаны.
  • Цель: сократить ручную работу при планировании пополнения запасов, сохранив детерминированный расчёт, проверяемые действия AI и обязательное решение менеджера.

Документация и проверочные записи

Зафиксированный combined run — a162030e-9c3b-459c-b106-632881838e4d. Его результаты относятся к синтетическим данным и конкретному проверенному runtime; это не подтверждение качества на данных партнёра или совместимости с его 1С.

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

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

ehala69 13dynamicmines 6Ali4ok 3

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

  • 2026-09-23 17:38docs: write Russian project READMEehala69
  • 2026-09-23 17:25Add revision-aware order quote and budget checkAli4ok
  • 2026-09-23 17:23Add revision-aware order quote and budget checkAli4ok
  • 2026-09-23 17:217 commitdynamicmines
  • 2026-09-23 17:20feat(web): prioritize shortage lines and preflight sales CSVdynamicmines
  • 2026-09-23 16:31docs: record verified GPU shutdown and degraded rerunehala69
  • 2026-09-23 16:26checkpoint: verify Brev GPU combined workflowehala69
  • 2026-09-23 15:50checkpoint: stabilize verified application workflowehala69
Все коммиты (22)
  • 2026-09-23 15:34Verify real frontend workflow through OpenAI and approvalehala69
  • 2026-09-23 15:30checkpoint: wire frontend workflow to live APIehala69
  • 2026-09-23 15:22Add frontend shell and typed workflow client (integration pending)dynamicmines
  • 2026-09-23 15:184commitehala69
  • 2026-09-23 15:07Integrate live OpenAI run and revision-safe order routesehala69
  • 2026-09-23 15:06Add frontend shell and typed workflow client (integration pending)dynamicmines
  • 2026-09-23 14:55Keep demand inspection within bounded tool timeehala69
  • 2026-09-23 14:53Implement AI runner and GPU client boundariesAli4ok
  • 2026-09-23 14:51Prepare draft assembly and revision-safe order servicesehala69
  • 2026-09-23 14:42Implement deterministic demand calculation and scoped toolsehala69
  • 2026-09-23 14:36Prepare Brev CUDA deployment and verification scriptsehala69
  • 2026-09-23 14:35Build backend workspace contracts persistence and import APIehala69
  • 2026-09-23 14:022 commitdynamicmines
  • 2026-09-23 14:00first commitdynamicmines
Структура репозитория (149 файлов)
.dockerignore
.env.example
.gitignore
.repowise/wiki.db
AGENTS.md
Dockerfile.api
Dockerfile.web
MODEL-POLICY.md
README.md
apps/api/package.json
apps/api/scripts/openai-flow.ts
apps/api/src/app.ts
apps/api/src/calculation/index.ts
apps/api/src/config.ts
apps/api/src/orders/index.ts
apps/api/src/orders/quote.ts
apps/api/src/routes.ts
apps/api/src/runs/assemble.ts
apps/api/src/server.ts
apps/api/src/tools/index.ts
apps/api/test/calculation.test.ts
apps/api/test/import.test.ts
apps/api/test/orders.test.ts
apps/api/test/quote.test.ts
apps/api/test/runs.test.ts
apps/api/tsconfig.json
apps/api/tsconfig.test.json
apps/web/next-env.d.ts
apps/web/next.config.ts
apps/web/package.json
apps/web/postcss.config.mjs
apps/web/src/app/globals.css
apps/web/src/app/layout.tsx
apps/web/src/app/page.tsx
apps/web/src/components/locale-provider.tsx
apps/web/src/components/ui/button.tsx
apps/web/src/components/workbench/LiveWorkbench.tsx
apps/web/src/components/workbench/index.tsx
apps/web/src/lib/api.ts
apps/web/src/lib/priority.ts
apps/web/src/lib/sales-csv.ts
apps/web/src/lib/transport.ts
apps/web/src/lib/utils.ts
apps/web/src/messages/en.ts
apps/web/src/messages/ru.ts
apps/web/tailwind.config.ts
apps/web/test/fixtures/degraded-run.json
apps/web/test/fixtures/gpu-success-stub.json
apps/web/test/fixtures/synthetic-dataset.json
apps/web/test/local-flow.mjs
apps/web/test/preview-transport.ts
apps/web/test/priority-csv.test.ts
apps/web/test/transport.test.ts
apps/web/tsconfig.json
compose.yaml
docs/ai-contract.md
docs/ai/orchestrator.md
docs/ai/plan.md
docs/ai/tasks/AI01.md
docs/ai/tasks/AI02.md
docs/ai/tasks/AI03.md
docs/ai/tasks/AI04.md
docs/ai/tasks/AI05.md
docs/ai/tasks/AI06.md
docs/ai/tasks/AI07.md
docs/ai/tasks/AI08.md
docs/ai/waves.md
docs/api.md
docs/backend/orchestrator.md
docs/backend/plan.md
docs/backend/tasks/B01.md
docs/backend/tasks/B02.md
docs/backend/tasks/B03.md
docs/backend/tasks/B04.md
docs/backend/tasks/B05.md
docs/backend/tasks/B06.md
docs/backend/tasks/B07.md
docs/backend/tasks/B08.md
docs/backend/tasks/B09.md
docs/backend/tasks/B10.md
docs/backend/tasks/B11.md
docs/backend/tasks/B12.md
docs/backend/tasks/B13.md
docs/backend/tasks/B14.md
docs/backend/tasks/B15.md
docs/backend/waves.md
docs/case.md
docs/evaluation-map.md
docs/execution-conventions.md
docs/final-checklist.md
docs/frontend/orchestrator.md
docs/frontend/plan.md
docs/frontend/tasks/FRT01.md
docs/frontend/tasks/FRT02.md
docs/frontend/tasks/FRT03.md
docs/frontend/tasks/FRT04.md
docs/frontend/tasks/FRT05.md
docs/frontend/tasks/FRT06.md
docs/frontend/tasks/FRT07.md
docs/frontend/tasks/FRT08.md
docs/frontend/waves.md
docs/product-spec.md
docs/review/application.md
docs/review/combined.md
docs/review/planning-check.md
docs/review/sentinel.md
docs/waves.md
infra/brev/.gitattributes
infra/brev/bootstrap.sh
infra/brev/compose.gpu.yaml
infra/brev/deployment.md
infra/brev/gpu-smoke.sh
infra/brev/restart.sh
infra/brev/smoke-request.json
infra/brev/verify-deployment.sh
package.json
packages/ai/package.json
packages/ai/scripts/gpu-smoke.ts
packages/ai/scripts/openai-smoke.ts
packages/ai/src/config.ts
packages/ai/src/gpu/index.ts
packages/ai/src/index.ts
packages/ai/src/openai/agent.ts
packages/ai/src/run.ts
packages/ai/test/config.test.ts
packages/ai/test/gpu.test.ts
packages/ai/test/openai.test.ts
packages/ai/test/run.test.ts
packages/ai/tsconfig.json
packages/contracts/package.json
packages/contracts/src/index.ts
packages/contracts/test/contracts.test.ts
packages/contracts/tsconfig.json
packages/contracts/tsconfig.test.json
packages/db/migrations/0001_initial.sql
packages/db/migrations/0002_run_lines.sql
packages/db/package.json
packages/db/scripts/env.ts
packages/db/scripts/migrate.ts
packages/db/scripts/seed.ts
packages/db/src/fixture.ts
packages/db/src/index.ts
packages/db/src/schema.ts
packages/db/test/persistence.test.ts
packages/db/tsconfig.json
packages/db/tsconfig.test.json
pnpm-lock.yaml
pnpm-workspace.yaml
tsconfig.base.json
Ветки (4)

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

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

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