
Я написал данную статью, чтобы поделиться опытом в применении подхода Architecture as Code в больших enterprise-компаниях, в которых есть как заказная, так и собственная разработка. Этот подход я применяю и внедряю уже несколько лет в разных телеком-компаниях. За последнее время с приходом эпохи агентной разработки (вайб-кодинга) многое поменялось. Код стал не так важен, как спецификации, а спецификации стало очень заманчиво генерировать (мне приходилось сталкиваться с аналитиками, которые не читали текст требований, который им сгенерировал ИИ). В этой статье я попытаюсь рассказать о подходе, который мы применяем, чтобы извлечь максимальную выгоду из агентной разработки и уменьшить возможное негативное влияние галлюцинаций агентов. Я буду больше писать про то, как работать с архитектурой, а не про то, как придумать правильный промпт или выбрать более умную модель (что тоже полезно).
В статье я буду много где ссылаться на конструкции из Structurizr, однако не буду его пояснять (в интернете полно ресурсов, которые отлично описывают синтаксис Structurizr).
Архитектура как код и агенты
Подход Architecture as Code существует уже лет 10: он начинался как простой механизм автоматической отрисовки диаграмм по простому коду (PlantUML, Mermaid, DBML ...) и эволюционировал до полноценного языка описания архитектуры, такого как Structurizr DSL (есть и другие нотации, например C4). Мне нравится Structurizr DSL по нескольким причинам:
Эталонная поддержка нотации моделирования C4. Собственно, язык придуман Саймоном Брауном — автором нотации C4. Так что можно быть уверенным: всё, что мы знаем о C4, мы найдём в Structurizr. Ну и сама модель C4 — удобный механизм описания структуры программного обеспечения на разных уровнях детализации: от уровня генерального директора (Context) до уровня технической поддержки (Container и Deployment).
Возможность отделения модели и представления. Стандарт ISO 42010 явно отделяет архитектуру от её представлений для нужд различных заинтересованных лиц. В Structurizr мы имеем отдельно model и отдельно механизм views, который с помощью запросов include/exclude и механизма тегов позволяет строить любые представления для решения различных задач.
Сама модель Structurizr за счёт продвижения Саймоном Брауном достаточно известна, и при поиске в команду архитектора со знанием Structurizr в 2026 году есть большая вероятность его найти. Впрочем, если вы и не знаете этот «язык», то освоить его можно часа за три (по моему опыту).
Как мы с вами знаем, код — это то, для чего созданы LLM. И если мы напишем промпт для qwen/deepseek/GLM, в котором попросим модель описать архитектуру в формате Structurizr, то результат получится вполне себе валидным. Тут, конечно, нужно дать модели пример «правильного» DSL с точки зрения вашей компании и дать механизм проверки этого DSL (на случай опечаток и галлюцинаций).
В случае, если вы используете агенты из Visual Studio Code (как это делаю я), то в качестве инструмента проверки можно использовать плагин с контролем синтаксиса языка. Лучшим, с моей точки зрения, является C4 Architecture As A Code: VARP. Среди возможностей плагина:
контроль синтаксиса языка, в том числе с поддержкой вложенности !include
отрисовка диаграмм с экспортом в SVG/drawIO
возможность генерации workspace.json прямо в редакторе (без необходимости Structurizr CLI/Lite)
Архитектурный Master Data Management (на примере BeeAtlas)

При всех своих достоинствах в экосистеме Structurizr есть один большой недостаток — отсутствие механизмов поддержки работы с архитектурным ландшафтом. Это и понятно: Саймон Браун ориентировался на продуктовые команды, работающие в стиле Agile, — код и архитектура «в одном флаконе». В корпорациях у нас есть сотни и тысячи систем, которые влияют друг на друга и только вместе могут обеспечить ценность для большой компании. Можно, конечно, сделать один большой репозиторий кода и попытаться научить работать с ним сотню команд (реально, попробуйте!), но мы придумали лучший путь — архитектурный MDM.
Его идея очень проста: давайте вести архитектуру в сотне небольших репозиториев продуктовых команд, а связку между ними сделаем с помощью обвязки инструментов. Идея взята из «обычных архитектурных практик»:
Связанность между системами на ландшафте будем поддерживать с помощью ссылок на идентификаторы систем (мы взяли коды из корпоративной CMDB-системы). Если я хочу указать на архитектуре, что вызываю систему Balance Manager (cmdb-код "bm"), то просто описываю соответствующий softwareSystem на ландшафте и указываю ему свойство (property) cmdb "bm". Теперь мы точно знаем, с какой системой я интегрирован.
При публикации системы на ландшафте будем одновременно публиковать и архитектуру в корпоративный репозиторий BeeAtlas. Таким образом, у нас будет возможность всегда иметь актуальный срез продуктивной архитектуры для целей анализа.
Добавим в репозитории возможность подгружать из других источников данные о фактическом поведении систем (с платформы наблюдаемости, интеграционной платформы ...) — это даст нам возможность давать архитекторам обратную связь о том, как реально работают архитектуры (какие работают интеграции, держат ли нагрузку сервисы и т.д.)
Добавим возможность для корпоративных архитекторов работать со сквозными процессами ландшафта и фреймворком бизнес-возможностей (TOGAF)
Проблема №1 Сложный ландшафт enterprise
В компаниях, где я работал, использовалось от тысячи до двух тысяч типов информационных систем, обеспечивающих деятельность оператора связи. Конечно, вряд ли при разработке нового приложения вам придётся интегрироваться больше, чем с десятком систем. Но вот незадача — как понять, с какими? Нам нужно описание функционала системы, интеграционных API, их нефункциональные характеристики (такие как допустимый RPS, фактический latency и декларируемый error_rate). Описание нужно вести, и по нему нужно искать. И модель C4 нам тут — не друг.
Мы придумали небольшое расширение: в C4 есть такой строительный блок, как component. В стандарте он описывается максимально туманно, по сути — это любая программная абстракция, которая нам нужна для описания структуры container. Почему бы одним из component не быть Technical Capability (в терминах TOGAF), а другим — API (в терминах интерфейсов)?
Пример описания возможности:
component "Получение баланса абонента" { description "Возможность получать информацию о балансе абонента, значениях его бонусных подбалансов и долговременных резервациях" properties { type capability # тип компонента code 001 # придумаем код возможности parents BC-011590 # сошлёмся на Business Capability, которую автоматизирует данная возможность } }
Пример описания API:
component "balance_api" { description "REST API работы с балансами абонентов" properties { type api api_url "https://someurl.ru/openapi.yaml" protocol rest "get /balance" rps=100;latency=50;error_rate=0.01;tc=001 } }
Теперь архитектор, который описывает своё приложение, может явно декларировать, что его приложение делает на ландшафте компании и как с ним интегрироваться. Данная информация агрегируется внутри BeeAtlas и доступна через его MCP Server для агентов. Т. е. мы можем попросить агента: «Перечисли API для получения баланса абонента» — и, скорее всего, получим искомый интерфейс без необходимости долгого исследования систем.
Проблема №2 Корпоративные стандарты и правила
Разработка в Enterprise отличается от стартапа тем, что даже первая версия приложения должна реализовывать большое число корпоративных стандартов (в основном в области информационной безопасности и надёжности). Стандартов может быть реально много, и только их изучение может повергнуть любого архитектора в уныние. Нам нужно решить — как понять, что нужно нашему приложению?
Воспользуемся тем, что у нас есть машиночитаемое описание архитектуры и единая точка управления архитектурой ландшафта — BeeAtlas. Заведём в ней корпоративные стандарты в виде нефункциональных требований, паттернов (и анти-паттернов) и научим MCP Server отдавать эту информацию. Мы хотим, чтобы на вопрос агенту «Какие требования нужно реализовать? Cоставь ADR по реализации требования!» мы получили адекватный текст Architecture Decision Record.
В BeeAtlas мы добавили возможность вести паттерны в привязке к нефункциональным требованиям и примерам их реализации в виде блоков кода Structurizr DSL. Например, так можно сделать паттерны интеграции с корпоративной IDP или по организации хранения данных с учётом требований критической инфраструктуры.
Проблема №3 Контроль качества созданной архитектуры

Хорошо, руками или с помощью агента у нас получилось описание архитектуры. Используя его и ещё спецификации, требования от аналитиков и ADR, мы готовы ставить задачу в команду разработки. Но всё ли мы (вместе с ИИ-агентом) учли? Этот вопрос мучает как архитектора системы, так и различный «Governance». И есть почему: исправление ошибок архитектуры на этапе проектирования — это изменение нескольких строк текста, а исправление тех же ошибок на этапе тестирования/внедрения — это дни или недели работы целой команды.
Мы сделали два вида проверок:
Автономные, которые проверяют сам файл с архитектурой — «Архитектурные фитнес-функции»
Интеграционные, которые проверяют влияние нашей архитектуры на ИТ-ландшафт компании — «Аналитика на графе»
Архитектурные фитнес-функции
Данный термин широко используется Нилом Фордом как способ проверки качества архитектуры. Термин достаточно общий и включает в себя все виды проверок (вплоть до нагрузочных тестов), которые можно применить к архитектуре. Однако в BeeAtlas мы его превратили в некоторый механизм, который проверяет полноту и непротиворечивость описания архитектуры.
Например:
все ли уровни архитектуры в модели C4 отражены?
применяются ли рекомендованные техрадаром технологии во всех контейнерах и интеграциях?
существуют ли указанные в deploymentEnvironment FQDN в CMDB?
В общем, всё, что мы можем проверить, глядя на локальный файл архитектуры, — проверяем с помощью фитнес-функций.
С точки зрения механики применения фитнес-функция — это небольшой скрипт на Python, которому на вход передаётся workspace.json в формате Structurizr, и он возвращает данные проверки по предопределённому формату. Механизм простой: написать свою фитнес-функцию, протестировать и включить в цикл проверки можно прямо на портале BeeAtlas.
Аналитика на графе архитектуры

Локальные проверки архитектуры приложения — это вещь полезная, однако при хорошем архитекторе все они не сильно-то и нужны (разобраться внутри своего продукта — в общем случае задача, решаемая внутри команды). Однако как понять, что будет, если приложение интегрировать в ландшафт? Что нарушится? Как повлияют другие системы на моё приложение?
Тут нам понадобится второй тип проверки: анализ графа ландшафта. Все архитектуры, которые делаются в компании, загружаются в большую графовую модель внутри графовой базы Neo4j. Загрузка происходит в два приёма:
Локальный граф — некоторый staging для проверок наличия антипаттернов и выявления паттернов для понимания того, какие нефункциональные требования были реализованы;
Глобальный граф — финальный граф архитектуры, который содержит «цифровой двойник» архитектуры компании и может быть использован как источник знаний в момент аварий (формирование гипотез о причине аварий на основе данных об интеграциях и deployment) или в момент планирования стратегических инициатив (например, организация георезервирования критических процессов или изоляция чувствительных контуров).
Давайте рассмотрим примеры таких проверок:
Циклические зависимости

Вы спроектировали хорошее приложение, которое требует для своей работы другое (использует его интерфейсы), оно в свою очередь использует еще одно, то еще одно и так далее. Проблема приходит в тот момент, когда в этой цепочке появляется цикл - кто-то из этих приложения вызвал обратно вас. Все выглядит незаметно, пока не пришла пора ставить обновление, которое ломает обратную совместимость интерфейсов (при интенсивном развитии - такое случается). В этот момент что бы поставить такое обновление вам нужно убедится что вся цепочка (цикл) обновился, а это значит вам нужно синхронизировать все системы в цепочке с точки зрения поставки. Это очень плохое влияние на t2m, если вообще этот фокус вам удастся.
На графе циклы обычно ищутся обходом в глубину (DFS) с раскраской вершин — белая (не посещена), серая (в стеке обхода), чёрная (обработана). Если DFS находит ребро в серую вершину, в цепочке зависимостей есть цикл; сложность O(V+E), где V — число систем, а E — число связей. Понятно, что реализовывать такие вещи на графовых базах данных уже не нужно - у нас есть Neo4J Graph Data Science DFS - который и помогает находить циклы (в принципе, можно еще поискать сильно-связанные компоненты, но это уже детали).
Единые точки отказа (SPOF)

Самая частая проблема в обеспечении доступности ландшафта - это система, от которой все зависят и которая не масштабируется. Она может выглядеть как что-то совершенно не важное, но при этом, ее отказ может быть критичным для работы систем, которые выглядят как важные. Это может быть вспомогательная система, которая хранит НСИ (например справочник валют). Но ее отказ повлияет на систему, которая осуществляет тарификацию клиентского трафика и абоненты не смогут пользоваться услугами сети (тут я сгущаю краски, конечно).
Как помогает граф: единые точки отказа находятся как точки сочленения графа — вершины, удаление которых увеличивает число компонент связности, то есть система, потеря которой «разваливает» ландшафт на изолированные части. В Neo4j в GDS (библиотека Graph Data Science) это реализованно через процедуру gds.articulationPoints.
«Божественный» объект

Антипаттерн, при котором один сервис знает обо всём: к нему сходятся связи от большинства систем ландшафта. Такой сервис становится узким местом и по нагрузке, и по эволюции — изменение его интерфейса требует согласования со всеми потребителями.
Как это работает (алгоритм): «божественный» объект выявляется центральностью по степени (degree centrality) — долей рёбер, инцидентных вершине: чем выше значение, тем больше систем зависят от сервиса. На графе это можно реализовать с помощью Neo4j GDS через gds.degree (degree centrality).
Shared Infrastructure

Антипаттерн, в котором несколько не связанных приложений размещены на одном оборудовании. Это может вызывать проблему в случае, если есть два приложения разной критичности, которые влияют на загрузку одного ресурса. Например, использование общей сети для передачи бизнес-сообщений приложения и синхронизации дисковых массивов. Или использование одного коммутатора для тестового и продуктивного контура. В этих примерах низкоприоритетные задачи могут "отнять" ресурс у высокоприоритетной задачи.
Тут нам не нужен графовый алгоритм, тут все просто: для каждого Deployment Node сравниваем множество размещённых на нём приложений — если на одном узле встречаются приложения разных продуктов или разной критичности, фиксируем антипаттерн. Проверку так же можно сделать через анализ графа (кто бы не указал в своей архитектуре размещение на определенном инфраструктурном элементе - мы все орбъеденим и проанализируем).
Итого
Чем круче становятся ИИ-агенты и чем больше кода они генерят за нас, тем важнее иметь чёткий контур архитектурного контроля. Потому что если агент нагаллюцинирует в коде — это поправимо, а если на уровне системных связей или стандартов — привет, техдолг и аварии в проде.
Суть подхода в двух вещах. Первое — единая база архитектурных знаний (например, така как BeeAtlas), куда стекаются формальные описания систем, их API, возможностей и стандартов из десятков командных репозиториев. Это не просто документация, а машиночитаемый слой, к которому могут обращаться те же агенты, чтобы не выдумывать интеграции из воздуха. Второе — двухэтапный контроль качества: сначала локальные фитнес-функции проверяют, не накосячили ли мы в рамках одного приложения, а потом графовая аналитика ищет системные проблемы вроде циклов, точек отказа или «божественных» объектов на всём ландшафте. Короче, рецепт такой: не запрещать агентам творить, а дать им жёсткие рельсы из проверенных архитектурных данных и автоматического контроля, чтобы скорость разработки не убила управляемость системы.
Благодарности
Методы графового анализа (раздел 4.2) разработаны в ВКР Почечуры Артемия Андреевича «Метод анализа архитектуры программного обеспечения на поиск уязвимостей» (МАИ, 01.04.02 «Прикладная математика и информатика», 2026).
Работа выполнена под научным руководством Булакиной Марии Борисовны; а я выступал научным консультантом при разработке методов графовой верификации и их интеграции в BeeAtlas.
Полезные ссылки
BeeAtlas FDM Infrastructure — https://github.com/tech-beeline/beeatlas-fdm-infrastructure
Structurizr DSL — https://docs.structurizr.com/dsl/tutorial
Модель C4 — https://c4model.com/
Neo4j Graph Data Science — https://neo4j.com/docs/graph-data-science/current/
Plugin C4 Architecture As A Code - https://github.com/tech-beeline/varp

