Что получится в результате
Соберем ИИ-агента для логистики и доставки, который читает заказы, отправления, перевозчиков, тарифы, трек-номера, checkpoints, SLA и обращения клиентов, затем находит задержки, exception-статусы, дорогие варианты доставки, риск нарушения срока и готовит задачи команде.
Первая рабочая версия будет делать так:
- настройки хранятся в `settings`;
- заказы хранятся в `orders`;
- адреса доставки хранятся в `shipping_addresses`;
- правила доставки хранятся в `shipping_rules`;
- перевозчики хранятся в `carrier_accounts`;
- отправления хранятся в `shipments`;
- трек-номера хранятся в `tracking_numbers`;
- события перевозчиков пишутся в `tracking_events`;
- тарифы и варианты доставки пишутся в `rate_quotes`;
- SLA по заказам пишется в `sla_targets`;
- риски задержки пишутся в `delivery_risk_log`;
- exception-статусы пишутся в `exception_queue`;
- черновики уведомлений пишутся в `notification_drafts`;
- черновики действий пишутся в `action_requests`;
- спорные действия уходят в `approval_queue`;
- одобренные действия попадают в `execution_queue`;
- задачи складу, поддержке и логистике пишутся в `task_queue`;
- ежедневная сводка пишется в `daily_delivery_report`;
- все решения пишутся в `audit_log`;
- ошибки API и данных пишутся в `error_log`.
В первой версии агент не покупает shipping label, не меняет адрес доставки, не отменяет отправление, не оформляет возврат, не обещает компенсацию и не пишет клиенту без approval. Он собирает факты, показывает риск и готовит действия.
Что понадобится
- n8n Cloud или self-hosted n8n.
- Google Sheets для MVP-таблиц.
- Источник заказов: Shopify, WooCommerce, Ozon, Wildberries, CRM, ERP или CSV.
- Доступ к shipping/tracking API: Shippo, EasyPost, AfterShip, СДЭК, Boxberry, Почта России, DHL, DPD или другой перевозчик.
- Read-only API-ключ на первом этапе.
- Список перевозчиков, тарифов, зон доставки и SLA.
- Данные по складу: когда заказ готов к отгрузке.
- Канал approval: Telegram, Slack, email или задача.
- Канал задач: CRM, Helpdesk, Jira, Asana, ClickUp, Telegram или Google Sheets.
- API-ключ LLM-провайдера.
- Ответственный логист или операционный менеджер.
Шаг 1. Выберите один сценарий доставки
Не начинайте с полного управления логистикой.
Для MVP выберите один сценарий:
- найти отправления с риском просрочки;
- найти exception-статусы у перевозчиков;
- сравнить обещанную дату и фактический checkpoint;
- подготовить черновики уведомлений клиентам;
- создать задачи складу по заказам без отгрузки;
- создать задачи поддержке по задержкам;
- собрать ежедневный отчет по SLA доставки.
Самый безопасный старт: `каждое утро проверить открытые отправления и создать задачи по задержкам и exception-статусам`.
Проверка: сценарий можно вручную проверить на 10 отправлениях.
Шаг 2. Запретите опасные действия
В первой версии запретите агенту:
- покупать shipping label;
- менять адрес доставки;
- менять способ доставки;
- отменять отправление;
- оформлять возврат;
- менять получателя;
- обещать компенсацию;
- обещать новую дату клиенту без фактов;
- отправлять клиенту сообщение без approval;
- менять статус заказа в CRM;
- списывать стоимость доставки;
- массово менять правила доставки.
Разрешите агенту:
- читать заказы;
- читать отправления;
- читать tracking;
- сравнивать SLA;
- готовить черновики уведомлений;
- создавать задачи;
- отправлять approval;
- вести лог.
Проверка: первый API-ключ имеет только чтение или write-действия отключены в workflow.
Шаг 3. Создайте Google Sheet проекта
Создайте таблицу:
Logistics delivery agent
Добавьте листы:
settings
orders
shipping_addresses
shipping_rules
carrier_accounts
shipments
tracking_numbers
tracking_events
rate_quotes
sla_targets
delivery_risk_log
exception_queue
notification_drafts
action_requests
approval_queue
execution_queue
task_queue
daily_delivery_report
audit_log
error_log
Проверка: n8n может читать и писать во все листы.
Шаг 4. Заполните settings
В `settings` добавьте колонки:
key
value
description
updated_at
Заполните минимум:
delivery_risk_hours | 12 | за сколько часов до SLA считать риск
stale_tracking_hours | 24 | сколько часов без checkpoint считать проблемой
notification_approval_required | true | клиентские уведомления только через approval
label_purchase_allowed | false | покупка labels выключена
address_change_allowed | false | изменение адреса выключено
auto_execute | false | автоприменение выключено
default_timezone | Europe/Moscow | часовой пояс SLA
critical_delay_hours | 48 | критическая задержка
Проверка: `auto_execute = false`, а уведомления клиентам требуют approval.
Шаг 5. Заполните orders
В `orders` добавьте колонки:
order_id
source_system
external_order_id
customer_id
customer_name
customer_email
customer_phone
order_status
paid_at
promised_ship_at
promised_delivery_at
delivery_method
warehouse_id
priority
updated_at
Статусы:
paid
ready_to_pack
packed
shipped
delivered
delayed
cancelled
returned
Пример:
ORD-1001 | shopify | 5901 | C-88 | Иван Петров | ivan@example.ru | +79990000000 | shipped | 2026-05-23 10:00 | 2026-05-24 18:00 | 2026-05-27 20:00 | courier | WH-MAIN | high | 2026-05-23
Проверка: у каждого заказа есть обещанная дата доставки или правило, по которому она считается.
Шаг 6. Заполните shipping_addresses
В `shipping_addresses` добавьте колонки:
address_id
order_id
country
region
city
postal_code
street
building
apartment
recipient_name
recipient_phone
address_quality
needs_review
updated_at
`address_quality`:
valid
missing_postal_code
missing_phone
ambiguous
unsupported_region
needs_manual_check
Проверка: агент не отправляет заказ перевозчику, если `needs_review = true`.
Шаг 7. Заполните shipping_rules
В `shipping_rules` добавьте колонки:
rule_id
region
city
delivery_method
carrier
service_level
min_weight_kg
max_weight_kg
max_declared_value
sla_days
cutoff_time
is_active
updated_at
Пример:
RULE-MSK-COURIER | Москва | Москва | courier | cdek | express | 0 | 10 | 100000 | 2 | 16:00 | true | 2026-05-23
Проверка: для каждого активного заказа находится хотя бы одно правило доставки.
Шаг 8. Заполните carrier_accounts
В `carrier_accounts` добавьте колонки:
carrier_account_id
carrier
api_provider
account_name
service_levels
pickup_required
tracking_supported
label_purchase_allowed
status
owner
updated_at
`api_provider`:
shippo
easypost
aftership
cdek
boxberry
pochta
manual_csv
Проверка: на MVP `label_purchase_allowed = false`.
Шаг 9. Заполните shipments
В `shipments` добавьте колонки:
shipment_id
order_id
carrier
service_level
warehouse_id
package_weight_kg
package_length_cm
package_width_cm
package_height_cm
declared_value
shipment_status
label_status
shipped_at
expected_delivery_at
delivered_at
updated_at
`shipment_status`:
draft
ready_for_label
label_draft
label_purchased
picked_up
in_transit
out_for_delivery
delivered
exception
returning
lost
cancelled
Проверка: у отправленного заказа есть `shipment_id`, перевозчик и expected delivery.
Шаг 10. Заполните tracking_numbers
В `tracking_numbers` добавьте колонки:
tracking_id
shipment_id
order_id
carrier
tracking_number
tracking_url
tracking_status
last_checkpoint_at
last_checkpoint_text
created_at
updated_at
`tracking_status`:
pending
info_received
picked_up
in_transit
out_for_delivery
delivered
available_for_pickup
exception
failed_attempt
expired
unknown
Проверка: у каждого shipped-заказа есть tracking number или задача на его получение.
Шаг 11. Заполните tracking_events
В `tracking_events` добавьте колонки:
event_id
tracking_id
shipment_id
carrier
event_at
status_raw
status_normalized
location
message
source_system
created_at
`status_normalized`:
label_created
picked_up
in_transit
customs
out_for_delivery
delivered
failed_attempt
exception
returning
lost
unknown
Проверка: один raw-статус перевозчика превращается в единый `status_normalized`.
Шаг 12. Заполните rate_quotes
В `rate_quotes` добавьте колонки:
quote_id
order_id
carrier
service_level
price
currency
estimated_days
estimated_delivery_at
pickup_available
risk_notes
status
created_at
Статусы:
quoted
selected
rejected
expired
manual_only
Проверка: агент может сравнить 2-3 варианта доставки, но не покупает label.
Шаг 13. Заполните sla_targets
В `sla_targets` добавьте колонки:
sla_id
order_id
shipment_id
promised_ship_at
promised_delivery_at
carrier_sla_days
customer_sla_days
risk_before_hours
timezone
status
updated_at
Статусы:
on_track
at_risk
violated
unknown
Проверка: у каждого отправления есть дата, с которой агент сравнивает tracking.
Шаг 14. Подключите источники данных в n8n
Создайте workflow:
Logistics Delivery Agent - daily check
Добавьте узлы:
- `Schedule Trigger`;
- `Read orders`;
- `Read shipping_addresses`;
- `Read shipping_rules`;
- `Read carrier_accounts`;
- `Read shipments`;
- `Read tracking_numbers`;
- `Fetch tracking events`;
- `Fetch rate quotes`;
- `Normalize statuses`;
- `Check SLA`;
- `LLM delivery analysis`;
- `Write risks`;
- `Create notification drafts`;
- `Send approval`;
- `Write audit_log`;
- `Write error_log`.
Проверка: workflow читает все таблицы и получает хотя бы один tracking event.
Шаг 15. Подключите API перевозчика read-only
Для AfterShip:
GET /tracking/2024-07/trackings/{slug}/{tracking_number}
Для Shippo:
GET /tracks/{carrier}/{tracking_number}
POST /shipments для rate preview без покупки label
Для EasyPost:
GET /trackers/{id}
POST /shipments для rates
Для локального перевозчика используйте `HTTP Request` или импорт CSV.
Проверка: API возвращает статус, checkpoint и время события, а покупка label выключена.
Шаг 16. Нормализуйте статусы доставки
Создайте Function node `Normalize statuses`.
Правила:
delivered, доставлено -> delivered
in_transit, в пути -> in_transit
out_for_delivery, передано курьеру -> out_for_delivery
failed_attempt, неудачная попытка -> failed_attempt
exception, проблема, задержка -> exception
available_for_pickup, ожидает в ПВЗ -> available_for_pickup
Если статус неизвестен:
status_normalized = unknown
Проверка: raw-статусы разных перевозчиков попадают в один словарь.
Шаг 17. Найдите риски SLA в delivery_risk_log
Условия риска:
now > promised_delivery_at - delivery_risk_hours
и tracking_status != delivered
или:
last_checkpoint_at старше stale_tracking_hours
или:
status_normalized in failed_attempt, exception, lost, returning
В `delivery_risk_log` добавьте колонки:
risk_id
run_id
order_id
shipment_id
tracking_id
carrier
risk_type
risk_level
promised_delivery_at
last_checkpoint_at
evidence_json
recommended_action
owner
status
created_at
`risk_type`:
sla_at_risk
sla_violated
stale_tracking
carrier_exception
failed_attempt
lost_risk
bad_address
no_tracking
Проверка: отправление без checkpoint 24 часа получает `stale_tracking`.
Шаг 18. Создайте exception_queue
В `exception_queue` добавьте колонки:
exception_id
run_id
order_id
shipment_id
tracking_id
carrier
exception_type
message
risk_level
owner_team
status
created_at
resolved_at
`exception_type`:
bad_address
failed_attempt
pickup_missed
customs_hold
damaged
lost
return_to_sender
carrier_delay
no_tracking
Проверка: exception не превращается сразу в сообщение клиенту, сначала создается задача или approval.
Шаг 19. Настройте prompt для LLM delivery analysis
В n8n добавьте узел `LLM delivery analysis`.
System prompt:
Ты логистический координатор. Работай только с переданными данными.
Не покупай shipping label, не меняй адрес, не отменяй доставку, не оформляй возврат и не обещай компенсацию.
Если данных не хватает, верни status = needs_data.
Любое клиентское сообщение и любое изменение доставки отправляй в approval.
Ответ возвращай только JSON.
User prompt:
Проанализируй отправление.
order:
{{$json.order}}
shipment:
{{$json.shipment}}
tracking:
{{$json.tracking}}
events:
{{$json.tracking_events}}
sla:
{{$json.sla_target}}
address:
{{$json.shipping_address}}
Верни JSON:
{
"order_id": "...",
"shipment_id": "...",
"status": "on_track | at_risk | delayed | exception | needs_data",
"risk_level": "low | medium | high | critical",
"summary": "...",
"evidence": ["..."],
"recommended_actions": [
{
"action_type": "create_task | draft_customer_notification | contact_carrier | ask_warehouse | ask_support",
"owner": "logistics | support | warehouse | operations",
"text": "...",
"requires_approval": true
}
]
}
Проверка: ответ валидный JSON и содержит evidence.
Шаг 20. Создайте notification_drafts
В `notification_drafts` добавьте колонки:
draft_id
order_id
shipment_id
customer_id
channel
subject
message_text
reason
risk_level
evidence_json
approval_required
status
created_at
Каналы:
email
sms
whatsapp
telegram
crm_note
Статусы:
draft
sent_to_approval
approved
rejected
sent
manual_only
Проверка: клиентский текст не отправляется, пока нет `approved`.
Шаг 21. Создайте action_requests
В `action_requests` добавьте колонки:
request_id
order_id
shipment_id
action_type
action_text
target_system
payload_json
risk_level
approval_required
status
created_at
`action_type`:
contact_carrier
change_delivery_method
correct_address
create_return
buy_label
reschedule_delivery
create_support_ticket
notify_warehouse
Проверка: `buy_label`, `correct_address`, `create_return` всегда требуют approval.
Шаг 22. Настройте approval_queue
В `approval_queue` добавьте колонки:
approval_id
source
source_id
order_id
shipment_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 отправляйте:
- клиентское уведомление;
- изменение адреса;
- покупку shipping label;
- изменение способа доставки;
- оформление возврата;
- обещание компенсации;
- отмену отправления;
- ручное изменение статуса заказа.
Проверка: без `approved` нет записи в `execution_queue`.
Шаг 23. Сделайте Telegram approval
В n8n добавьте узел `Telegram`.
Сообщение:
ORD-1001: риск HIGH
Перевозчик: cdek
Проблема: нет checkpoint 30 часов, SLA завтра 20:00.
Действие: отправить клиенту черновик уведомления и создать задачу логисту.
Approve: /approve LOG-770
Edit: /edit LOG-770
Reject: /reject LOG-770
После `/approve LOG-770` workflow должен:
- найти `approval_id`;
- проверить статус `pending`;
- записать `approved`;
- заполнить `approved_at`;
- передать действие в `execution_queue`;
- записать событие в `audit_log`.
Проверка: `/reject` не создает исполнение и не отправляет клиентское сообщение.
Шаг 24. Настройте execution_queue
В `execution_queue` добавьте колонки:
execution_id
approval_id
order_id
shipment_id
action_type
target_system
payload_json
status
executed_at
result_json
error_message
Статусы:
queued
manual_only
executed
failed
skipped
Для MVP используйте `manual_only`: агент готовит действие, а человек делает его в CRM, helpdesk или кабинете перевозчика.
Проверка: пока write-доступ не включен, все действия остаются `manual_only`.
Шаг 25. Создайте task_queue
В `task_queue` добавьте колонки:
task_id
source
source_id
order_id
shipment_id
task_type
title
description
owner_team
assignee
priority
status
created_at
due_at
closed_at
`task_type`:
contact_carrier
warehouse_check
support_follow_up
address_check
refund_review
delivery_method_review
data_fix
Пример:
TASK-610 | delivery_risk_log | RISK-441 | ORD-1001 | SH-9001 | contact_carrier | Проверить задержку CDEK | Нет checkpoint 30 часов, SLA завтра | logistics | manager_1 | high | open | 2026-05-23 | 2026-05-24 | -
Проверка: каждый риск получает владельца и срок.
Шаг 26. Соберите daily_delivery_report
В `daily_delivery_report` добавьте колонки:
report_date
open_shipments
delivered_today
sla_at_risk
sla_violated
exceptions_open
stale_tracking_count
notification_drafts
tasks_created
approvals_pending
summary
created_at
Пример summary:
Сегодня 86 открытых отправлений, 9 рискуют нарушить SLA, 3 уже просрочены, 5 без checkpoint больше 24 часов, 4 черновика уведомлений ждут approval.
Проверка: отчет отправляется логисту, поддержке и операционному менеджеру.
Шаг 27. Настройте audit_log
В `audit_log` добавьте колонки:
event_id
run_id
event_type
order_id
shipment_id
actor
input_hash
output_hash
summary
created_at
Пишите события:
run_started
data_loaded
tracking_fetched
status_normalized
sla_checked
risk_found
exception_created
notification_drafted
approval_requested
approval_approved
task_created
run_finished
Проверка: по `run_id` видно, почему агент создал уведомление или задачу.
Шаг 28. Настройте error_log
В `error_log` добавьте колонки:
error_id
run_id
step
source_system
order_id
shipment_id
tracking_number
error_type
error_message
payload_sample
status
created_at
resolved_at
`error_type`:
api_error
missing_tracking
unknown_carrier
bad_address
invalid_json
approval_error
write_error
timeout
Проверка: если tracking number пустой, агент пишет `missing_tracking`, а не пытается угадать его.
Шаг 29. Протестируйте на одной отправке
Создайте тестовый заказ:
orders:
ORD-TEST-001 | shopify | 9001 | C-TEST | Анна Смирнова | anna@example.ru | +79991112233 | shipped | 2026-05-23 10:00 | 2026-05-24 18:00 | 2026-05-27 20:00 | courier | WH-MAIN | high | 2026-05-23
shipments:
SH-TEST-001 | ORD-TEST-001 | cdek | express | WH-MAIN | 1.2 | 30 | 20 | 10 | 4500 | in_transit | label_purchased | 2026-05-24 12:00 | 2026-05-27 20:00 | - | 2026-05-23
tracking_numbers:
TR-TEST-001 | SH-TEST-001 | ORD-TEST-001 | cdek | 1234567890 | https://tracking.example/1234567890 | in_transit | 2026-05-25 08:00 | Покинул сортировочный центр | 2026-05-24 | 2026-05-23
Сделайте так, чтобы сейчас было позже `last_checkpoint_at + 24h`.
Ожидаемый результат:
- в `tracking_events` есть checkpoint;
- в `delivery_risk_log` появилась строка `stale_tracking`;
- в `exception_queue` появилась проблема;
- в `notification_drafts` появился черновик;
- в `approval_queue` появилась заявка;
- в `task_queue` появилась задача логисту;
- в `audit_log` есть шаги проверки;
- в `error_log` нет ошибки.
Проверка: клиенту ничего не отправлено без approval.
Шаг 30. Проверьте негативные сценарии
Сделайте 5 тестов:
- удалите tracking number;
- укажите неизвестного перевозчика;
- поставьте адрес без телефона;
- верните от API timeout;
- верните от LLM невалидный JSON.
Ожидаемый результат:
- нет tracking number - `missing_tracking`;
- неизвестный перевозчик - `unknown_carrier`;
- плохой адрес - `bad_address`;
- timeout API - `timeout`;
- невалидный JSON - `invalid_json`;
- клиентское уведомление не отправляется;
- execution не запускается без approval.
Проверка: агент не заменяет неизвестные данные догадками.
Минимальная проверка результата
Прототип работает, если выполняются условия:
- `orders` содержит минимум 10 заказов;
- `shipments` содержит отправления;
- `tracking_numbers` содержит трек-номера;
- `tracking_events` получает события перевозчика;
- `sla_targets` содержит обещанную дату;
- `delivery_risk_log` ловит задержку;
- `exception_queue` ловит exception;
- `notification_drafts` создает только черновик;
- `approval_queue` блокирует клиентские сообщения;
- без `approved` нет записи в `execution_queue`;
- `task_queue` назначает владельца;
- `daily_delivery_report` показывает SLA и исключения;
- `audit_log` объясняет действия;
- `error_log` показывает плохие данные.
Что нельзя автоматизировать в первой версии
- покупку shipping label;
- изменение адреса доставки;
- изменение способа доставки;
- отмену отправления;
- оформление возврата;
- обещание компенсации;
- отправку сообщения клиенту без approval;
- изменение статуса заказа;
- списание стоимости доставки;
- массовое изменение правил доставки;
- любые действия с деньгами, клиентскими обещаниями и юридически значимыми условиями.
Частые вопросы
Можно ли начать без Shippo или EasyPost?
Да. Для MVP хватит выгрузки заказов, трек-номеров и CSV со статусами перевозчика. API нужен, когда вы хотите автоматизировать получение checkpoints и rates.
Может ли агент сам писать клиенту о задержке?
В первой версии лучше нет. Агент должен подготовить `notification_drafts`, показать evidence и отправить текст на approval, потому что сообщение клиенту влияет на доверие, компенсации и ожидания.
Как агент понимает, что доставка задерживается?
Он сравнивает `promised_delivery_at`, последний checkpoint, нормализованный tracking status и настройки `delivery_risk_hours` и `stale_tracking_hours`. Если SLA близко или checkpoint давно не обновлялся, создается риск.
Чем логистический агент отличается от складского?
Складской агент работает до отгрузки: остатки, ячейки, резервы и пересчет. Логистический агент работает после передачи отправления: перевозчик, трек-номер, checkpoints, SLA, задержки и уведомления.
Какой минимальный результат считать успешным?
Успешный MVP: агент берет одну отправку, получает tracking event, находит риск SLA, создает черновик уведомления, отправляет approval, создает задачу логисту и пишет audit log.