PLC AI Studio, часть 2: многопроектный режим и маршрутные окна — как провести ИИ через целый объект

от автора

Дисклеймер: Это продолжение первой статьи про 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 из-за подстроки. Пришлось типизировать по токенам, а не по случайному совпадению букв.

  • Матрица блокировок — наглядная таблица «источник → потребитель → сигнал».

  • Контракт на каждую систему — что она читает (входы от других) и что пишет (выходы для других), под едиными именами.

Этот контракт — то самое техническое соглашение, которое раньше жило только в голове. Теперь оно явное, проверяемое и попадает в задание каждому агенту: «используй именно эти глобальные имена, не выдумывай свои».

Генерация — посистемно, теми же агентами, с аудитом и подтверждением

Здесь важный момент, на котором я в процессе сам споткнулся и переделал. Был соблазн «нагенерировать всё одним ИИ по кругу». Это неправильно: в одиночном режиме код пишут три агента с аудитом и сравнением вариантов, а инженер выбирает лучший. Многопроектный режим не должен быть слабее.

Генерация и проверка

Генерация и проверка

Поэтому генерация идёт посистемно через тот же штатный поток, что и в одиночном проекте:

  1. Маршрут загружает входы текущей системы в рабочую область — её теги, ТЗ, блок межсистемного контракта (что читать/писать) и критические запреты, и выставляет нужную категорию.

  2. Инженер запускает штатную генерацию: работают R2-PLCGen, Agents4PLC, truST Platform, идёт аудит, инженер выбирает лучший вариант — код оказывается в редакторе.

  3. Инженер проверяет, при необходимости правит логику, и нажимает «Подтвердить и сохранить систему». Код этой установки сохраняется (на диск, по системе), и маршрут переходит к следующей.

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

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

Проверка фактами: ко-симуляция всего объекта

В первой части главным принципом была «проверка фактами, а не доверие ИИ». Для одной установки это симулятор Tier S и компилятор matiec. Для объекта появляется новый уровень проверки — ко-симуляция взаимных блокировок.

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

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

  • такты до пожара: приточка работает (насос включён), дымоудаление стоит;

  • такт, в котором подан пожар: gFIRE_ALARM = TRUE → в том же цикле приточка встаёт (насос выключен), дымоудаление запускается;

  • дальше блокировка держится.

Это и есть интеграционный тест взаимосвязей. Не «ИИ так написал» и не «вроде должно работать» — а реально просчитанное поведение всего объекта на подаче аварийного сценария.

Сборка проекта: что получает инженер на выходе

Когда все системы подтверждены, нажимается «Собрать ZIP проект». В архиве:

  • папка на каждую установку — её сгенерированный код плюс исходные ТЗ и IOLIST;

  • общая папка _PROJECT/ — склеенный код всего объекта (общий GVL + все POU по порядку) и готовая пояснительная записка по ГОСТ в Word.

ZIP Архив

ZIP Архив
Отдельная папка установки

Отдельная папка установки

Записка — это не «таблицы ради таблиц», а тот же ГОСТ-документ, что формируется в одиночном режиме: с описанием состава, технических характеристик и алгоритмов, плюс раздел межсистемных связей и матрица блокировок. Системы пожарной автоматики в записке отдельно помечены как черновик, требующий проверки и сертификации — об этом ниже.

Что честно сказать про ограничения

  • Боевая генерация требует живого ИИ. Вся логика маршрута, контракта, ко-симуляции и сборки проверяется автотестами, но сам код пишет внешняя языковая модель — её итоговое качество вы проверяете на своём ключе и своём проекте.

  • Пожарные системы — это черновик. Код пожарной сигнализации, дымоудаления и подпора формируется как заготовка и обязан пройти проверку и сертификацию профильным специалистом по действующим нормам пожарной безопасности. Программа явно об этом предупреждает и в интерфейсе, и в отчёте.

  • Ко-симуляция честна ровно настолько, насколько честен код. Она доказывает блокировки при условии, что системы используют согласованные имена межсистемных сигналов, — поэтому контракт и прокидывается в задание каждому агенту.

  • Фактический импорт проекта в конкретную среду (CODESYS, e!COCKPIT и т.д.) — следующий рубеж; межсистемный обмен через GVL формируется, но финальную привязку проекта проверяет инженер.

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

Вопросы к сообществу

Как и в первой части, публикую до релиза ради обратной связи практиков.

  • Как вы сейчас фиксируете межсистемные блокировки на крупном объекте — есть ли у вас рабочий стандарт, или это всегда «по месту»? Подошёл бы вам формат «контракт интерфейсов» (общий GVL + матрица блокировок) как часть проектной документации?

  • Ко-симуляция взаимных блокировок на программном симуляторе — это для вас аргумент при приёмке, или заказчику нужна только проверка на железе?

  • Распределение систем по ПЛК — чаще решение проектировщика или диктуется комплектацией от вендора?

  • Маршрутные окна-чеклисты: помогает ли такая пошаговая навигация, или опытному инженеру это мешает? Где грань между «ведёт за руку» и «не путается под ногами»?

  • Какой формат вы бы хотели видеть на выходе для комплексного объекта — ZIP с папками по системам, единый проект среды, или что-то ещё?

Жду комментариев, особенно критических. Отвечу на всё.

ссылка на оригинал статьи https://habr.com/ru/articles/1045772/