Что получится в результате
Соберем ИИ-агента для производства, который каждый день читает производственные заказы, BOM, остатки материалов, рабочие центры, закупки и сроки, затем показывает, какие заказы можно запускать, где не хватает материалов, где перегружен цех и какие действия нужно согласовать с планировщиком.
Первая рабочая версия будет делать так:
- настройки хранятся в `settings`;
- изделия и SKU хранятся в `product_catalog`;
- производственные заказы хранятся в `production_orders`;
- спецификации материалов хранятся в `bom_items`;
- операции и маршруты хранятся в `routing_steps`;
- рабочие центры хранятся в `work_centers`;
- календарь смен хранится в `shift_calendar`;
- остатки материалов хранятся в `inventory_snapshot`;
- закупки и поставки хранятся в `purchase_pipeline`;
- потребность по материалам пишется в `material_requirements`;
- дефициты пишутся в `shortage_alerts`;
- проверка мощности пишется в `capacity_checks`;
- риски сроков пишутся в `delivery_risk_log`;
- рекомендации по плану пишутся в `planning_recommendations`;
- спорные действия уходят в `approval_queue`;
- одобренные действия попадают в `execution_queue`;
- задачи закупкам, складу и мастеру пишутся в `task_queue`;
- ежедневная сводка пишется в `daily_production_report`;
- все решения пишутся в `audit_log`;
- ошибки интеграции пишутся в `error_log`.
В первой версии агент не запускает заказы, не списывает материалы, не меняет BOM, не двигает смены и не меняет производственный план автоматически. Он считает, проверяет, предлагает и отправляет на approval.
Что понадобится
- n8n Cloud или self-hosted n8n.
- Google Sheets для MVP-таблиц.
- ERP, MRP или выгрузка из учетной системы: Odoo, Katana, MRPeasy, 1С, МойСклад или CSV.
- API-ключ или read-only выгрузка производственных заказов.
- BOM по изделиям: материал, количество, единица, версия.
- Остатки материалов по складам.
- Данные по закупкам: поставщик, ожидаемая дата, количество, статус.
- Список рабочих центров: станок, участок, линия, смена, мощность.
- Канал approval: Telegram, Slack, email или задача в CRM.
- API-ключ LLM-провайдера.
- Ответственный планировщик, который будет подтверждать действия.
Шаг 1. Выберите один производственный сценарий
Не начинайте с полного автопланирования производства.
Для MVP выберите один сценарий:
- проверить, можно ли запустить производственные заказы на завтра;
- найти дефицит материалов по открытым заказам;
- найти перегрузку рабочих центров на неделю;
- подготовить список закупок по дефицитам;
- найти заказы с риском просрочки;
- собрать ежедневную сводку планировщику.
Самый безопасный сценарий для старта: `каждое утро проверить открытые производственные заказы и показать, какие нельзя запускать из-за материалов, мощности или сроков`.
Проверка: сценарий можно объяснить одной фразой и вручную проверить на 3 заказах.
Шаг 2. Запретите опасные действия
В первой версии запретите агенту:
- запускать производственный заказ;
- закрывать производственный заказ;
- списывать материалы;
- перемещать материалы между складами;
- менять BOM;
- менять маршрут операций;
- менять норму времени;
- менять смены;
- менять приоритет заказа;
- отправлять заказ в производство без approval;
- отменять закупку;
- обещать клиенту новую дату отгрузки.
Разрешите агенту:
- читать данные;
- считать потребность;
- искать дефициты;
- искать перегрузку;
- готовить рекомендации;
- создавать задачи;
- отправлять approval;
- вести лог.
Проверка: API-ключ первого запуска имеет только чтение, а все write-действия проходят через `approval_queue`.
Шаг 3. Создайте Google Sheet проекта
Создайте таблицу:
Production planning agent
Добавьте листы:
settings
product_catalog
production_orders
bom_items
routing_steps
work_centers
shift_calendar
inventory_snapshot
purchase_pipeline
material_requirements
shortage_alerts
capacity_checks
delivery_risk_log
planning_recommendations
approval_queue
execution_queue
task_queue
daily_production_report
audit_log
error_log
Проверка: n8n может читать и писать во все листы.
Шаг 4. Заполните settings
В `settings` добавьте колонки:
key
value
description
updated_at
Заполните минимум:
planning_horizon_days | 14 | горизонт проверки заказов
min_material_buffer_pct | 5 | минимальный буфер материала
capacity_warning_pct | 90 | предупреждение по загрузке центра
capacity_block_pct | 110 | критическая перегрузка центра
approval_required | true | любые изменения только через approval
default_currency | RUB | валюта расчета
workday_hours | 8 | длительность смены по умолчанию
weekend_production | false | производство по выходным выключено
auto_execute | false | автоматическое применение выключено
Проверка: `approval_required` и `auto_execute` не позволяют агенту менять план без человека.
Шаг 5. Заполните product_catalog
В `product_catalog` добавьте колонки:
product_id
sku
name
product_type
unit
lead_time_days
default_bom_version
status
owner
updated_at
Пример:
P-1001 | STOOL-OAK-01 | Табурет дубовый | finished_good | pcs | 5 | v3 | active | planning | 2026-05-23
M-2201 | OAK-BOARD-20 | Доска дубовая 20 мм | raw_material | m2 | 10 | - | active | procurement | 2026-05-23
Проверка: у каждого изделия есть `product_id`, SKU и актуальная версия BOM.
Шаг 6. Заполните production_orders
В `production_orders` добавьте колонки:
production_order_id
source_system
external_id
product_id
sku
quantity
unit
due_date
priority
status
customer_order_id
planned_start_date
planned_finish_date
owner
updated_at
Статусы:
draft
planned
ready_check
blocked_materials
blocked_capacity
ready_to_start
in_progress
done
cancelled
Пример:
MO-00045 | odoo | 8451 | P-1001 | STOOL-OAK-01 | 120 | pcs | 2026-06-05 | high | planned | SO-219 | 2026-05-27 | 2026-06-04 | planner | 2026-05-23
Проверка: есть хотя бы 3 заказа со статусом `planned`.
Шаг 7. Заполните bom_items
В `bom_items` добавьте колонки:
bom_id
product_id
bom_version
component_id
component_sku
component_name
quantity_per_unit
unit
scrap_pct
is_alternative
alternative_group
status
updated_at
Пример:
BOM-STOOL-V3 | P-1001 | v3 | M-2201 | OAK-BOARD-20 | Доска дубовая 20 мм | 0.42 | m2 | 3 | false | wood | active | 2026-05-23
BOM-STOOL-V3 | P-1001 | v3 | M-3302 | SCREW-40 | Саморез 40 мм | 12 | pcs | 1 | false | fastener | active | 2026-05-23
Проверка: для каждого `product_id` из производственного заказа есть активная BOM.
Шаг 8. Заполните routing_steps
В `routing_steps` добавьте колонки:
route_id
product_id
bom_version
operation_no
operation_name
work_center_id
setup_minutes
run_minutes_per_unit
queue_minutes
quality_check_required
status
updated_at
Пример:
R-STOOL-V3 | P-1001 | v3 | 10 | Раскрой | WC-CUT-01 | 30 | 2.5 | 60 | true | active | 2026-05-23
R-STOOL-V3 | P-1001 | v3 | 20 | Шлифовка | WC-SAND-01 | 20 | 3.0 | 30 | true | active | 2026-05-23
Проверка: у каждого изделия есть хотя бы одна операция и рабочий центр.
Шаг 9. Заполните work_centers
В `work_centers` добавьте колонки:
work_center_id
name
department
capacity_hours_per_shift
shifts_per_day
calendar_id
status
owner
updated_at
Пример:
WC-CUT-01 | Раскройный участок | woodshop | 7.2 | 1 | CAL-WOODSHOP | active | master_cut | 2026-05-23
WC-SAND-01 | Шлифовка | woodshop | 6.5 | 1 | CAL-WOODSHOP | active | master_finish | 2026-05-23
Проверка: у каждого `work_center_id` есть мощность в часах.
Шаг 10. Заполните shift_calendar
В `shift_calendar` добавьте колонки:
calendar_id
date
is_workday
shift_no
start_time
end_time
available_hours
comment
updated_at
Пример:
CAL-WOODSHOP | 2026-05-27 | true | 1 | 09:00 | 18:00 | 7.2 | обычная смена | 2026-05-23
CAL-WOODSHOP | 2026-05-31 | false | 0 | - | - | 0 | выходной | 2026-05-23
Проверка: на ближайшие 14 дней есть календарь по каждому участку.
Шаг 11. Заполните inventory_snapshot
В `inventory_snapshot` добавьте колонки:
snapshot_at
warehouse_id
component_id
component_sku
on_hand_qty
reserved_qty
available_qty
unit
source_system
updated_at
Формула:
available_qty = on_hand_qty - reserved_qty
Пример:
2026-05-23 08:00 | WH-RAW | M-2201 | OAK-BOARD-20 | 92 | 18 | 74 | m2 | odoo | 2026-05-23
Проверка: `available_qty` не пустой для каждого материала из BOM.
Шаг 12. Заполните purchase_pipeline
В `purchase_pipeline` добавьте колонки:
purchase_id
component_id
component_sku
supplier
ordered_qty
received_qty
expected_date
status
owner
updated_at
Статусы:
draft
ordered
confirmed
in_transit
partially_received
received
delayed
cancelled
Пример:
PO-883 | M-2201 | OAK-BOARD-20 | ЛесПоставка | 120 | 0 | 2026-05-29 | confirmed | procurement | 2026-05-23
Проверка: будущие поставки материалов видны агенту.
Шаг 13. Подключите источник данных в n8n
Создайте workflow:
Production Planning Agent - daily check
Добавьте узлы:
- `Schedule Trigger`;
- `Read production_orders`;
- `Read bom_items`;
- `Read routing_steps`;
- `Read work_centers`;
- `Read shift_calendar`;
- `Read inventory_snapshot`;
- `Read purchase_pipeline`;
- `Calculate material_requirements`;
- `Check shortages`;
- `Check capacity`;
- `LLM planning analysis`;
- `Write recommendations`;
- `Send approval`;
- `Write audit_log`;
- `Write error_log`.
Для Google Sheets используйте OAuth Service Account или обычный OAuth-аккаунт, который имеет доступ к таблице.
Проверка: запуск workflow читает все листы без ошибки `403` или `404`.
Шаг 14. Если есть ERP, подключите ее read-only
Если данные лежат в ERP, в n8n добавьте `HTTP Request`.
Для Odoo:
POST /jsonrpc
Поля для чтения:
mrp.production
mrp.bom
mrp.routing.workcenter
stock.quant
purchase.order
Для Katana:
GET /v1/manufacturing_orders
GET /v1/materials
GET /v1/inventory
GET /v1/purchase_orders
Для MRPeasy:
GET manufacturing-orders
GET boms
GET stock
GET purchase-orders
Проверка: агент получает заказы, BOM и остатки, но не отправляет write-запросы.
Шаг 15. Рассчитайте material_requirements
Для каждого заказа возьмите:
quantity из production_orders
quantity_per_unit из bom_items
scrap_pct из bom_items
Формула:
required_qty = order_quantity * quantity_per_unit * (1 + scrap_pct / 100)
В `material_requirements` добавьте колонки:
run_id
production_order_id
product_id
component_id
component_sku
required_qty
available_qty
incoming_qty_before_due
shortage_qty
unit
due_date
status
calculated_at
Статусы:
ok
shortage
incoming_ok
incoming_late
unknown_bom
unknown_stock
Проверка: для заказа `MO-00045` агент создал строки по каждому материалу из BOM.
Шаг 16. Найдите дефициты в shortage_alerts
Условие:
shortage_qty > 0
или:
incoming_qty_before_due < shortage_qty
В `shortage_alerts` добавьте колонки:
alert_id
production_order_id
component_id
component_sku
required_qty
available_qty
incoming_qty_before_due
shortage_qty
first_expected_date
risk_level
recommended_action
owner
status
created_at
`risk_level`:
low
medium
high
critical
Пример `recommended_action`:
Ускорить PO-883 или перенести запуск MO-00045 на 2026-05-30.
Проверка: заказ с нехваткой материала получает статус `blocked_materials`.
Шаг 17. Рассчитайте загрузку в capacity_checks
Для каждой операции посчитайте:
required_hours = (setup_minutes + run_minutes_per_unit * quantity + queue_minutes) / 60
Сравните с доступными часами по `shift_calendar`.
В `capacity_checks` добавьте колонки:
check_id
date
work_center_id
production_order_id
operation_no
required_hours
available_hours
load_pct
risk_level
status
calculated_at
Статусы:
ok
warning
overloaded
no_calendar
no_route
Проверка: если `load_pct` выше 110, агент пишет `overloaded`.
Шаг 18. Найдите риск просрочки в delivery_risk_log
Создайте правило:
если materials_status != ok или capacity_status = overloaded или planned_finish_date > due_date, то есть риск просрочки
В `delivery_risk_log` добавьте колонки:
risk_id
production_order_id
due_date
planned_finish_date
materials_status
capacity_status
risk_reason
risk_level
recommended_new_date
owner
status
created_at
Пример:
RISK-1007 | MO-00045 | 2026-06-05 | 2026-06-07 | shortage | overloaded | Нет доски и перегрузка раскроя | high | 2026-06-08 | planner | open | 2026-05-23
Проверка: агент объясняет причину риска не одной фразой, а через материалы, мощность и дату.
Шаг 19. Настройте prompt для LLM planning analysis
В n8n добавьте узел `LLM planning analysis`.
System prompt:
Ты производственный планировщик. Работай только с переданными данными.
Не запускай заказы, не списывай материалы, не меняй BOM, не обещай сроки клиенту.
Если данных не хватает, верни status = needs_data.
Любое действие, которое меняет производственный план, отправляй в approval.
Ответ возвращай только JSON.
User prompt:
Проанализируй производственный заказ.
production_order:
{{$json.production_order}}
materials:
{{$json.material_requirements}}
shortages:
{{$json.shortage_alerts}}
capacity:
{{$json.capacity_checks}}
purchases:
{{$json.purchase_pipeline}}
Верни JSON:
{
"production_order_id": "...",
"status": "ready_to_start | blocked_materials | blocked_capacity | delivery_risk | needs_data",
"risk_level": "low | medium | high | critical",
"summary": "...",
"evidence": ["..."],
"recommended_actions": [
{
"action_type": "create_task | request_purchase | move_start_date | split_order | ask_planner",
"owner": "planning | procurement | warehouse | shop_floor",
"text": "...",
"requires_approval": true
}
]
}
Проверка: ответ LLM валидный JSON и не содержит действия без `requires_approval`.
Шаг 20. Запишите planning_recommendations
В `planning_recommendations` добавьте колонки:
recommendation_id
production_order_id
status
risk_level
summary
evidence_json
recommended_actions_json
owner
approval_required
created_at
Пример:
REC-540 | MO-00045 | blocked_materials | high | Не хватает доски OAK-BOARD-20 | ["shortage 26 m2", "PO-883 ожидается 2026-05-29"] | [{"action_type":"request_purchase","owner":"procurement","text":"Ускорить PO-883"}] | planner | true | 2026-05-23
Проверка: каждая рекомендация содержит evidence, а не только общий совет.
Шаг 21. Настройте approval_queue
В `approval_queue` добавьте колонки:
approval_id
source
production_order_id
action_type
action_text
payload_json
risk_level
requested_by
approver
status
requested_at
approved_at
decision_comment
Статусы:
pending
approved
rejected
needs_changes
expired
В approval отправляйте:
- перенос даты запуска;
- изменение приоритета;
- создание закупки;
- разделение производственного заказа;
- изменение количества;
- отправку сообщения клиенту;
- любые write-запросы в ERP.
Проверка: без строки `approved` в `approval_queue` в `execution_queue` ничего не попадает.
Шаг 22. Сделайте Telegram approval
В n8n добавьте узел `Telegram`.
Сообщение:
MO-00045: риск HIGH
Проблема: не хватает OAK-BOARD-20, перегрузка WC-CUT-01.
Действие: перенести старт на 2026-05-30 и создать задачу закупкам.
Approve: /approve REC-540
Reject: /reject REC-540
После команды `/approve REC-540` workflow должен:
- найти `approval_id`;
- проверить, что статус `pending`;
- записать `approved`;
- заполнить `approved_at`;
- записать комментарий;
- передать действие в `execution_queue`.
Проверка: команда `/reject` не создает запись в `execution_queue`.
Шаг 23. Настройте execution_queue
В `execution_queue` добавьте колонки:
execution_id
approval_id
production_order_id
action_type
target_system
payload_json
status
executed_at
result_json
error_message
Статусы:
queued
executed
failed
skipped
manual_only
Для MVP используйте `manual_only`: агент не делает write-запрос, а создает задачу человеку.
Проверка: все рискованные действия попадают в `manual_only`, пока вы не разрешили интеграцию на запись.
Шаг 24. Создайте task_queue
В `task_queue` добавьте колонки:
task_id
source_recommendation_id
production_order_id
task_type
title
description
owner_team
assignee
priority
due_date
status
created_at
closed_at
Типы задач:
procurement_follow_up
warehouse_stock_check
planner_review
shop_floor_check
bom_data_fix
capacity_review
customer_date_review
Пример:
TASK-778 | REC-540 | MO-00045 | procurement_follow_up | Ускорить поставку OAK-BOARD-20 | PO-883 должен прийти до 2026-05-29 | procurement | buyer_1 | high | 2026-05-24 | open | 2026-05-23 | -
Проверка: рекомендация превращается в понятную задачу с владельцем и сроком.
Шаг 25. Настройте audit_log
В `audit_log` добавьте колонки:
event_id
run_id
event_type
production_order_id
actor
input_hash
output_hash
summary
created_at
Пишите события:
run_started
data_loaded
requirements_calculated
shortage_found
capacity_checked
llm_called
recommendation_created
approval_requested
approval_approved
task_created
run_finished
Проверка: по `run_id` можно восстановить, почему агент сделал рекомендацию.
Шаг 26. Настройте error_log
В `error_log` добавьте колонки:
error_id
run_id
step
source_system
production_order_id
error_type
error_message
payload_sample
status
created_at
resolved_at
Типы ошибок:
api_error
missing_bom
missing_stock
missing_route
invalid_json
approval_error
write_error
Проверка: если нет BOM, агент не придумывает материалы, а пишет `missing_bom`.
Шаг 27. Соберите daily_production_report
В `daily_production_report` добавьте колонки:
report_date
open_orders
ready_to_start
blocked_materials
blocked_capacity
delivery_risk
critical_shortages
overloaded_centers
tasks_created
approvals_pending
summary
created_at
Пример summary:
Из 18 открытых заказов 7 готовы к запуску, 5 заблокированы материалами, 3 перегружены по рабочим центрам, 4 имеют риск просрочки. Критично: MO-00045 и MO-00052.
Проверка: отчет можно отправить планировщику каждое утро в Telegram или email.
Шаг 28. Протестируйте на одном заказе
Создайте тестовый заказ:
MO-TEST-001 | manual | TEST-001 | P-1001 | STOOL-OAK-01 | 120 | pcs | 2026-06-05 | high | planned | SO-TEST | 2026-05-27 | 2026-06-04 | planner | 2026-05-23
Создайте дефицит:
OAK-BOARD-20 required = 51.9 m2
available = 20 m2
incoming before due = 0 m2
Запустите workflow вручную.
Ожидаемый результат:
- в `material_requirements` появилась строка по `OAK-BOARD-20`;
- в `shortage_alerts` появился дефицит;
- в `delivery_risk_log` появился риск;
- в `planning_recommendations` появилась рекомендация;
- в `approval_queue` появилась заявка;
- в `task_queue` появилась задача закупкам;
- в `audit_log` записаны шаги запуска;
- в `error_log` нет ошибки.
Проверка: тест должен повторяться одинаково при втором запуске.
Шаг 29. Проверьте защиту от плохих данных
Сделайте 4 негативных теста:
- удалите BOM для `P-1001`;
- удалите остатки для `OAK-BOARD-20`;
- удалите маршрут `R-STOOL-V3`;
- верните LLM невалидный JSON.
Ожидаемый результат:
- при отсутствии BOM появляется `missing_bom`;
- при отсутствии остатков появляется `unknown_stock`;
- при отсутствии маршрута появляется `no_route`;
- при невалидном JSON появляется `invalid_json`;
- approval не создается для действий без evidence;
- execution не запускается.
Проверка: агент не заменяет неизвестные данные догадками.
Минимальная проверка результата
Прототип работает, если выполняются условия:
- `production_orders` содержит минимум 3 открытых заказа;
- для каждого заказа есть BOM в `bom_items`;
- остатки есть в `inventory_snapshot`;
- агент пишет потребность в `material_requirements`;
- дефицит попадает в `shortage_alerts`;
- перегрузка попадает в `capacity_checks`;
- риск срока попадает в `delivery_risk_log`;
- рекомендация содержит evidence;
- опасное действие попадает в `approval_queue`;
- без `approved` нет записи в `execution_queue`;
- задача создается в `task_queue`;
- запуск виден в `audit_log`;
- ошибки видны в `error_log`;
- отчет появляется в `daily_production_report`.
Что нельзя автоматизировать в первой версии
- запуск производственного заказа;
- закрытие производственного заказа;
- списание сырья и комплектующих;
- изменение BOM;
- изменение маршрута операций;
- изменение норм времени;
- массовое изменение дат;
- изменение смен и графика;
- обещание сроков клиенту;
- отмену закупки;
- перенос заказа без approval;
- любые действия, которые влияют на безопасность, качество и юридические обязательства.
Частые вопросы
Можно ли начать без ERP?
Да. Для MVP хватит Google Sheets с заказами, BOM, остатками, закупками и рабочими центрами. Но если заказов много, лучше подключить ERP или MRP хотя бы в read-only режиме.
Что важнее для агента: BOM или остатки?
Нужны оба слоя. BOM показывает потребность, а остатки показывают доступность. Если BOM устарел или остатки неверные, агент должен вернуть `needs_data`, а не строить план.
Можно ли агенту самому запускать производственный заказ?
В первой версии не стоит. Агент может показать, что заказ готов к запуску, но запуск должен подтвердить планировщик, мастер или ответственный менеджер.
Как проверить, что агент не придумывает данные?
В prompt запретите догадки, а в workflow добавьте проверки `missing_bom`, `missing_stock`, `no_route` и `invalid_json`. Если данных нет, агент должен писать ошибку или `needs_data`.
Какой минимальный результат считать успешным?
Успешный MVP: агент берет один заказ, считает материалы, находит дефицит, проверяет рабочий центр, создает рекомендацию, отправляет approval, создает задачу и пишет лог.