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

Как сделать ИИ-агента для склада и инвентаризации

Пошаговая инструкция от нуля до складского ИИ-агента: SKU, ячейки, остатки, резервы, stockout, cycle count, approval, задачи и отчеты.

AI-агенты склад инвентаризация inventory SKU stockout cycle count WMS

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

Соберем ИИ-агента для склада, который каждый день читает товары, ячейки, остатки, резервы, движения, заказы, закупки и результаты пересчета, затем находит stockout, overstock, пересорт, расхождения между системами, товары для cycle count и задачи для склада.

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

  1. настройки хранятся в `settings`;
  2. товары и SKU хранятся в `sku_master`;
  3. склады и ячейки хранятся в `warehouse_locations`;
  4. снимок остатков хранится в `inventory_snapshot`;
  5. резервы под заказы хранятся в `reservation_snapshot`;
  6. движения товара хранятся в `stock_movements`;
  7. закупки и ожидаемые поставки хранятся в `incoming_stock`;
  8. правила пополнения хранятся в `reorder_rules`;
  9. расчет доступного остатка пишется в `available_stock`;
  10. риски stockout пишутся в `stockout_alerts`;
  11. излишки пишутся в `overstock_alerts`;
  12. расхождения между системами пишутся в `discrepancy_log`;
  13. задания на пересчет пишутся в `cycle_count_tasks`;
  14. результаты пересчета пишутся в `cycle_count_results`;
  15. черновики корректировок пишутся в `adjustment_drafts`;
  16. рискованные действия уходят в `approval_queue`;
  17. одобренные действия попадают в `execution_queue`;
  18. задачи складу, закупкам и продажам пишутся в `task_queue`;
  19. ежедневная сводка пишется в `daily_warehouse_report`;
  20. все действия пишутся в `audit_log`;
  21. ошибки интеграции пишутся в `error_log`.

В первой версии агент не меняет остатки, не списывает товар, не переносит между ячейками, не создает реальные корректировки и не закрывает инвентаризацию. Он читает данные, считает риски, готовит задачи и отправляет спорные действия на approval.

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

  • n8n Cloud или self-hosted n8n.
  • Google Sheets для MVP-таблиц.
  • ERP, WMS, CMS магазина или выгрузка CSV: Odoo, Zoho Inventory, Shopify, 1С, МойСклад, Битрикс24, RetailCRM.
  • Read-only API-ключ к системе остатков.
  • Список складов, зон и ячеек.
  • Справочник SKU.
  • История движений минимум за 30 дней.
  • Список открытых заказов и резервов.
  • Список ожидаемых поставок.
  • Канал approval: Telegram, Slack, email или задача.
  • API-ключ LLM-провайдера.
  • Ответственный сотрудник склада, который подтверждает пересчет и корректировки.

Шаг 1. Выберите первый складской сценарий

Не запускайте агента сразу на весь склад.

Для MVP выберите один сценарий:

  1. найти SKU ниже reorder point;
  2. найти товары с риском stockout;
  3. найти товары с излишками;
  4. найти расхождения между магазином и складом;
  5. подготовить задания на cycle count;
  6. найти заказы без резерва;
  7. подготовить ежедневный складской отчет.

Самый безопасный старт: `каждое утро проверить остатки, резервы и incoming stock, затем создать задачи по рисковым SKU`.

Проверка: сценарий можно вручную проверить на 10 SKU.

Шаг 2. Запретите опасные действия

В первой версии запретите агенту:

  • менять физический остаток;
  • создавать stock adjustment в ERP;
  • списывать товар;
  • перемещать товар между ячейками;
  • менять серию или партию;
  • менять срок годности;
  • закрывать инвентаризацию;
  • менять резерв под заказ;
  • отменять заказ;
  • менять reorder point без согласования;
  • массово обновлять SKU;
  • удалять товарную карточку.

Разрешите агенту:

  • читать данные;
  • считать доступный остаток;
  • искать риски;
  • создавать задания на пересчет;
  • готовить черновик корректировки;
  • отправлять approval;
  • вести лог.

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

Шаг 3. Создайте Google Sheet проекта

Создайте таблицу:

Warehouse inventory agent

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

settings
sku_master
warehouse_locations
inventory_snapshot
reservation_snapshot
stock_movements
incoming_stock
reorder_rules
available_stock
stockout_alerts
overstock_alerts
discrepancy_log
cycle_count_tasks
cycle_count_results
adjustment_drafts
approval_queue
execution_queue
task_queue
daily_warehouse_report
audit_log
error_log

Проверка: n8n может читать и писать во все листы.

Шаг 4. Заполните settings

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

key
value
description
updated_at

Заполните минимум:

planning_horizon_days | 14 | горизонт прогноза stockout
stockout_days_threshold | 7 | критический запас в днях
overstock_days_threshold | 90 | излишек в днях
inventory_accuracy_target | 98 | целевая точность учета
cycle_count_daily_limit | 30 | максимум пересчетов в день
approval_required | true | корректировки только через approval
auto_execute | false | автоматическое применение выключено
max_adjustment_qty | 5 | лимит черновика корректировки

Проверка: `approval_required = true`, `auto_execute = false`.

Шаг 5. Заполните sku_master

В `sku_master` добавьте колонки:

sku
product_id
barcode
name
category
unit
abc_class
is_serialized
is_batch_tracked
has_expiry_date
default_supplier
status
updated_at

Пример:

TSHIRT-BLACK-M | P-1001 | 4600000000012 | Футболка черная M | apparel | pcs | A | false | false | false | textile_supplier | active | 2026-05-23

Проверка: у каждого активного товара есть `sku`, `barcode`, `unit` и `status`.

Шаг 6. Заполните warehouse_locations

В `warehouse_locations` добавьте колонки:

location_id
warehouse_id
zone
aisle
rack
shelf
bin
location_type
capacity_units
status
updated_at

`location_type`:

storage
pick
receiving
packing
quarantine
damaged
return

Пример:

LOC-A-01-02-03 | WH-MAIN | A | 01 | 02 | 03 | BIN-03 | pick | 120 | active | 2026-05-23

Проверка: у каждого складского остатка есть `location_id`.

Шаг 7. Заполните inventory_snapshot

В `inventory_snapshot` добавьте колонки:

snapshot_at
source_system
warehouse_id
location_id
sku
barcode
batch_no
serial_no
expiry_date
on_hand_qty
damaged_qty
quarantine_qty
unit
updated_at

Пример:

2026-05-23 08:00 | odoo | WH-MAIN | LOC-A-01-02-03 | TSHIRT-BLACK-M | 4600000000012 | - | - | - | 120 | 0 | 0 | pcs | 2026-05-23

Проверка: `on_hand_qty` не пустой, а отрицательные остатки попадают в `error_log`.

Шаг 8. Заполните reservation_snapshot

В `reservation_snapshot` добавьте колонки:

snapshot_at
order_id
source_system
warehouse_id
sku
reserved_qty
reservation_status
promised_ship_date
updated_at

Статусы:

reserved
partially_reserved
not_reserved
released
cancelled

Пример:

2026-05-23 08:00 | SO-2281 | shopify | WH-MAIN | TSHIRT-BLACK-M | 8 | reserved | 2026-05-24 | 2026-05-23

Проверка: агент видит заказы, которые забирают товар из доступного остатка.

Шаг 9. Заполните stock_movements

В `stock_movements` добавьте колонки:

movement_id
movement_at
source_system
warehouse_id
from_location_id
to_location_id
sku
qty
movement_type
document_id
operator
created_at

`movement_type`:

receipt
shipment
transfer
adjustment
return
write_off
cycle_count
reservation
release

Проверка: за последние 30 дней есть движения по товарам класса A и B.

Шаг 10. Заполните incoming_stock

В `incoming_stock` добавьте колонки:

incoming_id
source_system
purchase_order_id
supplier
warehouse_id
sku
ordered_qty
received_qty
expected_qty
expected_date
status
updated_at

Статусы:

ordered
confirmed
in_transit
partially_received
received
delayed
cancelled

Пример:

IN-775 | odoo | PO-775 | textile_supplier | WH-MAIN | TSHIRT-BLACK-M | 300 | 0 | 300 | 2026-05-30 | confirmed | 2026-05-23

Проверка: будущие поставки видны агенту при расчете stockout.

Шаг 11. Заполните reorder_rules

В `reorder_rules` добавьте колонки:

sku
warehouse_id
min_qty
max_qty
safety_stock_qty
average_daily_demand
lead_time_days
reorder_point
reorder_qty
owner
updated_at

Формула:

reorder_point = average_daily_demand * lead_time_days + safety_stock_qty

Пример:

TSHIRT-BLACK-M | WH-MAIN | 40 | 300 | 20 | 12 | 7 | 104 | 250 | procurement | 2026-05-23

Проверка: у SKU с регулярными продажами есть `reorder_point`.

Шаг 12. Подключите источник данных в n8n

Создайте workflow:

Warehouse Inventory Agent - daily check

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

  1. `Schedule Trigger`;
  2. `Read sku_master`;
  3. `Read warehouse_locations`;
  4. `Read inventory_snapshot`;
  5. `Read reservation_snapshot`;
  6. `Read stock_movements`;
  7. `Read incoming_stock`;
  8. `Read reorder_rules`;
  9. `Calculate available_stock`;
  10. `Detect stockout`;
  11. `Detect overstock`;
  12. `Detect discrepancies`;
  13. `LLM warehouse analysis`;
  14. `Create cycle count tasks`;
  15. `Send approval`;
  16. `Write audit_log`;
  17. `Write error_log`.

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

Шаг 13. Если есть ERP или WMS, подключите read-only API

Для Odoo через External API читайте модели:

product.product
stock.quant
stock.move
stock.location
purchase.order
sale.order

Для Shopify Admin API:

GET /admin/api/2025-01/inventory_levels.json
GET /admin/api/2025-01/locations.json
GET /admin/api/2025-01/products.json

Для Zoho Inventory API:

GET /inventory/v1/items
GET /inventory/v1/warehouses
GET /inventory/v1/purchaseorders
GET /inventory/v1/salesorders

Проверка: API возвращает товары и остатки, но write-запросы не используются.

Шаг 14. Рассчитайте available_stock

Для каждого SKU и склада возьмите:

on_hand_qty из inventory_snapshot
reserved_qty из reservation_snapshot
damaged_qty из inventory_snapshot
quarantine_qty из inventory_snapshot
incoming_qty из incoming_stock

Формула:

available_qty = on_hand_qty - reserved_qty - damaged_qty - quarantine_qty

В `available_stock` добавьте колонки:

run_id
snapshot_at
warehouse_id
sku
on_hand_qty
reserved_qty
damaged_qty
quarantine_qty
available_qty
incoming_qty_14d
unit
status
calculated_at

Статусы:

ok
negative_available
missing_inventory
missing_reservation
unknown_sku

Проверка: SKU `TSHIRT-BLACK-M` получил рассчитанный `available_qty`.

Шаг 15. Найдите stockout в stockout_alerts

Условия:

available_qty <= reorder_point

или:

days_until_stockout <= stockout_days_threshold

В `stockout_alerts` добавьте колонки:

alert_id
run_id
warehouse_id
sku
available_qty
average_daily_demand
days_until_stockout
incoming_qty_14d
reorder_point
risk_level
recommended_action
owner
status
created_at

`risk_level`:

low
medium
high
critical

Пример:

SA-1001 | RUN-20260523 | WH-MAIN | TSHIRT-BLACK-M | 28 | 12 | 2.3 | 300 | 104 | high | ускорить PO-775 или ограничить продажи | procurement | open | 2026-05-23

Проверка: товар ниже `reorder_point` появляется в `stockout_alerts`.

Шаг 16. Найдите излишки в overstock_alerts

Условия:

days_of_inventory >= overstock_days_threshold

или:

available_qty > max_qty

В `overstock_alerts` добавьте колонки:

alert_id
run_id
warehouse_id
sku
available_qty
average_daily_demand
days_of_inventory
max_qty
risk_level
recommended_action
owner
status
created_at

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

Шаг 17. Найдите расхождения в discrepancy_log

Сравните остатки из разных систем:

ERP on_hand
WMS on_hand
shop available
marketplace available
Google Sheet manual count

В `discrepancy_log` добавьте колонки:

discrepancy_id
run_id
sku
warehouse_id
source_a
qty_a
source_b
qty_b
difference_qty
difference_pct
reason_guess
risk_level
status
created_at

Статусы:

open
needs_count
explained
approved_adjustment
closed

Проверка: если в магазине 10, а в WMS 7, агент пишет расхождение и не исправляет его сам.

Шаг 18. Настройте prompt для LLM warehouse analysis

В n8n добавьте узел `LLM warehouse analysis`.

System prompt:

Ты складской аналитик. Работай только с переданными данными.
Не меняй остатки, не списывай товар, не создавай перемещения и не закрывай инвентаризацию.
Если данных не хватает, верни status = needs_data.
Любое действие с физическим остатком отправляй в approval.
Ответ возвращай только JSON.

User prompt:

Проанализируй SKU и складской риск.

sku:
{{$json.sku_master}}

available_stock:
{{$json.available_stock}}

stockout_alerts:
{{$json.stockout_alerts}}

overstock_alerts:
{{$json.overstock_alerts}}

discrepancies:
{{$json.discrepancy_log}}

movements:
{{$json.stock_movements}}

Верни JSON:
{
  "sku": "...",
  "warehouse_id": "...",
  "status": "ok | stockout_risk | overstock | discrepancy | needs_count | needs_data",
  "risk_level": "low | medium | high | critical",
  "summary": "...",
  "evidence": ["..."],
  "recommended_actions": [
    {
      "action_type": "create_cycle_count | create_procurement_task | create_sales_task | draft_adjustment | ask_warehouse",
      "owner": "warehouse | procurement | sales | operations",
      "text": "...",
      "requires_approval": true
    }
  ]
}

Проверка: LLM возвращает валидный JSON и не предлагает списание без approval.

Шаг 19. Создайте cycle_count_tasks

В `cycle_count_tasks` добавьте колонки:

task_id
run_id
warehouse_id
location_id
sku
barcode
expected_qty
reason
priority
assigned_to
status
created_at
due_at

Причины:

stockout_risk
discrepancy
negative_available
high_value_sku
fast_moving_sku
recent_adjustment
no_recent_count

Статусы:

open
in_progress
counted
needs_review
closed
cancelled

Проверка: агент создает не больше `cycle_count_daily_limit` задач в день.

Шаг 20. Запишите cycle_count_results

После пересчета сотрудник склада заполняет `cycle_count_results`.

Колонки:

result_id
task_id
warehouse_id
location_id
sku
expected_qty
counted_qty
difference_qty
counted_by
counted_at
comment
status

Статусы:

matched
mismatch
needs_recount
approved
rejected

Проверка: если `difference_qty != 0`, агент создает черновик корректировки, а не меняет остаток.

Шаг 21. Создайте adjustment_drafts

В `adjustment_drafts` добавьте колонки:

draft_id
source_task_id
warehouse_id
location_id
sku
expected_qty
counted_qty
adjustment_qty
reason
evidence_json
risk_level
approval_required
status
created_at

Статусы:

draft
sent_to_approval
approved
rejected
manual_only

Проверка: черновик корректировки содержит evidence: задача пересчета, ожидаемое количество, фактическое количество и комментарий сотрудника.

Шаг 22. Настройте approval_queue

В `approval_queue` добавьте колонки:

approval_id
source
source_id
warehouse_id
sku
action_type
action_text
payload_json
risk_level
requested_by
approver
status
requested_at
approved_at
decision_comment

Статусы:

pending
approved
rejected
needs_recount
expired

В approval отправляйте:

  1. корректировку остатка;
  2. списание;
  3. перемещение между ячейками;
  4. изменение reorder point;
  5. снятие резерва;
  6. закрытие результата инвентаризации;
  7. массовые изменения SKU.

Проверка: без статуса `approved` действие не попадает в `execution_queue`.

Шаг 23. Сделайте Telegram approval

В n8n добавьте узел `Telegram`.

Сообщение:

SKU: TSHIRT-BLACK-M
Склад: WH-MAIN / LOC-A-01-02-03

Ожидалось: 120 pcs
Посчитали: 116 pcs
Разница: -4 pcs

Действие: создать черновик корректировки -4 pcs.

Approve: /approve ADJ-9001
Recount: /recount ADJ-9001
Reject: /reject ADJ-9001

После `/approve ADJ-9001` workflow должен:

  1. найти строку в `approval_queue`;
  2. проверить статус `pending`;
  3. записать `approved`;
  4. заполнить `approved_at`;
  5. передать действие в `execution_queue`;
  6. записать событие в `audit_log`.

Проверка: `/recount` создает новую задачу пересчета, а не корректировку.

Шаг 24. Настройте execution_queue

В `execution_queue` добавьте колонки:

execution_id
approval_id
target_system
warehouse_id
sku
action_type
payload_json
status
executed_at
result_json
error_message

Статусы:

queued
manual_only
executed
failed
skipped

Для MVP используйте `manual_only`: агент готовит действие, а сотрудник склада выполняет его в ERP или WMS.

Проверка: пока write-доступ не включен, все корректировки остаются `manual_only`.

Шаг 25. Создайте task_queue

В `task_queue` добавьте колонки:

task_id
source
source_id
warehouse_id
location_id
sku
task_type
title
description
owner_team
assignee
priority
status
created_at
due_at
closed_at

`task_type`:

cycle_count
procurement_follow_up
warehouse_check
sales_warning
data_fix
reorder_rule_review

Пример:

TASK-552 | stockout_alerts | SA-1001 | WH-MAIN | LOC-A-01-02-03 | TSHIRT-BLACK-M | procurement_follow_up | Проверить поставку PO-775 | SKU уйдет в stockout через 2.3 дня | procurement | buyer_1 | high | open | 2026-05-23 | 2026-05-24 | -

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

Шаг 26. Настройте daily_warehouse_report

В `daily_warehouse_report` добавьте колонки:

report_date
total_sku
stockout_risk_count
critical_stockout_count
overstock_count
discrepancy_count
cycle_count_open
cycle_count_done
adjustments_pending
tasks_created
summary
created_at

Пример summary:

Сегодня 12 SKU ниже reorder point, 3 критических stockout, 5 расхождений между WMS и магазином, 18 задач cycle count, 4 черновика корректировки ждут approval.

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

Шаг 27. Настройте audit_log

В `audit_log` добавьте колонки:

event_id
run_id
event_type
sku
warehouse_id
actor
input_hash
output_hash
summary
created_at

Пишите события:

run_started
data_loaded
available_stock_calculated
stockout_found
overstock_found
discrepancy_found
cycle_count_created
adjustment_drafted
approval_requested
approval_approved
task_created
run_finished

Проверка: по `run_id` можно объяснить, почему агент создал задачу или черновик.

Шаг 28. Настройте error_log

В `error_log` добавьте колонки:

error_id
run_id
step
source_system
warehouse_id
sku
error_type
error_message
payload_sample
status
created_at
resolved_at

`error_type`:

api_error
unknown_sku
unknown_location
negative_stock
missing_reservation
invalid_json
approval_error
write_error

Проверка: при неизвестной ячейке агент пишет `unknown_location`, а не подставляет склад по умолчанию.

Шаг 29. Протестируйте на одном SKU

Создайте тестовые данные:

sku_master:
TSHIRT-BLACK-M | P-1001 | 4600000000012 | Футболка черная M | apparel | pcs | A | false | false | false | textile_supplier | active | 2026-05-23

inventory_snapshot:
2026-05-23 08:00 | odoo | WH-MAIN | LOC-A-01-02-03 | TSHIRT-BLACK-M | 4600000000012 | - | - | - | 40 | 0 | 0 | pcs | 2026-05-23

reservation_snapshot:
2026-05-23 08:00 | SO-2281 | shopify | WH-MAIN | TSHIRT-BLACK-M | 12 | reserved | 2026-05-24 | 2026-05-23

reorder_rules:
TSHIRT-BLACK-M | WH-MAIN | 40 | 300 | 20 | 12 | 7 | 104 | 250 | procurement | 2026-05-23

Ожидаемый расчет:

available_qty = 40 - 12 = 28
days_until_stockout = 28 / 12 = 2.3

Ожидаемый результат:

  1. в `available_stock` появилась строка `available_qty = 28`;
  2. в `stockout_alerts` появился риск;
  3. в `task_queue` появилась задача закупкам;
  4. в `daily_warehouse_report` обновился счетчик stockout;
  5. в `audit_log` появился запуск;
  6. в `error_log` нет ошибки.

Проверка: агент не создал stock adjustment и не изменил остаток.

Шаг 30. Проверьте негативные сценарии

Сделайте 5 тестов:

  1. удалите SKU из `sku_master`;
  2. удалите ячейку из `warehouse_locations`;
  3. поставьте `on_hand_qty = -5`;
  4. сделайте расхождение между WMS и магазином;
  5. верните от LLM невалидный JSON.

Ожидаемый результат:

  1. неизвестный SKU попадает в `error_log` как `unknown_sku`;
  2. неизвестная ячейка попадает как `unknown_location`;
  3. отрицательный остаток попадает как `negative_stock`;
  4. расхождение попадает в `discrepancy_log`;
  5. невалидный JSON попадает как `invalid_json`;
  6. без approval ничего не попадает в `execution_queue`.

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

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

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

  1. `sku_master` содержит минимум 10 SKU;
  2. `warehouse_locations` содержит реальные ячейки;
  3. `inventory_snapshot` содержит физический остаток;
  4. `reservation_snapshot` содержит резервы;
  5. `available_stock` показывает доступный остаток;
  6. `stockout_alerts` ловит SKU ниже reorder point;
  7. `overstock_alerts` ловит излишки;
  8. `discrepancy_log` ловит расхождения систем;
  9. `cycle_count_tasks` создает задания на пересчет;
  10. `adjustment_drafts` создает только черновики;
  11. `approval_queue` блокирует рискованные действия;
  12. без `approved` нет реального исполнения;
  13. `task_queue` показывает владельца задачи;
  14. `daily_warehouse_report` отправляет сводку;
  15. `audit_log` объясняет действия;
  16. `error_log` показывает плохие данные.

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

  • списание товара;
  • изменение физического остатка;
  • перемещение между ячейками;
  • закрытие инвентаризации;
  • изменение партии или серийного номера;
  • изменение срока годности;
  • снятие резерва с заказа;
  • отмену заказа;
  • изменение reorder point;
  • массовое обновление SKU;
  • удаление товара;
  • любые действия без approval, если они меняют складской учет.

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

Можно ли начать без WMS?

Да. Для MVP хватит Google Sheets, выгрузки из магазина или ERP и ручного листа ячеек. Но если есть партии, серийные номера, адресное хранение и много движений, лучше подключать WMS или ERP как основной источник.

Может ли агент сам корректировать остатки?

В первой версии нет. Он может создать `adjustment_drafts` и отправить approval, но корректировку должен подтвердить ответственный сотрудник склада.

Что важнее контролировать первым?

Начните с stockout, товаров ниже reorder point, расхождений между системами и SKU класса A. Эти ошибки быстрее всего влияют на продажи и операционные проблемы.

Как проверить, что агент не путает доступный и физический остаток?

Разделите `on_hand_qty`, `reserved_qty`, `damaged_qty`, `quarantine_qty` и `available_qty`. В каждом alert агент должен показывать, какую цифру использовал.

Чем складской агент отличается от агента для логистики?

Складской агент работает с остатками, ячейками, резервами, пересчетом и корректировками внутри склада. Логистический агент работает с отправлениями после отгрузки: перевозчики, трекинг, задержки и доставка клиенту.

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

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