Всем привет! Меня зовут Дмитрий Воронцов и я хочу кратко рассказать о своей новой low-code платформе NodaLogic, построении решений с помощью узлов(нодов) и свое видение будущего. Я автор мобильного фреймворка SimpleUI, которому скоро исполняется 7 лет. В этой статье будут некоторые пересечения с ним – я хочу рассказать, зачем сделал отдельную архитектуру, а не стал продолжать SimpleUI.

7 лет назад, когда я начинал Simple я хотел сделать LowCode фреймворк на котором разработчик может быстро разработать мобильное решение, как дополнение к своей учетной системе. Тогда еще не было LLM.  Но ориентиры во все времена одинаковые – чтобы решение было легко поддерживать и развивать, масштабировать – оно должно быть простым, компактным, читаемым. Объем кода может быть и не точный показатель, но когда на один и тот же функционал требуется в 10 (а то и в 100) раз больше/меньше строчек это сигнал. Этот ориентир у меня остался и для новой системы, как важнейший. Ведь не важно, что теперь разработчику не нужно писать, но ему нужно «читать решение», анализировать что ему нагенерила  нейросеть, чтобы направлять ее. И понятно, что можно взять любой стек и язык программирования и сгенерировать решение на нем, но будет ли при этом достигнут тот уровень простоты и читаемости как в LowCode фреймворке? Фреймворк, каким бы он ни был задает структуру - раскладывает все по полочкам, без него большой проект превращается в хаос.

Платформа позволяет делать клиент-серверные решения с мобильными самостоятельными оффлайн/онлайн фронтами-приложениями (Android) веб-клиентами и серверами. Естественно, единая семантика на веб и на мобильную платформу. Также можно делать и чисто мобильные фронты, мобильные приложения без сервера.  

Можно сказать что это документно-ориентированная система с бизнес-логикой, но при этом и процессно-ориентированная.

Применение

NodaLogic – это LowCode-фреймворк (а не NoCode) – решения на нем («конфигурации») – это JSON + обработчики (на Python и/или собственном скриптовом языке NodaScript), полностью открытые, в том плане что формы, механизмы – это код, который можно пощупать. Несмотря на то, что может быть облачным решением, сервер можно скачать с GitHub и развернуть у себя, не беспокоясь о надежности и защищенности. И само проектирование можно делать как в облачном конструкторе N-Maker https://nmaker.pw/ (и там же разворачивать решение, т.е. создать конфигурацию, засунуть туда свои данные, подключиться к АПИ, подключить устройства) , а можно развернуть конструктор у себя. Для конфигуратора тоже имеет смысл скачать локально если планируется работать с LLM.

Решения на NodaLogic могут быть на подхвате у больших учетных систем, Erp-систем и т.д. для того чтобы вынести слой бизнес-логики, связанный с устройствами, с высокой нагрузкой – во внешнюю систему, для того чтобы получить отказоустойчивый высоконагруженный фронт, не зависящий от каналов связи. Это база для построения WMS-систем, TMS, MES и других систем где есть работа с мобильными рабочими местами, оборудованием, штрихкодированием. И также можно использовать как базу для построения учетных систем. В перспективе планируется использовать это для симуляций и моделирования бизнес процессов, расчетов в разных сценариях, принцип сети узлов подходит для этого (подробнее об этом написано ниже). Но это в перспективе, а сейчас эта просто базовая документно-ориентированная платформа на которой можно вести учет и планирование с мобильными и веб- рабочими местами.

 

Возможные варианты встраивания NodaLogic
Возможные варианты встраивания NodaLogic

Например, возможен сценарий примерно такой – внешняя система отсылает/обновляет свои справочники на сервер, периодически отсылает документы-задания в ответ получает статусы о выполнении, собранные данные и все что ей нужно. На стороне NodaLogic в этом время может происходить следующее – сервер(сервер состоит из узлов и тут нужно читать как «узлы сервера получают…») получает документы, нарезает детальные задачи-узлы (как правила с подзадачами – подчиненными узлами) и отправляет это на устройства через механизм «комнат» (по сути, WebSocket-чаты) , узлы попадают на устройство и работают автономно (узлы – и хранение и выполнение) , собирают данные в себя, при необходимости порождают новые узлы и по мере надобности либо связываются со своей «серверной копией» и обращаются к ее методам либо просто целиком обновляют себя на сервере. При этом можно работать через веб-клиенты, в Android-приложении и обращаться через API

Но это необязательный сценарий - сервера может не быть вообще

  • Клиенты могут не хранить данные а работать онлайн

  • Клиенты могут хранить данные (в узлах/в SQL/NoSQL -на выбор) но общаться с внешней системой, минуя сервер

  • Клиенты могут хранить данные (в узлах/в SQL/NoSQL -на выбор) но общаться с внешней системой, минуя сервер

Как видите диапазон широк.

Файлы «все в одном»

Надо сказать, что клиент-серверная работа, сеть узлов, документно-ориентированная система это не все сценарии применения. Ввиду того что конфигурации – это JSON файл, мер по постоянному упрощению и отказу от обработчиков там. Где они не нужны, скриптовому языку, который позволяет не тащить пайтон в конфу если он не нужен в NL будет доступен еще один формат, который был в SimpleUI (в статье опиан как suip-файлы)  - формат когда данные, формы и скрипты упакованы в один файл. Его можно передавать по люым каналам связи и работать примерено так же как с файлом Excel с макросами – только со всеми UI/UX плюшками. Это хорошо проявило себя в Simple в районах, где нет интернета (сейчас это становится более актуально), а сейчас в NL это будет на еще лучшем технологическом уровне благодаря вышеописанным мерам. Т.е. файлы будут меньше, работать они будут быстрее, поскольку файлы – узлы, то можно ссылаться на другие файлы. Также, в систему будет встроен мессенджер и p-2-p шифрование, и идея подобных файлов «все свое ношу с собой» в принципе хорошо ложиться на идею сообщений-процессов, с активным фронтом, но без необходимости наличия нужной конфигурации у получателей и доступа к вашей системе.

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

Логика решений

В основе решений лежит принцип узла (нода). Это одновременно хранилище (по сути JSON NoSQL) и объект класса с методами и свойствами и API для доступа извне.  Узлы – это и бизнес-сущности (задачи, документы, строки документов, склады, сотрудники и т.д.) и вспомогательные сущности (хранилище учетных данных, процессы). Можно сказать что узел это обычный класс с постоянным хранением и можно сказать что узел – это NoSQL-объект со ссылкой на класс (свойство class) с методами. И то и то будет верно. Мне больше нравится сравнение с нейроном:  В UI/UX узел имеет рецепторы (подписки на события системы и действия других узлов), методы(алгоритмы узла) и внутренне состояние (свойство data в котором хранятся и оперативные и  долговременные данные узла. Узел может обращаться к другим узлам – локальным и на серверах, обращаясь к их методам (для обращения к серверным методам существует обертка RemoteClass вокруг API которая позволяет работать с удаленным узлом как с локальным). Таким образом, решение получается как «сеть узлов»

Да, и надо сказать что как только в конфигурации объявляется класс узла это автоматически порождает API – к такому классу можно обратиться извне. Причем если узел находится на мобильных устройствах – тоже, через rooms.

Бизнес-логика формируется перед записью/при записи узла, при этом узел обращается к другим узлам, формирует новые узлы, вызывает их методы и т.д. Также узел может хранить транзакции и балансы. «Транзакция суммы» и «Транзакция состояния» - что-то наподобие «мини блокчейна», хранящего цепочку транзакций в узле и вычисленный итог, который формируют транзакции. Каждая новая транзакция меняет итог и прописывается в цепочки со своим хешем. В результате в узле хранятся итоги (суммовые или «срез последних») и та цепочка транзакций, которая привела к этому итогу, в защищенном неизменяемом виде. Т.е. например в ячейке склада можно хранить остатки в этой ячейке и всю цепочку которая этот остаток сформировала.  В NL есть разные подходы к транзакциям и балансам в т.ч. идемпотентные и наоборот, существующие на разные периоды (например для моделирования в будущем)

Структура против кодовой базы

Как и в Simple основное усилие делается на минимизации кодовой базы (как и положено LowCode) за счет поиска наиболее удобных семантик и механизмов описания интерфейса, логики, UX. Структурирование проекта в классах/узлах дает читаемость и облегчает поддержку. Собственно, ориентация на LLM-генерацию состоит в нескольких принципах или «направлениях»

  • уменьшение правил (буквально объем документации или объем контекста) для достижения функционала

  • уменьшение кода решений (буквально кода обработчиков, либо где возможно – избавление от обработчиков)

  • уменьшение кода решений (буквально кода обработчиков, либо где возможно – избавление от обработчиков)

Эта работа перманентная, можно сказать постоянно можно что-то улучшать. Например, недавно я задумался, можно ли вообще избавиться от обработчиков для интерфейса в простых случаях таких как «организация табличной части» (табличные части в узле в NL можно организовать просто массивом объектов в узле, ссылками на другие узлы-строки и механизмом подчиненных узлов) и добавил механизм «виртуального узла» без потери гибкости для разработчика. Можно посмотреть тут:

Обработчики и языки

Обработчики выполняются на сервере (для серверной логики и веб-клиентов)  и локально на мобильной платформе. Система event-driven, на события подписывается конструкция из синхронных или асинхронных обработчиков.

  • Основные обработчики на Python везде

  • Таже можно использовать собственный скриптовый язык NodaScript для фронтовых целей. Описан в этой статье: https://infostart.ru/1c/articles/2635403/

  • Ну и если говорить об интерфейсе, то проводится большая оптимизация по отказу от обработчиков, чтобы заменить где можно это разметкой и упрощающими механизмами https://nodalogic-txt-ru.readthedocs.io/ru/latest/simplify.html

Пример NodaScript "в стиле 1С"
Пример NodaScript "в стиле 1С"

Разметка на клиентах, события, UI/UX –элементы

Примеры на Android
Примеры на Android
Примеры на web-клиенте
Примеры на web-клиенте

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

А вот так выглядит типичная разметка экрана и "помощник" для упрощенной разметки

Пример "упрощенной разметки"
Пример "упрощенной разметки"
Работа с интерфейсом
Работа с интерфейсом

А вот так выглядит работа с событиями: создали диалог ввода и подписали на него событие, ловим в обработчике и что то показываем в ответ – новый экран, диалог и т.д. На событие можно подписать несколько обработчиков, которые работают синхронно, асинхронно или с «прогрессбаром»

Подписки на события
Подписки на события

К условному экрану можно подключить оборудование, камеру, штрихкодирование камерой. Скоро с SimpleUI переедет ActiveCV. Писал о ней тут: https://habr.com/ru/articles/874560/

На клиенте теперь выполняется одновременно несколько конфигураций, существует это в разделах. Т.е. у клиента есть "репозиторий", который хранит установленные конфигурации. На веб- тоже самое

Еще экраны с Android
Еще экраны с Android

AI-генерация и перспективы.

Итак, я изначально задумывал архитектуру, заточенную на 2 вещи:

  1. Она должна быть максимально удобна для LLM. Ее должна понимать даже слабая модель и уметь на ней генерить решение без галлюцинаций и желательно выдавать результат без ошибок с первого раза.

    1.1 Решение должно быть полным – т.е. и UI/UX, формы и бекенд/бизнес-логика. А не только обработчики например

    1.2 Язык программирования должен быть популярным. Сейчас в NodaLogic -Python и NodaScript который содержит 2 лексера – «от 1С» и «от JavaScript»

    1.3 Сама документация для LLM (в проекте есть такое понятие как «документация для LLM», помимо обычной) должна быть краткой, чтобы вместиться в контекст и однозначной.

  2. Решение должно быть максимально простым для понимания разработчиками и даже бизнес-консультантами. Потому сгенерировать решение можно на чем угодно, а вот разбираться с проектом может быть тяжело. Большие решения быстро разрастаются, становятся неподдерживаемыми и схлопываются под собственной сложностью

    При этом:

    2.1  Не «коробка» с галками и полностью закрытая. Все решение на коде, все открыто, но кода мало – это ведь LowCode всё-таки.

    2.2  Единый принцип – и клиент и сервер(сервера) делаются из одних кирпичиков – узлов, отсюда и название.

    2.3  Единый стек и семантика для фронтенда и бекенда.

Пример генерации
Пример генерации
... и корректировка решения
... и корректировка решения

Генерация удобно встроена в N-Maker – по сути любое решение можно создать промптами и уточняющими промптами без вмешательства в код. Для этого использован довольно простой принцип: промпт объединяется со специальным файлом документации LLM.txt с этого репозитория (кстати, этот файл рассчитан на постоянное обогащение опытом по результатам вайбкодинга , коммиты приветствуются!) и текущей конфигурации и отсылается LLM. Далее ответ валидируется на соответствие NodaLogic, при необходимости отсылается на доработку автоматически и если все в порядке то решение встраивается в конфигурацию автоматически и его тут же можно посмотреть в действии.

Посмотреть что получилось и как это работает можно в этом видео: https://youtu.be/JWQ1LIt2ZIA

В рамках развития системы я постоянно иду по пути оптимизации и упрощения решений. К слову сказать , что пример, в видео выше, уже можно не делать так, как показано в видео – т.е. можно не напрягать генератор, а сделать проще (и LLM.txt об этом уже знает)

Вот так будет выглядеть разработка в N-Reactor
Вот так будет выглядеть разработка в N-Reactor

На самом деле, с разработкой решений и генерацией все еще интереснее. То что сейчас есть – это базовый уровень – т.е. документы-узлы, какие- то интерфейсы, хранение, синхронизация, бизнес-логика. Это все разрабатывается в конструкторе N-Maker и в целом это позволяет делать любые решения, да.

Но если говорить о действительно сложных решениях, уровня ERP, цифровых двойниках,  моделирующих системах, то на таком низком уровне разрабатывать решения, имеющий сотни классов и изощренную логику взаимодействия очень сложно. Для этого как «надстройку» я разрабатываю еще одну систему N-Reactor – систему для проектирования прикладных решений с широким использованием на разных уровнях AI-агентов.

О ней будет отдельный пост, сейчас писать рано, можно посмотреть скрины. Могу в качестве анонса указать несколько тезисов N-Reactor

  • Графическое создание/моделирование процессов, в т.ч. с анимацией

  • Использование AI на разных уровнях – для создания общей логики, взаимодействий узлов, прописывание конкретных узлов, наполнение системы данными

  • Использования сети узлов в качестве симуляции бизнес-процессов с отслеживанием показателей т.е. построение моделирующего двойника предприятия

  • Это не альтернатива, а скорее дополнение конфигуратора N-maker. Решение создается на концептуальном уровне в N-Reactor и потом дополняется на уровне допустим каких то хитрых интерфейсов в N-Maker

Еще N-Reactor
Еще N-Reactor

Компоненты системы и лицензии

N-maker – облачный конструктор и хостинг конфигураций. Можно скачать с GitHub и работать с ним локально. Написан на Python/Flask. Код открыт, GPL-3.0.

NodaLogic server – тут живут узлы и выполнятся серверная бизнес-логика, если таковая имеется. Написан на Python/Flask. Код открыт, GPL-3.0.

С ним совместно:

NodaLogic web клиенты – клиентская часть. Клиенты чисто онлайн. Выполняют ту же логику работы с узлами что и мобильный клиент. Написан на Python/Flask. Код открыт, GPL-3.0.

WebSocket – сервер (“Rooms”)  - для кеширования, передачи данных на устройства. Гарантирует доставку данных. Возможно эта часть в будущем будет переписана на Go, для разработчика все останется как есть.

Приложение NodaLogic на Android. Мобильная платформа с локальным хранением и выполнением узлов. Написана на Java (по определенным причинам). Бесплатно. Код не открыт.

N-Reactor – с него могут начинаться большие проекты, при необходимости совместно с ним можно работать на конфигурацией в N-Maker. Планируется в виде облака с подпиской.

Ссылки

GitHub, чтобы развернуть локально (конструктор+сервер+веб-клиенты): https://github.com/dvdocumentation/nodalogic

Облако, с тем же функционалом, чтобы попробовать сразу (конструктор+сервер+веб-клиенты): https://nmaker.pw/

ТГ-канал платформы: https://t.me/thinknodes_ru

Приложение в GooglePlay (мобильная платформа): https://play.google.com/store/apps/details?id=com.dv.noda и RuStore: https://www.rustore.ru/catalog/app/com.dv.noda