Проблема
Я пришел к идее AI-диспетчера не из любви к хайпу. Все началось с очень приземленной боли: логистика росла быстрее, чем люди успевали ее координировать. Заявки приходили из CRM, почты, телефонии и мессенджеров. Адреса писали как угодно: «склад на Софийской», «тот же объект, что в прошлый четверг», «заезд со стороны шлагбаума». Диспетчер держал в голове водителей, машины, привычки клиентов, пробки, ограничения по времени и вечное «а кто сегодня ближе».
Снаружи процесс выглядел рабочим. Машины ездили, грузы доставлялись, клиенты в целом были довольны. Но внутри было много ручной магии. Один опытный диспетчер мог за 10 минут решить задачу, на которую новый сотрудник тратил час. Если человек уходил в отпуск, качество маршрутов падало. Если заявок становилось больше обычного, начинались звонки, спешка, двойные назначения и холостые километры.
Самым неприятным было то, что ошибки не выглядели катастрофой. Они расползались мелкими потерями: водитель простоял 35 минут, машина поехала не с тем типом кузова, клиенту забыли отправить ETA, заявка с низкой маржинальностью заняла слот, который можно было отдать более выгодному рейсу. В конце месяца это превращалось в деньги, но найти конкретную причину было сложно.
Я зафиксировал базовые метрики: среднее время назначения машины — 18 минут, доля ручных уточнений по заявке — 42%, холостой пробег — около 14%, опоздания по вине планирования — 9%, среднее количество рейсов на машину в день — 3,1. Эти цифры стали отправной точкой. Без них любой разговор про AI был бы красивой презентацией, а не проектом.
Идея
Идея была простой: сделать не «робота, который управляет логистикой», а диспетчерский контур, который берет на себя рутину и предлагает человеку лучший вариант. Мне не хотелось отдавать системе полный контроль с первого дня. В логистике слишком много контекста: водитель может быть формально свободен, но после ночного рейса; машина может быть рядом, но с неподходящим пропуском; клиент может быть важным, хотя заявка выглядит маленькой.
Я сформулировал задачу так: AI-диспетчер должен принять заявку, извлечь параметры, проверить ограничения, подобрать 3 лучших варианта назначения, объяснить выбор и отправить задание водителю после подтверждения диспетчера. Если уверенность высокая и сумма риска низкая, система может назначать автоматически. Если есть конфликт, она подсвечивает его человеку.
Мне было важно, чтобы AI не заменял классические алгоритмы. Маршрутизация, расчет расстояний, временные окна, ограничения по грузоподъемности — это задачи для геосервисов, оптимизаторов и правил. LLM нужна там, где входные данные грязные: понять текст заявки, нормализовать адрес, извлечь вес и объем, распознать «нужна газель с гидробортом», объяснить решение и сформировать понятное сообщение водителю.
Так родилась архитектурная идея: LLM как слой понимания и коммуникации, оптимизатор как слой расчета, база событий как слой памяти, человек как слой контроля. Это звучит менее эффектно, чем «полностью автономный AI», зато работает в реальном бизнесе.
Техническая реализация
Первую версию я собрал на FastAPI, PostgreSQL с PostGIS, Redis Queue и простом интерфейсе для диспетчера. Источники заявок подключил через webhook из CRM и отдельный почтовый парсер. Все входящие сообщения попадали в очередь, чтобы система не падала при всплесках. Дальше LLM извлекала поля: адрес загрузки, адрес разгрузки, временное окно, тип груза, вес, объем, требования к машине, контакт клиента и комментарии.
После извлечения данных шел этап валидации. Адрес проверялся через геокодер, координаты сохранялись в PostGIS, а сомнительные адреса отправлялись на ручное уточнение. Вес и объем сравнивались с типами машин. Временное окно проверялось на реалистичность. Если клиент писал «срочно сегодня», система переводила это в конкретный дедлайн только после уточнения у менеджера или клиента.
Для маршрутов я использовал связку OSRM и коммерческого API пробок. OSRM давал быстрый расчет базового маршрута, а внешний API корректировал ETA с учетом реальной дорожной ситуации. Для назначения машины система считала несколько факторов: расстояние до точки загрузки, доступность водителя, тип кузова, остаток рабочего времени, история опозданий, приоритет клиента, маржинальность рейса и вероятность успеть в окно.
Интерфейс диспетчера я специально сделал скучным. Карта, список заявок, карточки машин, объяснение рекомендации и кнопки «назначить», «поменять», «уточнить». Никакой магии. Если система предлагала водителя, рядом было написано почему: «8,4 км до загрузки, подходит по кузову, завершает текущий рейс через 22 минуты, успевает к окну с запасом 31 минута». Такое объяснение быстро повысило доверие.
Водителю задание уходило в Telegram-бот и мобильную веб-страницу. Там были адреса, маршрут, контакты, кнопки статусов «принял», «прибыл», «загрузился», «разгрузился», «проблема». Эти статусы возвращались в систему и обучали следующий расчет. Без обратной связи AI-диспетчер был бы просто красивым планировщиком.
Архитектура
Финальная архитектура выглядела так: источники заявок → API Gateway → очередь событий → модуль извлечения данных → геокодинг → нормализация → оптимизатор назначения → интерфейс диспетчера → канал водителя → события исполнения → аналитика. Отдельно стояли сервис правил, база водителей, база машин, календарь смен, интеграция с CRM и финансовый модуль для расчета маржинальности.
Я разделил систему на события. Заявка создана, адрес подтвержден, машина назначена, водитель принял, прибыл на загрузку, вышел с точки, прибыл на разгрузку, рейс закрыт. Благодаря этому стало видно, где теряется время. До проекта мы спорили ощущениями. После проекта открывали дашборд и видели, что проблема не «водители медленные», а «менеджеры часто присылают неполные адреса после 16:00».
Для мониторинга поставил Prometheus и Grafana. Важные метрики: время обработки заявки, доля автоматических назначений, доля ручных уточнений, точность ETA, холостой пробег, опоздания, отмены, нагрузка по водителям, экономия километров, маржинальность рейсов. Я отдельно вывел показатель доверия: как часто диспетчер принимает рекомендацию системы без изменений.
Самым полезным архитектурным решением стала возможность отката. Диспетчер мог отменить рекомендацию, выбрать другого водителя и указать причину: «знает объект», «клиент просил именно его», «устал после ночного рейса», «машина чистая после мойки». Эти причины попадали в правила и постепенно превращали человеческий опыт в данные.
Первые 2 недели (ошибки)
Первая ошибка была ожидаемой: грязные адреса. LLM отлично извлекала смысл, но геокодер иногда выбирал не тот корпус или въезд. Для склада это критично. Водитель может приехать к правильному зданию, но потерять 20 минут на поиске ворот. Я добавил справочник частых объектов с координатами въездов, комментариями и фотографиями. После этого точность резко выросла.
Вторая ошибка — я переоценил готовность водителей нажимать статусы. Первые дни часть событий не возвращалась в систему, и ETA становился неточным. Мы упростили интерфейс до четырех больших кнопок и добавили голосовые подсказки. Еще сработала честная коммуникация: я объяснил, что статусы нужны не для контроля ради контроля, а чтобы меньше звонить водителю и точнее планировать следующий рейс.
Третья ошибка — слишком агрессивная оптимизация. Алгоритм иногда выбирал математически лучший вариант, но игнорировал человеческий контекст. Например, ставил водителя на сложного клиента второй раз подряд. Формально это эффективно, фактически — путь к выгоранию. Я добавил коэффициент справедливости нагрузки и ограничения на повтор сложных рейсов.
Четвертая ошибка — недостаточно понятные объяснения. Первая версия писала: «назначение оптимально по совокупному скору 0,82». Диспетчеру это ни о чем не говорит. Мы переписали объяснения человеческим языком: «эта машина ближе, подходит по объему, водитель уже был на объекте, но есть риск пробки на КАД». После этого рекомендации стали принимать чаще.
Пятая ошибка — я поздно подключил финансы. Сначала мы оптимизировали километры и время, но не учитывали маржинальность. Оказалось, иногда выгоднее отдать более дальнюю машину на срочный дорогой рейс, а ближнюю оставить под серию коротких доставок. После добавления маржи система стала думать ближе к бизнесу.
Результаты
Через 4 месяца после запуска мы сравнили метрики с baseline. Среднее время назначения машины снизилось с 18 минут до 46 секунд. Доля ручных уточнений упала с 42% до 17%. Холостой пробег снизился с 14% до 9,6%. Опоздания по вине планирования сократились с 9% до 3,8%. Среднее количество рейсов на машину выросло с 3,1 до 3,7 в день.
Самое важное — диспетчеры перестали тонуть в рутине. Они не исчезли из процесса, а стали заниматься исключениями: сложные клиенты, нестандартные грузы, конфликтные окна, переговоры с водителями. Система брала типовые назначения и готовила решения там, где раньше нужно было держать в голове десятки переменных.
ROI 340% получился не за счет одной большой экономии, а за счет суммы маленьких улучшений. Меньше холостых километров, меньше срочных доплат, выше загрузка машин, меньше пропущенных окон, меньше ручного времени, быстрее реакция на заявки. Отдельно выросла управляемость: я наконец-то видел логистику не через рассказы, а через события и цифры.
Клиенты тоже заметили изменения. ETA стали точнее, менеджеры быстрее отвечали на вопрос «когда машина», а повторные звонки в диспетчерскую снизились. Для B2B-логистики это важнее, чем кажется: клиент покупает не только доставку, он покупает предсказуемость.
Бюджет
Первый рабочий пилот стоил около 780 000 ₽. В эту сумму вошли backend, база, интеграции, простой интерфейс диспетчера, Telegram-бот, настройка картографических API и аналитика. Я не покупал тяжелую готовую TMS, потому что задача была не заменить весь контур, а встроить интеллектуальную диспетчеризацию поверх существующих процессов.
Ежемесячные расходы составили примерно 95 000 ₽: серверы, API карт, LLM-запросы, мониторинг и поддержка. После оптимизации промптов и кэширования часть расходов снизилась. Например, повторные адреса больше не гонялись через полный контур распознавания, а брались из справочника объектов.
Экономический эффект на четвертый месяц мы оценили примерно в 660 000 ₽ в месяц. Это осторожная оценка: учитывали только подтвержденное снижение холостого пробега, экономию времени диспетчеров, уменьшение срочных доплат и рост выполненных рейсов без расширения парка. Репутационный эффект и удержание клиентов в расчет не включали, хотя они тоже были.
Главный урок по бюджету: не нужно начинать с идеальной платформы. Начните с узкого контура, который принимает заявку, предлагает назначение и собирает фактические события. Если этот контур дает деньги, дальше можно добавлять прогноз спроса, динамическое ценообразование, автоматические уведомления клиентам и интеграцию с бухгалтерией.
Еще один вывод, который я сделал уже после запуска: AI-диспетчер — это не только про маршруты. Это про дисциплину данных. Пока заявки приходили в свободной форме, каждый отдел считал процесс по-своему. Менеджер был уверен, что передал всю информацию, диспетчер считал, что получил неполный адрес, водитель думал, что его поздно предупредили, а клиент видел только задержку. Когда мы перевели процесс в события, спорить стало сложнее. У каждого этапа появилось время, владелец и причина задержки.
Я специально не стал начинать с большого внедрения на весь парк. Первые недели система работала как рекомендательный слой: она предлагала назначение, но диспетчер подтверждал его вручную. Это помогло собрать доверие и не испугать команду. Люди видели, что AI не забирает у них работу, а показывает варианты, которые можно принять или отклонить. Более того, отклонения стали ценными данными. Если диспетчер выбирал другого водителя, я просил указать причину. Через месяц этих причин было достаточно, чтобы улучшить правила.
С клиентскими уведомлениями тоже был интересный момент. Сначала я хотел отправлять красивые автоматические сообщения на каждом этапе. Потом понял, что клиенту не нужна лишняя лента событий. Ему нужны три вещи: подтверждение, точное ETA и предупреждение, если что-то идет не так. Мы оставили короткие сообщения и сделали упор на точность. Это снизило нагрузку на менеджеров, потому что клиенты перестали звонить с вопросом «где машина» каждые полчаса.
Отдельно пришлось поработать с исключениями. Например, что делать, если водитель нажал «прибыл», но геопозиция показывает, что он в двух километрах от точки? Что делать, если клиент переносит окно уже после назначения машины? Что делать, если подходящая машина есть, но ее водитель скоро превысит рабочее время? Такие сценарии нельзя отдавать одной LLM. Я вынес их в правила и сделал так, чтобы модель только объясняла ситуацию человеческим языком.
После проекта я стал осторожнее относиться к обещаниям «AI оптимизирует логистику на 100%». В реальности оптимизация появляется там, где есть повторяемый процесс, понятные ограничения, обратная связь и готовность команды менять привычки. Если просто подключить модель к хаотичным заявкам, она ускорит хаос. Если сначала навести порядок в событиях и правилах, AI начинает приносить деньги.
FAQ
С чего начать AI-диспетчеризацию в логистике?
Начните не с модели, а с карты процесса: откуда приходит заявка, кто назначает машину, где хранятся адреса, как фиксируется статус рейса и какие метрики считаются сейчас.
Можно ли сделать такую систему без собственной LLM?
Да. На первом этапе можно использовать облачную модель для извлечения данных из заявки и правил назначения, а критичные расчеты маршрута оставить классическим алгоритмам и картографическим API.
Какая главная ошибка при запуске?
Недооценить качество адресов и статусов. Если база адресов грязная, водители не подтверждают события, а фактическое время не возвращается в систему, AI будет красиво ошибаться.
Когда появляется ROI?
В моем случае первые деньги были видны через 6 недель: меньше ручной диспетчеризации, меньше холостых километров, меньше срочных доплат. Полный ROI 340% посчитали на горизонте 4 месяцев.
