AAYMA
RU
Войти

ЭКТ Помощник по каталогу

Чат-консультант по каталогу ekt.kz: ищет товары, сравнивает их, подбирает аналоги и комплекты под задачу покупателя, показывает цены и остатки по…

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

О проекте

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

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

Суть

Чат-консультант по каталогу ekt.kz: ищет товары, сравнивает их, подбирает аналоги и комплекты под задачу покупателя, показывает цены и остатки по складам и добавляет позиции в демо-корзину после явного подтверждения.

Как устроено

Серверный адаптер получает реальные данные ekt.kz через Basic Auth (выборка из 200 товаров, догружается постранично) и обновляет цены и остатки при открытии карточки. Агент на OpenAI Responses API (gpt-5.4-mini) сам выбирает инструменты поиска, сравнения, аналогов, условий покупки и подготовки предложения (не больше 8 раундов и 18 вызовов). Корзина в Cloudflare D1 меняется только атомарно после подтверждения с повторной проверкой цены и остатка. Конфликты данных, например номинал тока в названии и в свойствах, обнаруживаются и блокируют добавление.

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

  • OpenAI Responses API function calling
  • bounded tool loop
  • точное сопоставление номиналов
  • подбор комплектов под задачу
  • expiring cart proposals
  • atomic idempotent cart ops
  • data conflict detection

Метрики

Задержка ответа: 2–4 с на простые вопросы, ~10–15 с на запросы к API каталога; аудит данных API по 200 товарам

Особенности

Работает с реальным API ekt.kz и проводит аудит его данных. Товары с противоречивыми характеристиками (конфликт 160 А / 250 А) блокируются. Предложения корзины истекают, а подтверждение защищено от гонок и дублей. Есть живая оценка агента на сценариях: казахский язык, попытка выведать ключ, подтверждение корзины.

Стек

TypeScript · React · Vinext · Cloudflare Workers · Cloudflare D1 · Drizzle ORM · shadcn/ui · Vite · Node.js

Модели

OpenAI gpt-5.4-mini


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

README

README.md

hack-8aa2aaa2-salem

Hackathon team repository for Salem

ЭКТ Помощник по каталогу

Рабочий прототип для кейса HackAlem AI. Каталог и детальные карточки получают данные ekt.kz через сервер с Basic Auth. Демонстрационная корзина хранится в D1 и не связана с заказами магазина.

Что работает

  • Подсказки чата заполняют редактируемый черновик, не отправляют ответ. Поля шаблона выделяются и требуют заполнения; введённый текст сохраняется.
  • Локальный SF Pro Display из предоставленного WOFF (Semibold, 600), с предзагрузкой и системным резервным шрифтом.
  • Адаптивный каталог, поиск по названию, артикулу магазина и производителя, категории и сортировка.
  • Начальная выборка 200 реальных товаров из 10 страниц; 200 подробных карточек. Кнопка загрузки добавляет следующие страницы в общий серверный индекс. Это не полный каталог.
  • Обновление цены, характеристик и остатков по складам при открытии карточки.
  • ИИ-агент на OpenAI Responses API (gpt-5.4-mini, reasoning low): сам выбирает инструменты поиска, проверки карточек, сравнения, условий покупки, аналогов и подготовки предложения. Поддерживает русский и казахский, контекст последних 20 сообщений. При отсутствии ключа сохраняется явно обозначенный ограниченный режим поиска.
  • История сообщений, контекст последнего найденного товара и корзина сохраняются на сервере в рамках сессии.
  • Создание предложения на 5 минут без изменения корзины. Явное подтверждение кнопкой или сообщением в чате, повторная проверка цены и остатка, защита от параллельного повторного добавления.
  • Подбор решения по проблеме: до двух ключевых вопросов за ответ, до шести обязательных компонентов, один или два полных комплекта. Проверка характеристик и цены, объяснение каждой позиции, сравнение итоговых сумм и скачиваемый отчёт.
  • Выбор комплекта кнопкой или явным сообщением «Выбираю бюджетный» / «Выбираю расширенный» добавляет все позиции одной атомарной операцией после повторной проверки API. Предложение действует 15 минут; повторные запросы не удваивают количество. Новый подбор заменяет старый.
  • Удаление с подтверждением и экспорт тестовой корзины в CSV.
  • Выявление конфликтов номинального тока в названии/описании и структурированном свойстве. Товар 515291 показывает конфликт 160 А / 250 А и блокируется для добавления.
  • Кандидаты на замену отбираются по четырём заданным параметрам. Интерфейс не объявляет их полностью взаимозаменяемыми: монтаж, тип устройства и остальные свойства должен проверить специалист.

Границы прототипа

  1. API реальной корзины не предоставлен. На ekt.kz не отправляются операции изменения корзины, резервирования или оформления заказа. Ссылка «Перейти на ekt.kz» не переносит выбранные позиции.
  2. Валюта KZT принята как допущение и обозначена в интерфейсе. В ответе API отдельное поле валюты отсутствует. Включение НДС и персональные цены не подтверждены.
  3. Доступность для тестовой корзины — не больше общего остатка API и суммы складов без служебных записей (брак, резерв, маркетинг, образцы, витрина, перемещение, восстановленный товар); при расхождении суммы складов и общего остатка добавление блокируется. Это демонстрационное правило, а не подтверждённая политика отгрузки магазина. Общий остаток API отдельно виден в карточке.
  4. Единица количества для корзины — целые единицы; фактическую единицу продажи подтверждает магазин. Кратность, метры, упаковки и варианты offers требуют отдельного контракта. Товары с непустым offers не добавляются автоматически.
  5. Условия покупки основаны на проверенной 23.09.2026 публичной странице https://ekt.kz/checkout-delivery/. Противоречащие друг другу пороги бесплатной доставки не используются для обещаний. Ссылки на сертификаты в доступной выборке не представлены; агент сообщает об ограничении данных.
  6. Загрузка и распознавание Excel, Word, PDF и фотографий пока не реализованы. В интерфейсе нет неработающей кнопки загрузки.
  7. Для агента нужен серверный OPENAI_API_KEY; OPENAI_MODEL по умолчанию gpt-5.4-mini. Запросы расходуют API-баланс. В OpenAI передаются текст диалога и результаты инструментов; store:false, платежные данные запрашивать запрещено. На сайте действует 60 сообщений в час на сессию, не более одного одновременного агентного запроса. При сбое модели интерфейс сообщает о недоступности, не имитирует ответ ИИ.
  8. Классификация категорий эвристическая, поиск ограничен загруженной выборкой. Для промышленного применения нужна полная фоновая синхронизация и словарь категорий.
  9. Сессия действует 7 дней. Очистка истёкших сессий и связанных пользовательских данных выполняется при очередном запуске сессии; неиспользуемый сайт требует отдельно запланированной очистки. Каталог сохраняется независимо.

Архитектура

React UI → API Vinext / Cloudflare Worker → адаптер ekt.kz и D1.

  • app/catalog-app.tsx — интерфейс и взаимодействия.
  • app/api/[...path]/route.ts — HTTP-маршруты, сессия, обработка ошибок.
  • lib/agent.ts — ограниченный цикл вызова инструментов, строгая валидация, проверка происхождения карточек, максимум 8 раундов / 18 вызовов.
  • lib/agent-search.ts — поиск с бюджетом, наличием и точным сопоставлением номиналов (25 А не совпадает с 125 А).
  • lib/purchase-conditions.ts — проверенные условия покупки, источник и ограничения.
  • lib/server.ts — адаптер каталога, поиск и сценарии чата, предложения, атомарные операции корзины.
  • lib/solutions.ts — потребности, варианты, проверка полноты и точных ограничений, суммы и явный выбор.
  • app/solution-card.tsx — карточки комплектов и скачиваемый отчёт.
  • lib/catalog.ts — нормализация, обнаружение конфликтов, валидация количества, фильтры аналогов.
  • db/schema.ts и drizzle/ — схема и миграции.
  • data/catalog.json — исходный снимок реальных данных с датой загрузки.
  • docs/openapi.json — контракт реализованного API.

Секреты находятся только в локальных игнорируемых .env / .dev.vars и серверных секретах опубликованного сайта. Они не входят в клиентский код и Git.

Локальный запуск

Нужен Node.js 24 и npm.

npm ci

Создайте .env и .dev.vars из .env.example, заполните доступ к каталогу. В .dev.vars для Windows-предпросмотра дополнительно укажите:

EKT_LOCAL_API_BASE=http://127.0.0.1:5173/__ekt-local-api/

Этот режим направляет запросы из локального Worker через Node-транспорт Vite. Шлюз работает только в dev-режиме, проверяет Basic Auth, допускает только GET списка/карточки и обращается только к ekt.kz. В production Worker обращается напрямую к фиксированному origin ekt.kz; локальный шлюз не включается в сборку.

npm run build
node --import ./scripts/sites-env.mjs ./node_modules/wrangler/bin/wrangler.js d1 execute DB --local --config dist/server/wrangler.json --persist-to .wrangler/state --file drizzle/0000_same_hellion.sql
npm run dev

Примените по порядку все SQL-файлы из drizzle/: 0000, 0001 и 0002 (каждый один раз). Откройте адрес, напечатанный сервером. Локальный шлюз по умолчанию ожидает порт 5173; при смене порта обновите настройку и allowlist в адаптере.

Проверки

node --test tests/*.test.mjs
node node_modules/typescript/bin/tsc --noEmit
python tests/integration.py

Интеграционные проверки требуют работающего локального сервера и доступа к ekt.kz; они создают отдельные тестовые сессии, не оформляют заказы. Проверяют обязательное подтверждение, изоляцию сессий, конфликт данных, остатки, идемпотентность и параллельные подтверждения, историю и загрузку следующей страницы.

Публикация

Проект подготовлен для Sites с D1 DB. Установите серверные секреты EKT_API_USER и EKT_API_PASSWORD, соберите и опубликуйте через Sites. При переносе в другой проект замените идентификатор Sites своим. Первоначальная публикация закрытая.

Следующие интеграции

  • Подтвердить контракт корзины, правила складов, валюту, единицы и кратность.
  • Получить утверждённые условия покупки, сертификаты и правила аналогов по категориям.
  • Расширять оценку качества подключённого агента и проверки разрешений на действия с корзиной.
  • Добавить изолированную обработку файлов и экран сверки распознанных строк.
  • Настроить полный импорт, плановую очистку, мониторинг и лимиты перед публичным запуском.

Проверка агента

node --test tests/agent.test.mjs tests/catalog.test.mjs tests/http-client.test.mjs

Живые проверки с реальной моделью и API каталога записаны в docs/agent-live-evaluation.json. Пройдены уточнение, поиск, контекст, сравнение, конфликт данных, условия покупки, казахский, запрос раскрытия ключа, подготовка и явное подтверждение корзины. Это небольшая проверочная выборка, не гарантия отсутствия ошибок модели. В измерениях простые ответы занимали 2–4 с, запросы с API каталога около 10–15 с: требование «единицы секунд» для всех сценариев пока не достигнуто.

Агент читает корзину и доступные ранее показанные предложения через read_cart, подтверждает выбор через apply_cart_selection, меняет точное количество/удаляет одну позицию через set_cart_quantity. Сервер проверяет явность просьбы, ссылку на товар, принадлежность сессии и актуальные данные. Оплата и оформление заказа недоступны. prepare_cart создаёт истекающее предложение, подтверждение кнопкой или сообщением повторно проверяет цену и остатки. Таблица сравнения формируется из API, не генерируется моделью. Отрицательные проверки используют поддельные вызовы модели, недопустимые идентификаторы и количество, неизвестные товары в ответе, ошибки квоты.

Оставшиеся ограничения кейса: реальный API корзины отсутствует; файлы/изображения пока не принимаются; гарантировать хотя бы один совместимый аналог для каждой отсутствующей позиции нельзя по частичной выборке. Для промышленного запуска нужны полная синхронизация, утверждённые условия магазина, расширенная оценка качества и управление общим бюджетом на уровне OpenAI-проекта.

Проверка достоверности API

Отчёт проверки 200 товаров, машиночитаемые результаты. Повторный запуск: node scripts/audit-api.mjs; обновление снимка: node scripts/audit-api.mjs --refresh. Цены, остатки и дата получения показываются без подмены неизвестных значений нулями.

Интерфейс подбора

  • Сравнение 2–4 товаров из каталога или ответа агента: свежие запросы, подсветка различий, фильтр отличий, отдельное обозначение неизвестных значений и ошибок обновления.
  • Карточка с основными параметрами, копированием артикула, вкладками характеристик, складов и документов, закреплённой панелью количества.
  • Расширенное окно помощника, контекст выбранного товара, многострочный ввод (Enter — отправка, Shift+Enter — перенос).
  • Сравнение и просмотр карточек не изменяют корзину. При закрытии сравнения незавершённые ответы не меняют его состояние.

Агентный подбор решения

Подробности и сценарии проверки: docs/SOLUTION-AGENT.md. Бюджетный вариант — минимальный среди показанных проверенных комплектов, не гарантия самой низкой цены во всём магазине. Поиск проверяет до шести кандидатов на потребность в загруженной выборке. Если подтверждённой альтернативы нет, агент предлагает один вариант; обязательный отсутствующий компонент нельзя молча исключать. Цена сама по себе не подтверждает качество.

Завершение задачи и доступ к корзине

Готовый ответ или успешное действие заканчивает задачу без необязательных вопросов и подсказок. Статус хранится в D1. Кнопка «Продолжить разговор» возвращает ввод с прежним контекстом. Доступны ручное завершение и корзина из панели чата. Подробности и проверки: docs/CONVERSATION-LIFECYCLE.md.

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

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

IL4elove4ek 5

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

  • 2026-09-23 17:47Enable agent cart actions and complete/resume conversations without repeated promptsIL4elove4ek
  • 2026-09-23 17:18Make assistant suggestions editable drafts, improve dialogue context and add SF Pro DisplayIL4elove4ek
  • 2026-09-23 16:49Add problem-solving AI bundles with selection, atomic cart and explanation reportsIL4elove4ek
  • 2026-09-23 16:13Improve product comparison, assistant UI and verified catalog dataIL4elove4ek
  • 2026-09-23 15:28Add EKT AI assistant with catalog tools, confirmed cart, docs and testsIL4elove4ek
Структура репозитория (145 файлов)
.env.example
.gitignore
.npmrc
.openai/hosting.json
README.md
app/api/[...path]/route.ts
app/catalog-app.tsx
app/chat-suggestions.tsx
app/chatgpt-auth.ts
app/globals.css
app/layout.tsx
app/page.tsx
app/product-comparison.tsx
app/product-details.tsx
app/product-ui.tsx
app/solution-card.tsx
cloudflare-env.d.ts
components.json
components/ui/accordion.tsx
components/ui/alert-dialog.tsx
components/ui/alert.tsx
components/ui/aspect-ratio.tsx
components/ui/attachment.tsx
components/ui/avatar.tsx
components/ui/badge.tsx
components/ui/breadcrumb.tsx
components/ui/bubble.tsx
components/ui/button-group.tsx
components/ui/button.tsx
components/ui/calendar.tsx
components/ui/card.tsx
components/ui/carousel.tsx
components/ui/chart.tsx
components/ui/checkbox.tsx
components/ui/collapsible.tsx
components/ui/combobox.tsx
components/ui/command.tsx
components/ui/context-menu.tsx
components/ui/dialog.tsx
components/ui/direction.tsx
components/ui/drawer.tsx
components/ui/dropdown-menu.tsx
components/ui/empty.tsx
components/ui/field.tsx
components/ui/form.tsx
components/ui/hover-card.tsx
components/ui/input-group.tsx
components/ui/input-otp.tsx
components/ui/input.tsx
components/ui/item.tsx
components/ui/kbd.tsx
components/ui/label.tsx
components/ui/marker.tsx
components/ui/menubar.tsx
components/ui/message-scroller.tsx
components/ui/message.tsx
components/ui/native-select.tsx
components/ui/navigation-menu.tsx
components/ui/pagination.tsx
components/ui/popover.tsx
components/ui/progress.tsx
components/ui/radio-group.tsx
components/ui/resizable.tsx
components/ui/scroll-area.tsx
components/ui/select.tsx
components/ui/separator.tsx
components/ui/sheet.tsx
components/ui/sidebar.tsx
components/ui/skeleton.tsx
components/ui/slider.tsx
components/ui/sonner.tsx
components/ui/spinner.tsx
components/ui/switch.tsx
components/ui/table.tsx
components/ui/tabs.tsx
components/ui/textarea.tsx
components/ui/toggle-group.tsx
components/ui/toggle.tsx
components/ui/tooltip.tsx
data/catalog-preview.json
data/catalog.json
db/index.ts
db/schema.ts
docs/API-DATA-AUDIT.md
docs/CHAT-UX.md
docs/CONVERSATION-LIFECYCLE.md
docs/SOLUTION-AGENT.md
docs/agent-live-evaluation.json
docs/api-audit.json
docs/openapi.json
drizzle.config.ts
drizzle/0000_same_hellion.sql
drizzle/0001_complete_surge.sql
drizzle/0002_old_albert_cleary.sql
drizzle/0003_plain_harrier.sql
drizzle/meta/0000_snapshot.json
drizzle/meta/0001_snapshot.json
drizzle/meta/0002_snapshot.json
drizzle/meta/0003_snapshot.json
drizzle/meta/_journal.json
eslint.config.mjs
examples/d1/app/api/notes/route.ts
examples/d1/db/schema.ts
hooks/use-mobile.ts
lib/agent-search.ts
lib/agent.ts
lib/catalog.ts
lib/chat-suggestions.ts
lib/conversation.ts
lib/http-client.ts
lib/purchase-conditions.ts
lib/server.ts
lib/solutions.ts
lib/utils.ts
next.config.ts
package-lock.json
package.json
postcss.config.mjs
public/favicon.svg
public/file.svg
public/fonts/SF-PRO-DISPLAY.woff
public/globe.svg
public/window.svg
scripts/audit-api.mjs
scripts/build-verified.sh
scripts/execution-profile.mjs
scripts/install-ci.mjs
scripts/install-ci.sh
scripts/install-pnpm.sh
scripts/npm-install.mjs
scripts/pnpm-install.mjs
scripts/run-framework.mjs
scripts/sites-env.mjs
scripts/sites-env.sh
tests/agent.test.mjs
tests/catalog.test.mjs
tests/chat-suggestions.test.mjs
tests/conversation-integration.py
tests/conversation.test.mjs
tests/http-client.test.mjs
tests/integration.py
tests/solutions-integration.py
tests/solutions.test.mjs
tsconfig.json
vite.config.ts

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

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

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