Больше всего на моём производстве терялись задачи. Утром я ставлю задачу, человек берёт её в работу. Через час к нему подходит другой человек со своим «срочно», и он переключается. Про первую задачу вспоминают через неделю, когда она уже нужна, а её никто не начинал. Виноватых нет: каждый был занят делом.

С чертежами было похоже. Чертёж обновили, а в цеху лежит старый. Или чертёж есть, но никто не помнит, у кого последняя версия. Вопросы по чертежу я записывал на бумажку, на ходу, прямо в цеху. Потом возвращался в офис, садился за компьютер и разбирал свои записи. На это уходило отдельное время, а часть записей до компьютера просто не доезжала.

Я посмотрел, что с этим делают большие системы, и решил собрать свою. Ушло около трёх недель чистой работы: по выходным и вечерам, в свободное от основной работы время. Получилась система APP Motors: задачи, наряды, склад, инструмент, чертежи. А главное в ней — агент, который смотрит на всё сразу, видит цепочки задач и сам напоминает людям, пока я занят другим. Ниже о том, как она устроена, для чего она мне и почему, по-моему, так можно закрыть задачи почти любого небольшого производства.

Почему не ERP

ERP и MES я не ругаю, на большом заводе без них никак. Но для небольшого производства это слишком дорого и долго: внедрение на месяцы, интегратор, лицензии на каждого пользователя, обучение. И слишком много всего: в системе сотни экранов, а нам нужны десять.

Главное для меня другое. ERP хранит, но не тормошит. Задача, которую никто не двигает, лежит в ней так же спокойно, как в блокноте. Чтобы что-то сдвинулось, кто-то должен зайти, найти, позвонить. Обычно этот кто-то я. А чтобы задача вообще попала в ERP, надо дойти до компьютера и заполнить форму, и в этот момент половина задач и теряется.

Мне нужно было другое:

  • задачу ставят за десять секунд, голосом с телефона, прямо там, где она возникла;

  • все видят, кто что делает и что горит;

  • сроки и простои отслеживает сама система, а не я;

  • чертежи, склад и история не теряются, даже если кто-то ошибся;

  • всё это работает на обычном сервере, без лицензий и интеграторов.

Кто этим пользуется

Сейчас в системе работают технолог-наладчик, два конструктора, мастер цеха, который распределяет работу, рабочие цеха, системный администратор и технический директор. В цеху стоит планшет с приложением, у остальных приложение на телефоне, а у кого компьютер под рукой, тот работает в веб-кабинете. Уведомления приходят в шторку телефона, как сообщения из мессенджера.

Как устроен APP Motors: где рождается задача, что внутри, что делает надзиратель
Как устроен APP Motors: где рождается задача, что внутри, что делает надзиратель

Внутри то, что есть у любого производства:

  • задачи «кто что делает»: купить, заказать, сделать, спроектировать, с фото и сроками;

  • наряды и операции на изделие;

  • склад: приход, выдача, резервы материалов под наряд, места хранения;

  • инструмент поштучно, с историей, у кого он сейчас;

  • чертежи и документы с ревизиями;

  • замечания производства, дефициты и заявки на закупку.

Каждый видит свою часть. В системе 11 ролей: владелец, администратор, конструктор, технолог, диспетчер, исполнитель в цеху, склад, закупщик, сборщик, директор и отдельная роль для ИИ-агента. Права выдаются по действиям: «создать задачу», «зарезервировать материал», «утвердить ревизию». Новая роль собирается из готовых прав без правки кода.

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

Доска задач в приложении: счётчики, «кто что делает», вкладки «Все / Мне / От меня / Лично» (имена замазаны)
Доска задач в приложении: счётчики, «кто что делает», вкладки «Все / Мне / От меня / Лично» (имена замазаны)

Задача рождается в цеху

Ради этого я всё и делал. Захожу в цех быстро что-то обсудить, по ходу разговора всплывает вопрос к конструктору. Раньше я бы записал его на бумажку, донёс до офиса, сел за компьютер и написал конструктору, если бы не забыл. Сейчас я достаю телефон и надиктовываю задачу прямо там.

Телефон распознаёт речь, а кнопка «Разобрать с ИИ» раскладывает сказанное по полям: название, описание, тип, срочность, срок, исполнитель. На проверке фраза вида «конструктору к пятнице, срочно, …» стала задачей с типом «Спроектировать», срочностью «Срочно», сроком в пятницу 23:59 и нужным конструктором в поле исполнителя. Я смотрю, что всё правильно, и жму «Создать». Это несколько секунд, и я даже не вышел из цеха.

Экран новой задачи: микрофон в каждом поле, «Разобрать с ИИ», тип, срочность, срок, исполнитель, личная задача, фото
Экран новой задачи: микрофон в каждом поле, «Разобрать с ИИ», тип, срочность, срок, исполнитель, личная задача, фото

Модель заодно чинит то, что телефон расслышал плохо. Наговорено «уплотнитильные кольца для корпуса ам12, штук двадцать». На выходе название «Закупить уплотнительные кольца к корпусу АМ-12», в описании «Количество: 20 штук» и пометка «Уточнить: спецификация (размер, материал, ГОСТ/ТУ)». Ещё система нашла в базе задачу по этому корпусу и предложила связать новую с ней как «нужно для».

Дальше всё идёт само. Конструктору сразу прилетает уведомление в шторку. Если ему что-то непонятно, он пишет вопрос в комментарии, и уже мне прилетает уведомление с вопросом. Я отвечаю, он берёт задачу в работу. Цепочка запустилась, вопрос начал решаться в ту же минуту, а не на следующий день, когда я доберусь до компьютера. Новую общую задачу видят все, кто работает в системе, поэтому, если она касается ещё кого-то, он узнает о ней сразу.

Секунды на заполнении формы тут мелочь. Пропадает целый круг: записать, дойти, сесть, вспомнить, что имел в виду, набрать, отправить. А с ним пропадают и задачи, которые на этом кругу терялись.

Исполнителя система ищет у себя на сервере по списку сотрудников, до модели. В текст, который уходит в Claude (здесь Haiku), вместо имени подставляется «[исполнитель]». Три разбора при первой проверке стоили вместе 0,004 $.

На этом же разборе меня поймал первый баг, найденный уже на живой системе. Функция принимала контекст базы (проекты, похожие задачи), но в сам запрос к модели его не добавляла. Тесты были зелёные: они подменяли функцию уровнем выше и не смотрели, что реально уходит в модель. Теперь есть тест, который проверяет собранный запрос целиком.

Надзиратель

Поставить задачу быстро — половина дела. Вторая половина — чтобы её не забыли, когда придёт следующее «срочно». Этим занимается надзиратель: фоновая задача, которая каждые пять минут обходит все активные задачи и решает, кому что пора напомнить.

Решают простые правила, которые можно прочитать в коде. Языковая модель подключается в одном месте, когда надо по-человечески сформулировать совет мне. Если модель недоступна, всё остальное продолжает работать. Тормошить людей надзиратель может только днём, с 8:00 до 21:00 по Москве. Ночью он молчит, даже если всё горит.

Сроки: лесенка напоминаний

Исполнитель получает напоминание за сутки до срока, потом за два часа. Каждое уходит один раз на значение срока: если автор перенёс срок, лесенка начинается заново, а исполнителю приходит уведомление «срок: было → стало». После просрочки напоминание повторяется не чаще раза в три часа, с текстом вроде этого (задача для примера):

Просрочено: Заказать подшипники
Срок был 13.11 23:59 МСК, просрочка 1 д 4 ч.
Сделайте или напишите в комментарии, что мешает.

Просьба написать, что мешает, стоит в каждом напоминании. Мне проще прочитать «жду поставщика до среды», чем гадать, почему задача стоит. А в цепочках, о которых ниже, комментарий ещё и считается движением, и простой отсчитывается заново.

«Готово» нажимает автор

Исполнитель не может сам закрыть задачу. Он переводит её «на проверку», и для этого нужно приложить хотя бы одно фото или файл: собранный узел, накладную, скриншот. Принимает или возвращает задачу автор. Вернуть можно только с комментарием, что не так. Если автор и исполнитель один человек, он принимает сам.

Так «сделал» перестаёт означать «я считаю, что сделал»: у каждой закрытой задачи есть фото и человек, который его посмотрел.

Цепочки: кто держит работу

Любую задачу можно поставить как «нужно для» другой: чертёж нужен для детали, деталь нужна для сборки. В карточке задачи есть кнопка «Нужно для этой задачи…», которая сразу открывает создание подзадачи. Из таких связей получается цепочка, и надзиратель смотрит на неё целиком.

Цепочка «нужно для»: узкое место, кому что пишет надзиратель, пороги простоя
Цепочка «нужно для»: узкое место, кому что пишет надзиратель, пороги простоя

Узкое место цепочки — активная задача, у которой нет своих незакрытых подзадач. Её никто не ждёт снизу, её просто кто-то должен сделать. Простой считается от последнего движения: смены статуса, комментария или нового фото. Порог зависит от срочности самой срочной задачи в цепочке:

STALL_AFTER: dict[str, timedelta] = {
    TaskPriority.CRITICAL.value: timedelta(hours=4),   # «Нужно вчера»
    TaskPriority.HIGH.value: timedelta(days=1),        # «Срочно»
    TaskPriority.NORMAL.value: timedelta(days=2),
    TaskPriority.LOW.value: timedelta(days=5),         # «Не срочно»
}

Когда порог пройден, надзиратель пишет тому, кто держит узкое место: из-за него стоит цепочка, и вот кто ждёт. Тем, кто ждёт, он пишет, что можно пока переключиться на другую работу и им сообщат, когда будет готово. Если цепочка с пометкой «Нужно вчера», он сразу пишет и мне, не дожидаясь сводки. Так выглядят первые два сообщения (задачи для примера, в живых уведомлениях вместо ролей стоят имена):

Из-за задачи стоит цепочка: Чертёж крышки
Нет движения 1 д 3 ч; срок не назван — назовите его, чтобы остальные могли планировать.
Ждут: Сборщик (по «Собрать узел»). Если есть сложности — напишите в комментарии, что мешает.
Ждём: Чертёж крышки
Ваша задача «Собрать узел» ждёт «Чертёж крышки» у Конструктора (срок пока не назван).
Пока можно переключиться на другую работу — сообщим, когда будет готово.

Когда подзадачу принимают, ждущие сразу получают «готово, можно продолжать». Цепочку видно и в карточке задачи: у родителя «ждём 1 из 2», у подзадачи «нужна для задачи такой-то», по звеньям можно переходить.

Чтобы не превратиться в спам, каждое напоминание запоминается вместе с моментом последнего движения. Пока узкое место стоит, держателю повторяют не чаще порога, а ждущим пишут один раз за эпизод простоя. Сдвинулось и снова встало — новый эпизод.

Сводка в 9:00 и 18:00

Дважды в день мне приходит сводка: сколько задач активно, что просрочено, что горит в ближайшие сутки, что с пометкой «Нужно вчера», что без исполнителя, что не двигалось три дня и больше, сколько задач у каждого. В конце раздел про цепочки с простоем. Если ничего не горит, сводка так и пишет: «Всё спокойно».

Сводки в уведомлениях приложения
Сводки в уведомлениях приложения

Здесь и работает модель (Claude Haiku). По каждой стоящей цепочке она пишет одну фразу-совет и готовое сообщение, которое я могу переслать держателю. Имена людей в модель не уходят: перед запросом сервер заменяет их на «Сотрудник 1», «Сотрудник 2», а в ответе меняет обратно у себя.

labels: dict[str, str] = {}

def lab(name: str) -> str:
    return labels.setdefault(name, f"Сотрудник {len(labels) + 1}")

# ... запрос к модели только с метками ...

back = {v: k for k, v in labels.items()}

def unlab(text: str) -> str:
    for label in sorted(back, key=len, reverse=True):   # «Сотрудник 12» раньше «Сотрудник 1»
        text = text.replace(label, back[label])
    return text

В промпте модели прямо написано: без угроз, без денег и наказаний, технические параметры не придумывать. Сообщение от моего имени система сама не отправляет никогда, только предлагает текст. Отправляю я.

Ночной обход производства

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

Находит это обычный SQL. Модель (здесь Sonnet) получает уже готовый список, расставляет приоритеты и пишет дайджест. Сама ничего не закрывает и в справочники не пишет: у роли ИИ-агента прав на запись нет. Рядом работает агент дефицитов: сравнивает, сколько материала нужно под открытые наряды, с тем, что есть на складе за вычетом резервов, и заранее говорит, чего не хватит.

Почему ничего не теряется

«Ничего не теряется» держится на нескольких жёстких правилах:

  • складские записи нельзя удалить или исправить; ошибку исправляют обратной проводкой, остаток всегда считается по журналу движений;

  • ревизия чертежа не редактируется: новая версия — новая запись, старая уходит в архив с автором, датой и причиной замены; у документа одна действующая ревизия, и в цех попадает только она;

  • каждое важное действие пишется в журнал аудита: кто, что, было, стало;

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

Это ровно те две боли, с которых всё началось. Старый чертёж в цеху больше не окажется: действующая ревизия одна. А задача, которую отодвинуло чужое «срочно», не пропадёт: она висит на доске со сроком, и надзиратель про неё напомнит.

Плюс резервная копия каждую ночь, и её забирают на мой компьютер. После того как в ноябре хостинг потерял мой сервер целиком (я писал, как переезжал), базу этой системы подняли как раз из такой копии.

Как это сделано и сколько заняло

Сервер на Python: FastAPI, PostgreSQL, Redis, RabbitMQ и Celery для фоновых задач, MinIO для файлов, Nginx. Приложение на Kotlin и Jetpack Compose. Уведомления в шторку через Firebase. Всё в Docker Compose на обычном VPS на 8 ГБ, где рядом живут ещё два моих проекта.

Около трёх недель чистой работы, не подряд: в основном выходные и вечера. Git это хорошо видит: из 245 коммитов 120 пришлись на субботы и воскресенья.

Писал я систему вместе с командой ИИ-агентов, и это отдельная тема. На Хабре про такие команды уже много хорошего, например «Один разработчик, 14 агентов, восемь месяцев». У меня то же самое, только под производство: тех-лид, бэкенд, Android, тестировщик, проверяющий безопасность и контролёр релиза, который не верит отчётам остальных и проверяет каждый пункт сам. Получилось около 73 тысяч строк на Python в сервере, около 43 тысяч на Kotlin в приложении и примерно полторы тысячи тестов. Как устроена эта команда и где она ошибалась, расскажу в одной из следующих статей.

Похожий путь уже описывали коллеги: в «Нейроскладе компонентов для микроэлектроники» тоже небольшое производство и своя система вместо таблиц.

Почему это подходит не только мне

В коде почти нет ничего про моторы. Роли собираются из прав, справочники материалов, инструмента и мест хранения заполняются под своё производство, маршруты операций задаёт технолог. Цепочки задач, напоминания, приёмка с фото и сводки вообще не знают, что именно производят. Слово «электродвигатели» есть в паре промптов, чтобы модели было понятнее, о чём речь.

Поэтому я думаю, что такая схема подходит почти любому небольшому производству, где работа проходит через несколько человек, будь то мебель или сборка электроники. Задача там теряется так же, как у меня: между людьми, в момент передачи.

Что дальше

Сейчас готовится модуль аналитики. Основа для него уже есть: каждый переход задачи и наряда пишется в журнал с временем и автором, и из журнала видно, сколько задача была в работе, сколько ждала и на ком стояла. Модуль соберёт это в графики: по каждой конкретной задаче — сколько она заняла и где были простои, по производству в целом — где работа застревает чаще всего. Поверх графиков будет агент, который смотрит на эти цифры и показывает слабые места процесса. Тогда можно будет разбирать ошибки по фактам, а не по памяти: например, почему сборка заняла две недели вместо трёх дней и на каком звене она простояла.

Остальное по плану:

  • бухгалтерия: связь с учётом, чтобы закупки и списания не вбивать второй раз;

  • сквозное ведение заказа от заявки клиента до отгрузки, с теми же цепочками и напоминаниями;

  • свои экраны в приложении для конструктора, технолога, закупщика и директора (сейчас в приложении есть экраны исполнителя, сборщика, склада и диспетчера, а доска задач у всех);

  • кнопка «Отправить» прямо в совете из сводки, чтобы не копировать текст руками;

  • несколько площадок в одной системе.

В следующих статьях цикла разберу по частям: как семь агентов превращают голосовое сообщение в черновик задачи, как работает команда ИИ-агентов, которая писала систему, и почему приложение на планшете говорило «нет соединения», хотя сервер ответил 200.

Вместо вывода

Хранить данные умеет любая таблица. Мне нужна была система, которая не даёт забыть: задачу ставишь там, где она возникла, она сразу у исполнителя, а дальше за ней смотрят агенты и тормошат, пока она не закрыта с фото. Теперь я могу зайти в цех, поговорить, надиктовать три задачи и уйти, не думая, что что-то из этого потеряется по дороге в офис.

Идеальной её не назову: экраны для половины ролей ещё в работе, аналитика готовится, бухгалтерия пока в планах. Про каждую из этих частей напишу отдельно, когда доделаю.

Комментарии (5)


  1. quiet_archivist
    10.11.2026 06:16

    Поздравляю, вы изобрели "Битрикс24". А точнее, его модуль "Задачи и проекты".


    1. Kogolbok
      10.11.2026 06:16

      Все эти битриксы и пр. дороги и универсально бесполезны как швейцарский нож. А тут человек и сэкономил и написал под свои нужды. Я тоже себе пишу систему с нуля, потому что под мои нужды ну вообще ничего не идёт. Слишком много зависимостей в продукции и оборудовании. Если решиться на какой-то erp или cmms, то заколебёшься интегратору рассказывать даже суть проблемы. У нас пытались написать систему для бухгалтеров под это дело, да уже второй год так и не заработало. А деньги уплачены. И я не знаю никого кому пошли бы все такие штуки без напилинга. Пришлый специалист делает всё не особо вникая, а потом все мучаются. Лучше я сам напишу. Ещё пара переделок с нуля и у меня получится. Точно-точно :))


      1. Aflubin1978 Автор
        10.11.2026 06:16

        Спасибо, приятно читать. Универсальная система хороша для всех понемногу, а мне нужна была такая, которая знает наше производство: какой чертёж держит сборку, где сейчас инструмент, кто чем занят. Удачи с вашей! Интересно, с чего вы начали: с задач или со склада?


        1. Kogolbok
          10.11.2026 06:16

          Спасибо :) я всё ещё в процессе. Нет времени, приходится в режиме пожаротушения заниматься абсолютно всем сразу и программа вторую неделю на паузе и переосмыслении. Я начинал и со склада и с продукции и с оборудования и всё вязну. Пишу с нуля, на питончике, безо всяких ИИшек-надзирателей, мне такое даже не снится :)) и по причине сложности и того, что никогда на это времени не хватит и по причине того, что комп на котором всё крутится ну очень слабенький. Ну да ладно. Переборю. Сначала хотелось выложить в опенсорс, но подумал... а кому кроме нас может быть это полезно? Слишком уж завязано на наши процессы и из интересного там... ну может Гантт для нищих :)))

          Успехов и Вам :)


    1. Aflubin1978 Автор
      10.11.2026 06:16

      В Битрикс24 задачи сделаны хорошо, спорить не буду: сроки, напоминания, связанные задачи. Мне же в одной системе нужны были ещё склад с резервами под наряд, инструмент поштучно, наряды и ревизии чертежей. И чтобы агент видел всё это вместе: какой наряд стоит, какого материала не хватит, чей чертёж держит сборку. Плюс задача голосом прямо из цеха, без формы. Подгонять под это чужую систему мне показалось дольше, чем собрать своё под своё производство.