C4 + Structurizr: как удержать ИИ-код от превращения в спагетти

· ·

C4 + Structurizr: как удержать ИИ-код от превращения в спагетти

PrimeCoder · 2026 · формат: tech

Разбор новинки простыми словами: что это, кому нужно и брать ли.

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

Связанные услуги: каталог, AI Boost Team, стать клиентом.

Спагетти вырастает за две недели, а не за два года

Инженерная лаборатория «Микрофабрика» (на Хабре — ZloAlien) выложила разбор того, как команда вытаскивает себя из «ИИ-спагетти». Материал — 9 минут чтения, 710 читателей на момент выгрузки. Интересен он не тем, что кто-то снова пожаловался на качество генерации кода. Интересен он тем, что предложен рабочий контур: описание архитектуры в C4 Model через Structurizr DSL, файл workspace.dsl в каталоге docs/architecture/, рендер диаграмм и экспорт в Mermaid для GitHub.

Команда пишет код в связке с ИИ: DeepSeek Harness и OpenCode, модель Kimi K2.7 Code через провайдеров. Скорость выросла в разы. Вместе с ней вырос и техдолг — только заметили это не сразу, а через несколько недель.

ИИ пишет код быстро, но превращает архитектуру в лапшу за недели.

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

Причина одна. У агента нет структурированного представления об архитектуре.

Весь код в контекст не спасает

Первое возражение звучит логично: дайте модели весь проект в контекст, и вопрос закрыт. Не закрыт. Контекст ограничен, между сессиями памяти нет. И главное — объём не равен пониманию.

ИИ видит функции и классы, но не видит, кто за что отвечает и где границы модулей.

Он читает текст, а не карту. Структура — отдельное представление, и его надо отдать явно.

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

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

Почему блоки и стрелочки не выиграли

Дальше напрашивается ход: раз архитектор рисует квадратики со стрелками, давайте и код писать квадратиками. Идея не нова. Блок-схемы, Visual Basic, LabVIEW, Simulink, Scratch, потом low-code и no-code. Список длинный, результат одинаковый — как способ писать код графика проиграла.

Дело не в том, что человек не воспринимает двумерность. Люди прекрасно читают схемы метро и чертежи. Дело в природе графа.

У текста есть тотальный порядок: символы идут друг за другом, и это единственно возможная форма записи. У графа порядок частичный: узлы и рёбра, а раскладок одного и того же графа бесконечно много, и ни одну нельзя объявить канонической. Отсюда практические последствия, которые бьют по команде каждый день.

  • Diff. Добавил строку — увидел зелёную. Убрал — красную. В графе вставка узла требует переукладки, и на картинке едут чужие блоки.
  • Merge. Два разработчика правят текст — конфликт решается построчно. Два разработчика правят граф — конфликт решается глазами и нервами.
  • Поиск и рефакторинг. По тексту работают grep и автоматика. По картинке — нет.
  • Логика. Цикл, условие, рекурсия, generics словами записываются компактнее и точнее. Одна строка кода против трёх узлов и обратной связи.

Плюс смешение семантики и расположения. В большинстве визуальных редакторов граф и его координаты лежат в одном файле. Поправил одну связь — поехала вся картинка, а diff показывает мусор вместо смысла.

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

Четыре уровня, чтобы не утонуть

C4 Model — методология описания архитектуры от Саймона Брауна. Название расшифровывается как четыре уровня: Context, Containers, Components, Code. Вместо одной гигантской диаграммы на всю систему — четыре разреза, каждый под свою аудиторию и свою задачу.

УровеньЧто показываетКому смотретьКак часто трогать
C1 ContextПользователи системы и внешние системы, с которыми она общаетсяЗаказчик, продукт, новый разработчикРедко, при выходе на новый контур
C2 ContainersКрупные «коробки»: бэкенд, фронтенд, база, кэш, внешние APIАрхитектор, тимлидПри архитектурных решениях
C3 ComponentsБизнес-модули внутри одного контейнера и их ответственностьКоманда, ИИ-агентПри появлении нового модуля
C4 CodeКлассы и методыПочти никомуНе рисуют: источник правды — сам код

Ценность здесь не в картинках, а в самих уровнях. Они задают глубину и держат фокус. Смотришь на C3 — видишь взаимодействия компонентов внутри выбранного контейнера и их связи с внешним миром, а не компоненты всех контейнеров сразу. Для агента это ровно то, чего ему не хватало: границы и ответственность в явном виде.

Четвёртый уровень команда фактически не использует, и это правильно. Диаграммы классов устаревают быстрее, чем их успевают отрисовать.

Где Structurizr отличается от draw.io и Mermaid

Рисовать C4 можно в чём угодно. Проблема в том, что рисовалка хранит результат, а не модель. Картинка живёт отдельно от репозитория, устаревает молча и никто не замечает момента, когда она начала врать.

Structurizr устроен иначе, и это ключ ко всей истории. Описание системы пишется на DSL в файле workspace.dsl — там семантика: элементы, связи, границы. Расположение блоков на холсте хранится отдельно, в workspace.json. Смысл и координаты разведены.

Что это даёт на практике:

  • Модель лежит в Git рядом с кодом. Правки идут через обычный diff, конфликты решаются как конфликты текста.
  • Диаграммы не хранятся как картинки — они рендерятся из модели. Расхождение между описанием и картинкой исчезает по построению.
  • Экспорт в Mermaid позволяет выводить схемы прямо в GitHub, в README и в pull request. Разработчик видит карту там, где работает.
  • Один и тот же источник даёт несколько уровней — от C1 до C3, без перерисовки вручную.

Для ИИ-агента это удобно именно потому, что DSL — текст. Его можно положить в инструкции, прочитать в начале сессии, использовать как ограничение: новый модуль не создавать, если он попадает в зону ответственности существующего.

Что это дало команде

Единственная цифра эффекта в разборе — про рефакторинг.

Рефакторинг, на который мы закладывали неделю, с его помощью занял один вечер.

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

Ценность эпизода в другом. Когда структура описана явно, работа перестаёт быть разговором «а куда это положить» и становится операцией по карте. Человеку это экономит часы. Агенту это заменяет отсутствующую у него память.

Как применить у себя, без героизма

Порядок, который следует из логики разбора:

  1. C1 и C2 на одном листе. Пользователи, внешние системы, крупные коробки. Полчаса с тимлидом, без перфекционизма.
  2. Завести docs/architecture/workspace.dsl в репозитории. Не в Confluence, не в Miro. Только рядом с кодом, иначе модель умрёт.
  3. Описать C3 для самого проблемного контейнера. Не для всех сразу. Там, где агент чаще всего дублирует функции и путает ответственность.
  4. Настроить рендер и экспорт в Mermaid. Схема в pull request читается чаще, чем схема в отдельном каталоге.
  5. Прописать правило для агента. В инструкциях проекта: перед добавлением модуля сверить с картой. Без этой строчки DSL останется красивым файлом.

Отдельно про дисциплину. Модель живёт, пока её правят вместе с кодом. Появился контейнер — обновили C2. Появился модуль — обновили C3. Пропустили месяц — карта начала врать, и агент начнёт врать вместе с ней, только увереннее.

Подвохи, о которых надо сказать прямо

  • Это ещё один артефакт на поддержке. Проблема «вики устарела на три месяца» никуда не делась. Она переехала в DSL. Плюс в том, что здесь устаревание видно в diff.
  • Порог входа. Structurizr DSL — не мышкой порисовать. Первый день уйдёт на синтаксис, и это день, который никто не любит.
  • Сдерживает, не запрещает. Явная карта снижает вероятность дублирования и протечек через границы модулей. Она не отменяет ревью и не заменяет тесты. Агент по-прежнему способен «улучшить» код локально.
  • Доказательств мало. Один проект, одна команда, один эпизод с рефакторингом. Данных, по которым можно считать возврат инвестиций, в разборе нет — и придумывать их не надо.
  • Не для всех. Проект на три файла и один разработчик в этом не нуждается. C4 начинает окупаться там, где контейнеров и модулей уже столько, что их не удержать в голове.

Брать или подождать: вердикт за 30 секунд

Брать, если у вас в команде ИИ пишет код каждый день, а архитектура держится на памяти двух человек. Заведите workspace.dsl с C1 и C2, добавьте C3 для худшего контейнера, пропишите правило в инструкциях для агента. Даже это уже даёт эффект.

Подождать, если вы ещё не накопили боли. Один сервис, один разработчик, код без ИИ — заводить DSL рано. Сначала пусть появится то, что нужно держать в структуре.

Не брать как замену ревью, тестов и нормального code review. Карта архитектуры дисциплинирует агента, но не отвечает за качество кода.

FAQ

Чем Structurizr лучше Mermaid?

Mermaid — язык рендера диаграмм. Structurizr — модель: семантика в DSL, раскладка отдельно, из одной модели получаются все уровни C4. Mermaid хорош как способ показать результат в GitHub, поэтому в разборе он и используется для экспорта.

Почему не draw.io?

Потому что draw.io хранит картинку. Картинка не диффится и устаревает незаметно. Модель с текстовым описанием живёт в Git и стареет заметно.

Нужен ли четвёртый уровень C4?

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

Поможет ли это, если команда пишет без ИИ?

Поможет, но мотивация будет слабее. Основной аргумент из разбора — у агента нет своего «листочка» с архитектурой, ему карту нужно отдавать явно.

Сколько времени это занимает?

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

Что сделать на этой неделе

Откройте репозиторий и посмотрите на последние двадцать коммитов от агента. Если среди них есть две функции с одинаковым смыслом и модуль, который знает про внутренности соседнего, — проблема уже есть, просто вы её ещё не считали.

Дальше минимум: каталог docs/architecture/, файл workspace.dsl, C1 и C2, рендер и экспорт в Mermaid, строка в инструкциях для модели. Если после этого рефакторинг займёт вечер вместо недели — считайте, что инструмент окупился. Если нет — у вас появится карта, с которой можно спорить. Это уже лучше, чем лапша, в которой никто не помнит, где чей код.

Читайте также