МАТЕРИАЛЫ КУРСА
СИИ • НАВИГАЦИЯ

C4: четыре уровня архитектуры

Как описывать архитектуру AI-продукта: context → container → component → code, только PlantUML, только as-code

C4: четыре уровня архитектуры

Право «нормально вертеть проект» зарабатывается пониманием архитектуры: если ты свободно переходишь между уровнями C4 — от «кто нами пользуется» до «какой модуль за что отвечает», — любое изменение проекта перестаёт быть страшным.

В 2026 у архитектуры as-code есть второй заказчик: агент. Диаграмма в PlantUML, лежащая в репозитории, — это карта проекта, которую читает и человек, и Vibe/Claude Code. Агент с актуальной container-диаграммой делает на порядок меньше архитектурного бреда.

Правила игры

  1. Только as-code. Исходник .puml лежит в docs/diagrams/, сгенерированный .svg — рядом, оба закоммичены. Figma и Miro не используются.
  2. Диаграмма отражает то, что есть, а не то, что мечталось. Разъехались — чинишь диаграмму в том же PR, что и код.
  3. Один уровень — одна диаграмма. Не смешивай контейнеры с компонентами на одной картинке: это главный источник каши.

Генерация SVG:

plantuml -tsvg docs/diagrams/*.puml

Уровень 1 — Context: система и мир

C4 Context

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

Не показываем: технологии, базы данных, внутренности.

Типичные ошибки: контейнеры на контекстной диаграмме («а вот тут у нас PostgreSQL»); забытые внешние системы (LLM-провайдер и Langfuse — тоже внешние системы); связи без подписей.

Уровень 2 — Container: из чего состоит система

C4 Container

Показываем: самостоятельно запускаемые единицы (frontend, API, БД, AI-модуль), технологию каждого, протоколы связи.

Не показываем: классы, модули, файлы — это уровень ниже.

Тест на контейнер: запускается отдельно ИЛИ хранит данные — контейнер; иначе — компонент. Контейнер ≠ Docker-контейнер (c4model.com прямо пишет «Not Docker!»): слои controller/service/repository живут в одном процессе — это компоненты; очередь и топик — контейнеры, а вот брокер целиком — нет.

Типичные ошибки: «AI» как магическое облако без границ (модель — это внешний провайдер, а AI-модуль — ваш контейнер); стрелки «все со всеми» без протоколов; больше ~20 коробок — значит, ты уже рисуешь компоненты.

Это главная диаграмма проекта — именно её проверяет aact check, и именно она нужна агенту в контексте.

Уровень 3 — Component: внутри одного контейнера

C4 Component

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

Не показываем: отдельные функции и классы.

Правило одного предложения: если обязанность компонента не описывается одним предложением без «и» — это два компонента. AI Gateway на диаграмме — осознанный паттерн: единая точка вызова модели, где живут ретраи, таймауты и лимиты токенов, а не размазанные по коду вызовы API.

Уровень 4 — Code: не рисуем

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

Процедура: от описания к модели

Порядок из скилла aact-architect — строго по шагам, не забегая вперёд:

  1. Назови систему — одна система, одна System_Boundary.
  2. Люди и внешние системы — кто пользуется (Person), от чего зависим (System_Ext: LLM-провайдер, Langfuse — тоже сюда).
  3. Запускаемые единицы и хранилища — каждая проходит тест «запускается отдельно или хранит данные».
  4. Связи — каждая с подписью что течёт и как: Rel(web, api, "fetches orders", "JSON/HTTPS"), а не Rel(web, api).
  5. Границы — только если контекстов реально больше одного.
  6. Стоп. На уровень компонентов — только когда понадобилось разобрать внутренности одного контейнера.

Связка с ADR: решение → диаграмма → цена

Каждое значимое изменение диаграммы — следствие решения, а у решения есть цена. Минимальный ADR:

# ADR-002: Выбор модели для генерации

## Решение
Используем <модель> через <провайдера>, деградация на <дешёвую модель>.

## Альтернативы
<что рассматривали и почему отказались>

## Цена решения
<какой долг берём: стоимость, привязка к провайдеру, лимиты>

ADR без заполненной «Цены решения» не проходит DoD. Диаграмма показывает «как», ADR отвечает «почему именно так и что нам это стоит».

Канонический шаблон (Status / Context / Decision / Consequences) и живые примеры решений — в ADRs репозитория aact; наша «Цена решения» — это Consequences, вынесенные в обязательное поле. Файл ADR называй по решению, а не по технологии: «Anti-corruption Layer.md», а не «Добавили Kafka.md».