Дисклеймер: Это продолжение первой статьи про PLC AI Studio — инструмент, который заставляет ИИ сначала разобраться в задании, а потом писать код ПЛК, и проверяет результат фактами. В первой части был разобран базовый режим: одна установка, один IOLIST + одно ТЗ → один проверенный ST-файл. Здесь рассказываю то, что в прошлый раз было только тизером «что дальше»: многопроектный (многосистемный) режим и маршрутные окна — пошаговую навигацию по программе. Инструмент по-прежнему проходит тестирование, и я по-прежнему публикую до релиза, чтобы услышать инженеров-практиков.
Где мы остановились
В первой части я показал, как ИИ из «уверенного галлюцинатора» превращается в управляемого исполнителя: разбор задания перед генерацией, три специализированных агента (R2-PLCGen, Agents4PLC, truST Platform), проверка кода в программном симуляторе (Tier S) и в настоящем компиляторе matiec (Tier H), детерминированный ремонт типовых ошибок и финальное слово всегда за инженером.
Всё это работало для одной установки. Но я закончил статью честным признанием: реальный крупный объект — это не одна установка. И обещал многосистемный режим. Он теперь есть. Расскажу, как он устроен — и почему по дороге пришлось переделать саму навигацию по программе.
Почему одной установки мало
Возьмём типичный объект — производственный корпус. Внутри:
-
приточно-вытяжная вентиляция (несколько систем П1, П2, …),
-
индивидуальный тепловой пункт (ИТП),
-
пожарная сигнализация,
-
дымоудаление и подпор воздуха,
-
конвейерная линия,
-
водоподготовка.
Каждая система живёт в своём техническом задании и, нередко, в своём ПЛК. Но работают они в единой цепочке:
-
при пожаре пожарная сигнализация останавливает приточки и запускает дымоудаление и подпор;
-
приточка с водяным калорифером зависит от готовности теплоносителя от ИТП;
-
конвейер не пускается, пока вентиляция зоны не вышла на режим.
Эти связи — самое важное и самое хрупкое в проекте. И при этом они почти нигде не формализованы: инженер держит их в голове или, в лучшем случае, в Excel. Когда систему программируют по отдельности, межсистемная блокировка — первое, что ломается.
Многопроектный режим — это попытка вытащить эти связи на свет, дать инженеру их явно подтвердить и только потом генерировать код, единый для всего объекта.
Несколько терминов — чтобы дальше было понятно
В первой части я уже объяснял ST, IOLIST, POU, RAG и matiec. Для второй части добавлю ещё несколько.
GVL (Global Variable List) — список глобальных переменных. В CODESYS и других средах это переменные, видимые всем программам проекта. Именно через них одна система передаёт сигнал другой: например, переменная gFIRE_ALARM (глобальный сигнал «Пожар»), которую пишет пожарная сигнализация, а читают приточки и дымоудаление.
Межсистемная блокировка — логическая связь, при которой состояние одной системы влияет на работу другой. Классика: «при пожаре закрыть противопожарный клапан и остановить вентилятор».
Топологический порядок — порядок, в котором системы нужно обрабатывать, чтобы «производитель» сигнала шёл раньше «потребителя». Пожарная сигнализация и ИТП производят сигналы, которые потребляют приточки, — значит, их логично рассматривать первыми.
Ко-симуляция — совместный прогон нескольких программ в одном расчётном цикле через общую таблицу сигналов. В отличие от проверки одной POU, ко-симуляция показывает, как системы реагируют друг на друга.
Контракт интерфейсов — формализованное описание, какие межсистемные сигналы существуют, какого они типа, кто их производит и кто потребляет. По сути — техническое соглашение между системами, которое раньше жило только в голове инженера.
Сначала про навигацию: зачем понадобились маршрутные окна
Когда базовый режим оброс возможностями — разбор задания, три агента, две ступени проверки, аудит, редакторы, отчёт, — возникла банальная проблема: в программе стало легко потеряться. Что нажимать первым? Что обязательно, а что нет? На каком я шаге?
Поэтому появилось маршрутное окно — вертикальная панель-чеклист, которая ведёт инженера по шагам и подсвечивает следующее действие. Это не модальное окно, которое мешает работать: панель живёт сбоку, её можно скрыть, менять размер (тянуть за угол — сужать, расширять) и она не перекрывает рабочую область.
Маршрутных окна теперь два, по числу режимов работы — и в заголовке проводника две отдельные кнопки:
-
🧭 Объект — для одиночного проекта (одна установка);
-
🏢 Комплекс (много систем) — для комплексного объекта.
Какой режим вы выбрали кнопкой, так и работает ИИ. Панели взаимно исключаются: открыли одну — вторая прячется, чтобы не путаться.
Объект (одиночный) — теперь длиннее
Раньше одиночный маршрут был коротким: загрузить ТЗ → загрузить теги → выбрать сценарий → сгенерировать. Но в процессе работы над многосистемным режимом стало очевидно, что и одиночному проекту не хватает того же дисциплинирующего разбора. Поэтому перед генерацией добавились три шага:
Взаимосвязи — здесь инженер описывает зависимости и блокировки внутри самой установки (что от чего зависит, какие режимы, какие защиты).
Критические запреты — что обязательно и что запрещено (например: «запрещено пускать вентилятор при сработавшем термостате защиты от замерзания»).
Понимание системы — сводка перед генерацией: загружено ли ТЗ, есть ли теги, какой сценарий, заданы ли взаимосвязи и запреты. Инженер подтверждает — и только потом идёт генерация.
Эти взаимосвязи и запреты не остаются «для галочки»: они подмешиваются в задание для ИИ в обоих потоках генерации — и в одиночном провайдере, и в мультиагентном. ИИ получает их явным блоком, а не вынужден угадывать.
Многопроектный режим по шагам
Кнопка 🏢 Комплекс открывает расширенный маршрут. Принцип всего режима один: ИИ предлагает — инженер принимает или переписывает по-своему. Никаких «доверьтесь ИИ». Везде, где ИИ что-то решает, последнее слово — за человеком.
Шаг 1. Архив систем
На вход подаётся ZIP-архив, где папка = система. Внутри каждой папки — её ТЗ (txt/pdf) и IOLIST (csv/xlsx). Программа разбирает архив, распознаёт системы, считывает теги и определяет тип каждого канала по реальному формату IOLIST: DI/DO/AI/AO → дискретный/аналоговый вход/выход, и сразу сопоставляет с типом МЭК (BOOL/REAL) и направлением.
Откуда берётся такой аккуратный архив? Это результат предварительного этапа: моё приложение анализирует ТЗ заказчика (даже если оно написано «от руки», без внятных тегов), само разбивает объект на оборудование и формирует теги. На вход многопроектного маршрута уже приходит структурированная картина.
Шаг 2. Категории систем
В одном объекте системы относятся к разным инженерным мирам: приточка — это bms_hvac, конвейер — conveyor, водоподготовка — water_treatment, пожарная — fire_alarm. От категории зависит, какой доменный промпт получит система при генерации (в первой части я показывал, почему ПВУ и конвейер нельзя писать одним промптом).
ИИ предлагает категорию каждой системы по её имени, ТЗ и сигналам. Инженер проверяет и при необходимости меняет. Кстати, именно здесь вылез поучительный баг: приточка, в IOLIST которой есть «пожарная заслонка», поначалу классифицировалась как пожарная система. Пришлось научить классификатор не путать наличие противопожарного клапана в составе ОВ с системой пожарной сигнализации — взвешивать имя и ТЗ выше, чем пару сигналов в списке.
Шаг 3. Взаимосвязи — карта связей по всему архиву
Это сердце режима. Инженер загружает общее ТЗ взаимодействий (как всё работает в единой цепочке), и ИИ анализирует весь архив целиком — имена систем, их ТЗ и сигналы — и предлагает карту межсистемных связей: кто кому какой сигнал передаёт. Например: «Пожарная сигнализация → Центральный кондиционер П1.1: FIRE_ALARM (останов вентиляции)».
Дальше — ключевой принцип. ИИ предлагает, а инженер:
-
принимает предложенную связь как есть,
-
удаляет лишнее,
-
или дописывает свою (выбирает систему-источник, систему-потребитель и имя сигнала).
Источник предложения честно подписан: «предложено ИИ (анализ архива)» или «эвристика». Если у вас связи уже формализованы — можно ничего не принимать от ИИ и задать их руками.
Шаг 4. Критические запреты
Правила уровня всего объекта: что обязательно и что запрещено. Они подмешиваются в промпт каждой системы, чтобы ни один агент про них не «забыл». Это то место, где инженер закладывает безопасность всего объекта одним списком.
Какие системы в какой ПЛК и какой марки (ОВЕН, WAGO, CODESYS-совместимый и т.д.). Это определяет, какие POU объединяются в один проект и под какую платформу пойдёт экспорт. ИИ и здесь предлагает черновик: инженерные системы — в общий контроллер, пожарную автоматику, дымоудаление и подпор — на отдельные (безопасность принято изолировать). Инженер принимает или переопределяет — состав и марку.
Шаг 6. Понимание системы — ревью-гейт
Финальный экран перед генерацией. Программа собирает всю картину: системы и их категории, карту связей, распределение по контроллерам, список запретов — и показывает раздел «что уточнить». Здесь же работает автоматическая проверка интерфейсов: если какой-то межсистемный сигнал кто-то читает, но никто не производит (висячая ссылка), или один сигнал производят сразу несколько систем — это подсвечивается, и подтвердить понимание нельзя, пока не исправлено.
Это не «пусть ИИ угадает связи». Это «инженер явно верифицирует понимание объекта, прежде чем нажать кнопку».
Контракт интерфейсов: общий GVL и матрица блокировок
Когда понимание подтверждено, из карты связей автоматически формируется контракт интерфейсов:
-
Общий GVL межсистемных сигналов — единый список глобальных переменных с префиксом
gи автоматически выведенным типом (сигнал «Пожар» —BOOL, «температура подающей воды» —REAL). Здесь, к слову, тоже была ловушка: имяHEAT_READYпоначалу ошибочно становилосьREALиз-за подстроки. Пришлось типизировать по токенам, а не по случайному совпадению букв. -
Матрица блокировок — наглядная таблица «источник → потребитель → сигнал».
-
Контракт на каждую систему — что она читает (входы от других) и что пишет (выходы для других), под едиными именами.
Этот контракт — то самое техническое соглашение, которое раньше жило только в голове. Теперь оно явное, проверяемое и попадает в задание каждому агенту: «используй именно эти глобальные имена, не выдумывай свои».
Генерация — посистемно, теми же агентами, с аудитом и подтверждением
Здесь важный момент, на котором я в процессе сам споткнулся и переделал. Был соблазн «нагенерировать всё одним ИИ по кругу». Это неправильно: в одиночном режиме код пишут три агента с аудитом и сравнением вариантов, а инженер выбирает лучший. Многопроектный режим не должен быть слабее.
Поэтому генерация идёт посистемно через тот же штатный поток, что и в одиночном проекте:
-
Маршрут загружает входы текущей системы в рабочую область — её теги, ТЗ, блок межсистемного контракта (что читать/писать) и критические запреты, и выставляет нужную категорию.
-
Инженер запускает штатную генерацию: работают R2-PLCGen, Agents4PLC, truST Platform, идёт аудит, инженер выбирает лучший вариант — код оказывается в редакторе.
-
Инженер проверяет, при необходимости правит логику, и нажимает «Подтвердить и сохранить систему». Код этой установки сохраняется (на диск, по системе), и маршрут переходит к следующей.
Системы идут в топологическом порядке — производители сигналов раньше потребителей. Подтверждённые системы помечаются, и к их коду всегда можно вернуться — открыть в редакторе. По каждой системе подключаются и ваши загруженные библиотеки функциональных блоков, если они активны, — ровно так же, как в одиночном режиме (это серверная логика, она не зависит от режима).
То есть многопроектный режим — это не «другая программа внутри программы». Это оркестратор поверх той же проверенной одиночной генерации: он готовит контекст для каждой системы и собирает результат.
Проверка фактами: ко-симуляция всего объекта
В первой части главным принципом была «проверка фактами, а не доверие ИИ». Для одной установки это симулятор Tier S и компилятор matiec. Для объекта появляется новый уровень проверки — ко-симуляция взаимных блокировок.
Все подтверждённые системы запускаются в одном расчётном цикле, разделяя общую таблицу g-сигналов. В топологическом порядке каждой системе подаются сигналы, которые она читает, она исполняется, и сигналы, которые она пишет, собираются обратно — так производитель и потребитель связаны уже внутри одного цикла.
Дальше подаётся сценарий — например, «Пожар» — и программа показывает трассу по тактам. На реальном прогоне это выглядит так:
-
такты до пожара: приточка работает (насос включён), дымоудаление стоит;
-
такт, в котором подан пожар:
gFIRE_ALARM = TRUE→ в том же цикле приточка встаёт (насос выключен), дымоудаление запускается; -
дальше блокировка держится.
Это и есть интеграционный тест взаимосвязей. Не «ИИ так написал» и не «вроде должно работать» — а реально просчитанное поведение всего объекта на подаче аварийного сценария.
Сборка проекта: что получает инженер на выходе
Когда все системы подтверждены, нажимается «Собрать ZIP проект». В архиве:
-
папка на каждую установку — её сгенерированный код плюс исходные ТЗ и IOLIST;
-
общая папка
_PROJECT/— склеенный код всего объекта (общий GVL + все POU по порядку) и готовая пояснительная записка по ГОСТ в Word.
Записка — это не «таблицы ради таблиц», а тот же ГОСТ-документ, что формируется в одиночном режиме: с описанием состава, технических характеристик и алгоритмов, плюс раздел межсистемных связей и матрица блокировок. Системы пожарной автоматики в записке отдельно помечены как черновик, требующий проверки и сертификации — об этом ниже.
Что честно сказать про ограничения
-
Боевая генерация требует живого ИИ. Вся логика маршрута, контракта, ко-симуляции и сборки проверяется автотестами, но сам код пишет внешняя языковая модель — её итоговое качество вы проверяете на своём ключе и своём проекте.
-
Пожарные системы — это черновик. Код пожарной сигнализации, дымоудаления и подпора формируется как заготовка и обязан пройти проверку и сертификацию профильным специалистом по действующим нормам пожарной безопасности. Программа явно об этом предупреждает и в интерфейсе, и в отчёте.
-
Ко-симуляция честна ровно настолько, насколько честен код. Она доказывает блокировки при условии, что системы используют согласованные имена межсистемных сигналов, — поэтому контракт и прокидывается в задание каждому агенту.
-
Фактический импорт проекта в конкретную среду (CODESYS, e!COCKPIT и т.д.) — следующий рубеж; межсистемный обмен через GVL формируется, но финальную привязку проекта проверяет инженер.
И отдельно — про мелочь, которая на практике бесит больше всего: маршрут проекта теперь сохраняет состояние между перезагрузками страницы. Раньше случайный F5 обнулял весь прогресс; теперь системы, категории, связи, запреты, распределение и подтверждённый код подтягиваются обратно. Маленькая вещь, но именно из таких складывается доверие к инструменту.
Вопросы к сообществу
Как и в первой части, публикую до релиза ради обратной связи практиков.
-
Как вы сейчас фиксируете межсистемные блокировки на крупном объекте — есть ли у вас рабочий стандарт, или это всегда «по месту»? Подошёл бы вам формат «контракт интерфейсов» (общий GVL + матрица блокировок) как часть проектной документации?
-
Ко-симуляция взаимных блокировок на программном симуляторе — это для вас аргумент при приёмке, или заказчику нужна только проверка на железе?
-
Распределение систем по ПЛК — чаще решение проектировщика или диктуется комплектацией от вендора?
-
Маршрутные окна-чеклисты: помогает ли такая пошаговая навигация, или опытному инженеру это мешает? Где грань между «ведёт за руку» и «не путается под ногами»?
-
Какой формат вы бы хотели видеть на выходе для комплексного объекта — ZIP с папками по системам, единый проект среды, или что-то ещё?
Жду комментариев, особенно критических. Отвечу на всё.
ссылка на оригинал статьи https://habr.com/ru/articles/1045772/