Пошаговые инструкции intermediate 18 мин

Как сделать ИИ-агента для прогноза спроса

Пошаговая инструкция от нуля до рабочего прототипа: история продаж, остатки, события, baseline-прогноз, LLM-объяснение, approval и backtest.

AI-агенты n8n Google Sheets закупки остатки прогноз спроса demand forecasting backtest

Что получится в результате

Соберем ИИ-агента, который раз в неделю прогнозирует спрос по товарам или услугам и готовит понятные рекомендации для закупки, производства или маркетинга.

Первая рабочая версия будет делать так:

  1. история продаж лежит в таблице `sales_history`;
  2. остатки лежат в `stock`;
  3. промо, праздники и события лежат в `events`;
  4. n8n запускает расчет по расписанию;
  5. workflow строит простой базовый прогноз на 4 недели вперед;
  6. агент проверяет выбросы, остатки и дни без товара;
  7. LLM объясняет, почему прогноз вырос или снизился;
  8. результат попадает в `forecast_output` со статусом `draft`;
  9. менеджер проверяет прогноз и ставит `approved`, `needs_review` или `rejected`;
  10. approved-рекомендации превращаются во внутренние задачи, но не создают заказ поставщику автоматически.

В первой версии агент не закупает товар сам, не меняет цены, не запускает рекламу и не обещает точность. Он считает прогноз, показывает основания и помогает принять решение.

Что понадобится

  • n8n Cloud или self-hosted n8n.
  • Google Sheets для первого прототипа.
  • История продаж минимум за 8-12 недель, лучше за 6-12 месяцев.
  • Список товаров или услуг.
  • Остатки и дни отсутствия товара.
  • Данные о промо, праздниках и крупных событиях.
  • API-ключ LLM-провайдера.
  • Ответственный менеджер, который подтверждает рекомендации.

Шаг 1. Выберите объект прогноза

Не начинайте с “прогнозировать весь бизнес”.

Для первого прототипа выберите один уровень:

  1. SKU;
  2. категория;
  3. услуга;
  4. филиал;
  5. канал продаж.

Самый простой старт:

прогноз спроса по SKU на 4 недели вперед

Проверка: у каждого SKU есть история продаж и текущий остаток.

Шаг 2. Создайте таблицу проекта

Создайте Google Sheet:

Demand forecast AI agent

Добавьте листы:

products
sales_history
stock
events
forecast_output
action_queue
forecast_log
settings
backtest
test_cases

Проверка: у n8n есть доступ на чтение и запись ко всем листам.

Шаг 3. Создайте справочник товаров

В листе `products` сделайте колонки:

sku
product_name
category
unit
min_stock
lead_time_days
is_active
manager

Пример:

SKU-1001
AI-консультация базовая
services
шт
5
7
yes
Иван

Проверка: у каждого активного товара есть `sku`, `min_stock`, `lead_time_days` и ответственный.

Шаг 4. Создайте историю продаж

В листе `sales_history` сделайте колонки:

date
sku
quantity
revenue
channel
region
order_id
is_return

Пример:

2026-05-01
SKU-1001
3
45000
site
moscow
O-9001
no

Правило:

возвраты храните отдельно через is_return = yes

Проверка: за выбранный период по каждому SKU есть продажи по датам.

Шаг 5. Создайте лист остатков

В листе `stock` сделайте колонки:

date
sku
stock_on_hand
reserved
available_stock
stockout

Пример:

2026-05-20
SKU-1001
18
3
15
no

Если товара не было в наличии:

stockout: yes

Проверка: агент сможет отличить падение спроса от ситуации “товара не было на складе”.

Шаг 6. Создайте календарь событий

В листе `events` сделайте колонки:

date_start
date_end
event_type
sku
category
impact
comment

Типы:

  • `promo`;
  • `holiday`;
  • `price_change`;
  • `stockout`;
  • `launch`;
  • `external_event`.

Пример:

2026-05-10
2026-05-17
promo
SKU-1001
services
high
скидка 20% на базовую консультацию

Проверка: крупные промо и события не теряются в “шуме” продаж.

Шаг 7. Создайте настройки прогноза

В листе `settings` добавьте:

key
value
comment

Заполните:

forecast_horizon_weeks | 4 | на сколько недель вперед прогнозировать
history_weeks | 12 | сколько недель брать для базового прогноза
moving_average_weeks | 4 | окно скользящего среднего
min_history_points | 8 | минимум недель для прогноза
stockout_adjustment | yes | учитывать дни без товара
high_risk_wape | 0.35 | порог плохой точности

Проверка: параметры прогноза можно менять без переписывания workflow.

Шаг 8. Создайте лист результата

В листе `forecast_output` сделайте колонки:

forecast_id
sku
product_name
category
period_start
period_end
forecast_quantity
baseline_quantity
last_4_weeks_avg
trend
current_stock
recommended_order_qty
risk_level
confidence
explanation
review_status
review_comment
approved_by
created_at
approved_at

Статусы:

  • `draft`;
  • `approved`;
  • `needs_review`;
  • `rejected`;
  • `done`;
  • `error`.

Проверка: прогноз и рекомендация не смешиваются с сырыми продажами.

Шаг 9. Создайте очередь действий

В листе `action_queue` сделайте колонки:

action_id
forecast_id
sku
manager
action_type
message_draft
reason
risk_level
review_status
task_id
created_at
processed_at
error

Типы действий:

  • `order_more`;
  • `reduce_order`;
  • `check_stockout`;
  • `review_promo`;
  • `no_action`.

Проверка: даже approved-прогноз сначала превращается во внутреннюю задачу, а не в автоматический заказ.

Шаг 10. Создайте workflow расчета

Назовите workflow:

Demand forecast weekly

Добавьте узлы:

  1. `Schedule Trigger`;
  2. `Google Sheets` - чтение `settings`;
  3. `Google Sheets` - чтение `products`;
  4. `Google Sheets` - чтение `sales_history`;
  5. `Google Sheets` - чтение `stock`;
  6. `Google Sheets` - чтение `events`;
  7. `Code` - нормализация данных;
  8. `Code` - агрегация продаж по неделям;
  9. `Code` - расчет базового прогноза;
  10. `Code` - расчет потребности и рисков;
  11. `LLM` - объяснение прогноза;
  12. `Code` - проверка JSON;
  13. `Google Sheets` - запись `forecast_output`;
  14. `Google Sheets` - запись `action_queue`;
  15. `Google Sheets` - запись `forecast_log`.

Проверка: workflow создан и запускается вручную.

Шаг 11. Настройте расписание

В `Schedule Trigger` поставьте:

Mode: Every Week
Weekday: Monday
Hour: 07
Minute: 30
Timezone: Europe/Moscow

Проверка: прогноз готов до планирования закупок или производства.

Шаг 12. Нормализуйте продажи

В узле `Code` приведите данные к одному виду.

function qty(value) {
  return Math.max(0, Number(String(value || '0').replace(',', '.')));
}

function money(value) {
  return Math.round(Number(String(value || '0').replace(',', '.')) * 100) / 100;
}

function dateOnly(value) {
  return String(value || '').slice(0, 10);
}

Возвраты учитывайте отдельно:

если is_return = yes, quantity вычитается из продаж

Проверка: продажи, возвраты и пустые значения не ломают расчет.

Шаг 13. Сгруппируйте продажи по неделям

Для каждого SKU посчитайте:

week_start
sku
quantity_sum
revenue_sum
orders_count

Неделя начинается с понедельника.

Пример:

2026-05-04 | SKU-1001 | 18 | 270000 | 12
2026-05-11 | SKU-1001 | 25 | 375000 | 16

Проверка: по каждому SKU есть недельный ряд, а не разрозненные продажи по дням.

Шаг 14. Уберите недели без наличия

Если в неделе был `stockout = yes`, не считайте ее обычным падением спроса.

Правило первой версии:

если stockout_days >= 2, неделя помечается как distorted
distorted-недели не входят в moving average

Проверка: отсутствие товара не занижает прогноз.

Шаг 15. Посчитайте базовый прогноз

Используйте простую и проверяемую формулу:

baseline = среднее quantity_sum за последние 4 нормальные недели

Если доступно меньше 4 недель, но больше `min_history_points`, берите среднее по доступным неделям.

Если истории меньше минимума:

review_status = needs_review
risk_level = high
reason = мало истории

Проверка: прогноз можно пересчитать вручную по таблице.

Шаг 16. Посчитайте тренд

Сравните средние:

last_4_weeks_avg
previous_4_weeks_avg
trend = (last_4_weeks_avg - previous_4_weeks_avg) / previous_4_weeks_avg

Интерпретация:

  • `trend > 0.20` - спрос растет;
  • `trend < -0.20` - спрос падает;
  • иначе спрос стабилен.

Проверка: резкий рост или спад виден отдельно от базового среднего.

Шаг 17. Учтите промо и события

Если на будущий период запланировано промо:

impact = high -> baseline * 1.25
impact = medium -> baseline * 1.10
impact = low -> baseline * 1.05

Если промо было в прошлых 4 неделях, но в будущем его нет:

снизить влияние промо-недели или отправить прогноз в needs_review

Проверка: скидочная неделя не превращается в завышенный обычный спрос.

Шаг 18. Рассчитайте прогноз на 4 недели

Для каждой будущей недели:

forecast_quantity = baseline с учетом trend и events

Округление:

товары в штуках -> округлить вверх
услуги -> округлить до целого или до допустимой единицы

Проверка: в `forecast_output` будет отдельная строка на SKU и неделю.

Шаг 19. Рассчитайте рекомендуемый заказ

Формула первой версии:

recommended_order_qty = forecast_quantity + min_stock - available_stock

Если результат меньше 0:

recommended_order_qty = 0

Если `lead_time_days > 7`, учитывайте две недели прогноза:

recommended_order_qty = forecast_next_2_weeks + min_stock - available_stock

Проверка: агент не предлагает заказать товар, которого и так достаточно на складе.

Шаг 20. Посчитайте уровень риска

Правила:

critical: available_stock = 0 и forecast_quantity > 0
high: recommended_order_qty > 0 и lead_time_days >= 14
medium: trend > 20% или trend < -20%
low: обычный прогноз без отклонений

Отдельно ставьте `needs_review`, если:

  • мало истории;
  • были stockout-недели;
  • есть промо с high impact;
  • прогноз отличается от прошлого больше чем на 50%.

Проверка: самые рискованные SKU поднимаются наверх.

Шаг 21. Добавьте LLM-объяснение

LLM не должен считать прогноз. Он объясняет уже посчитанные цифры.

System prompt:

Ты аналитик спроса.
Пиши только по переданным данным.
Не придумывай причины роста или падения.
Не обещай точность прогноза.
Верни только JSON.

User prompt:

Данные прогноза:
{{ JSON.stringify($json.forecast_item) }}

Верни JSON:
{
  "explanation": "2-3 предложения: почему такой прогноз",
  "recommended_action": "что сделать менеджеру",
  "risk_level": "low|medium|high|critical",
  "needs_review_reason": "string|null"
}

Проверка: ответ модели не содержит новых цифр, которых не было во входных данных.

Шаг 22. Проверьте JSON и факты

После LLM добавьте `Code`.

Правила:

  • JSON парсится;
  • `risk_level` входит в разрешенный список;
  • `explanation` не длиннее 500 символов;
  • модель не добавила новые факты: “конкуренты”, “погода”, “новый рынок”, если их нет в events;
  • нет автоматического решения “срочно заказать”.

Если проверка не прошла:

review_status = needs_review
validation_error = invalid_llm_explanation

Проверка: объяснение помогает, но не управляет расчетом.

Шаг 23. Запишите результат в forecast_output

Для каждой строки прогноза запишите:

forecast_id
sku
product_name
category
period_start
period_end
forecast_quantity
baseline_quantity
last_4_weeks_avg
trend
current_stock
recommended_order_qty
risk_level
confidence
explanation
review_status
created_at

Статус:

draft - если данных достаточно
needs_review - если мало истории, stockout или сильное отклонение

Проверка: менеджер видит прогноз, основание и статус.

Шаг 24. Проверьте прогноз человеком

Менеджер открывает `forecast_output`.

Проверяет:

  • не было ли разовой крупной сделки;
  • не было ли stockout;
  • не было ли промо;
  • не менялась ли цена;
  • не планируется ли запуск или остановка канала продаж;
  • адекватен ли recommended_order_qty.

После проверки ставит:

review_status: approved
approved_by: имя
approved_at: дата

Или:

review_status: rejected
review_comment: причина

Проверка: без `approved` агент не создает задачу на закупку.

Шаг 25. Создайте workflow для approved-действий

Назовите workflow:

Demand forecast actions approved

Он делает:

  1. читает `forecast_output`;
  2. берет только `review_status = approved`;
  3. создает строку в `action_queue`;
  4. отправляет задачу ответственному менеджеру;
  5. меняет статус на `done`.

Пример задачи:

SKU-1001: прогноз 28 шт. на неделю 25-31 мая.
Остаток 15 шт., min_stock 5, рекомендуемый заказ 18 шт.
Причина: спрос выше среднего на 22%, промо не запланировано.

Проверка: задача внутренняя, поставщику заказ не отправляется автоматически.

Шаг 26. Сделайте backtest

В листе `backtest` храните проверку качества.

Колонки:

run_id
sku
period_start
period_end
forecast_quantity
actual_quantity
absolute_error
ape
wape_group
created_at

Формулы:

absolute_error = abs(actual_quantity - forecast_quantity)
ape = absolute_error / actual_quantity

Для группы SKU считайте WAPE:

WAPE = сумма absolute_error / сумма actual_quantity

Если WAPE выше `high_risk_wape`, прогнозы по этой категории отправляйте в `needs_review`.

Проверка: вы видите не только прогноз, но и насколько он был точным после факта.

Минимальная проверка результата

Прототип работает, если выполняются все пункты:

  • товары читаются из `products`;
  • продажи читаются из `sales_history`;
  • остатки читаются из `stock`;
  • события читаются из `events`;
  • продажи агрегируются по неделям;
  • stockout-недели не занижают прогноз;
  • прогноз считается кодом, а не LLM;
  • объяснение формируется LLM по готовым цифрам;
  • результат пишется в `forecast_output`;
  • без `approved` задача не создается;
  • backtest считает ошибку прогноза.

Что нельзя автоматизировать в первой версии

  • автоматический заказ поставщику;
  • изменение цен;
  • запуск рекламы;
  • списание товара;
  • прогноз по товарам без истории;
  • закупку по прогнозу без проверки менеджером;
  • смешивание разных валют и каналов без нормализации;
  • принятие решений по сезонным товарам без событийного календаря.

Частые вопросы

Можно ли сразу использовать сложную ML-модель?

Можно, но для первой версии лучше начать с простого baseline. Если простой прогноз уже дает пользу и понятные ошибки, потом можно подключать более сложные модели.

Почему LLM не должен сам считать прогноз?

Потому что прогноз должен быть воспроизводимым. Арифметику считает код, а LLM объясняет результат понятным языком и помогает сформулировать действие.

Что делать с товарами без истории?

Ставить `needs_review`. Для новых товаров используйте аналоги, план запуска, промо и экспертную оценку, но не выдавайте прогноз как автоматический расчет.

Как учитывать дни без товара?

Если товара не было на складе, продажи ниже не потому, что спрос упал. Такие недели нужно исключать из среднего или помечать прогноз как рискованный.

Какой минимум нужен для запуска?

Листы `products`, `sales_history`, `stock`, `events`, `forecast_output`, n8n workflow, простой baseline-прогноз, LLM-объяснение, approval менеджера и backtest качества.

Дальше по теме

Похожие материалы