Logo
Overview

Агентный пайплайн аналитика: от интервью до C4-модели одной цепочкой

November 13, 2026
10 min read

Агентный пайплайн аналитика: от интервью до C4-модели одной цепочкой

Системный анализ — это не про рисование схем и не про заполнение шаблонов ТЗ. Это про цепочку преобразований: смутные ожидания заказчика → структурированные требования → доменная модель → архитектурная схема. Каждый этап съедает часы, и на каждом этапе аналитик переключает контекст — из режима «слушаю и задаю вопросы» в режим «формализую» и потом в режим «проектирую».

Агентный пайплайн собирает эти этапы в сквозную цепочку. Не набор изолированных AI-помощников, а конвейер: один агент передаёт результат следующему, а между ними — гейты валидации, которые отбрасывают брак и отправляют на итерацию. На выходе — готовая C4-модель с уровнями Context, Container и Component плюс структурированные ADR-заметки. Всё, что обычно занимает две недели встреч и правок, ужимается в несколько прогонов за вечер.

Я собрал такой пайплайн на одном из проектов — страховая автоматизация, три стейкхолдера с противоречивыми ожиданиями. Разбираю по шагам.

Пайплайн целиком: три агента, три гейта

Сначала схема, потом детали по каждому агенту.

100%
flowchart TD
  Interview["Интервью со стейкхолдерами"] --> Transcribe["Транскрибация и структурирование"]
  Transcribe --> Agent1["Агент 1: Извлечение требований"]
  Agent1 --> Gate1{"Гейт: пропуски и противоречия?"}
  Gate1 -->|"Итерация"| Agent1
  Gate1 -->|"Принято"| Agent2["Агент 2: Доменная модель"]
  Agent2 --> Gate2{"Гейт: корректность связей?"}
  Gate2 -->|"Итерация"| Agent2
  Gate2 -->|"Принято"| Agent3["Агент 3: C4-диаграммы"]
  Agent3 --> Gate3{"Гейт: полнота уровней?"}
  Gate3 -->|"Итерация"| Agent3
  Gate3 -->|"Принято"| Output["C4 Context + Container + Component"]
  Output --> Doc["Техническая документация"]
  style Interview fill:#4a90d9,stroke:#2c5f8a,color:#fff
  style Transcribe fill:#7b68ee,stroke:#5a4db2,color:#fff
  style Agent1 fill:#50c878,stroke:#3a9a5c,color:#fff
  style Gate1 fill:#f0a500,stroke:#c88400,color:#000
  style Agent2 fill:#50c878,stroke:#3a9a5c,color:#fff
  style Gate2 fill:#f0a500,stroke:#c88400,color:#000
  style Agent3 fill:#50c878,stroke:#3a9a5c,color:#fff
  style Gate3 fill:#f0a500,stroke:#c88400,color:#000
  style Output fill:#50c878,stroke:#3a9a5c,color:#fff
  style Doc fill:#e0e0e0,stroke:#999,color:#000

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

Петли обратной связи («Итерация») возвращают результат агенту на доработку. Это не дефект проектирования, а ровно то, что происходит в голове у живого аналитика: написал → перечитал → нашёл дыру → дописал. Агенты делают то же самое, только быстрее и без кофе.

Гейты — это главное

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

Гейт — это либо ещё один вызов LLM с ролью «критика» (промпт: «Найди противоречия в этих требованиях»), либо жёсткое правило (проверка структуры JSON, наличие обязательных полей). Комбинация того и другого работает надёжнее чистого LLM-ревью: формальные проверки отсекают синтаксис, смысловые — семантику.

У меня на проекте без гейтов агенты в 3 случаях из 10 придумывали сущности, которых нет в требованиях. Просто потому, что «в страховой системе всегда есть модуль расчёта премии». С гейтами — примерно 1 случай, и тот ловится на этапе ревью модели.

Агент 1: от аудиозаписи к структурированным требованиям

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

Агент делает это за пару прогонов. Схема простая:

  • На входе: аудиозапись или текстовая расшифровка интервью (Whisper или аналог справляются с транскрибацией).
  • Промпт: «Извлеки из интервью функциональные и нефункциональные требования. Для каждого укажи: источник (стейкхолдер), тип (ФТ/НФТ), приоритет. Сгруппируй по доменным областям. Отметь противоречия — если стейкхолдер А говорит X, а стейкхолдер Б говорит Y по одному вопросу.»
  • Формат выхода: структурированный JSON. Это критично — следующий агент парсит JSON, а не свободный текст. Если агент 1 выдал «размышлизмы» вместо полей — вся цепочка ломается. Поэтому в системном промпте жёстко: «Ответ — только JSON. Без комментариев, без markdown-обёртки.»

Я долго подбирал структуру JSON. Остановился на такой:

\{
"requirements": [
\{
"id": "FR-001",
"type": "functional",
"source": "Главный андеррайтер",
"text": "Система автоматически рассчитывает базовый тариф",
"priority": "high",
"domain": "андеррайтинг",
"related_to": []
\}
],
"conflicts": [
\{
"req_a": "FR-001",
"req_b": "FR-007",
"description": "Андеррайтер хочет автоматический расчёт, compliance — ручное подтверждение"
\}
],
"missing_context": [
"Не указан SLA на расчёт тарифа"
]
\}

Если вы ещё не пробовали гонять интервью через LLM, есть смысл начать с отдельного поста про превращение интервью в структурированные требования — там про промпты и нюансы извлечения. Я здесь фокусируюсь именно на цепочке.

Первый гейт: проверяем JSON на валидность, считаем количество требований (если меньше пяти при часовом интервью — агент схалтурил), сравниваем список стейкхолдеров в источнике со списком участников интервью (все ли услышаны?). Если гейт не прошёл — дорабатываем промпт и запускаем агента заново.

Агент 2: доменная модель из требований

Когда список требований готов, второй агент строит доменную модель. Это уже не линейный текст, а граф: сущности предметной области, их атрибуты и связи.

Промпт агенту выглядит так:

Построй доменную модель на основе требований.
Выдели:
- Сущности (Entities) и их атрибуты
- Value Objects (неизменяемые объекты-значения)
- Агрегаты (группы сущностей с общим корнем)
- Связи между сущностями (один-ко-многим, многие-ко-многим)
- Бизнес-инварианты (правила, которые не могут быть нарушены)
Для каждой сущности укажи, из какого требования она следует (ID из FR-NNN).
Формат ответа: JSON.

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

Пример выхода агента (кусок JSON):

\{
"entities": [
\{
"name": "Договор страхования",
"type": "aggregate_root",
"attributes": ["номер", "дата_начала", "дата_окончания", "статус"],
"from_requirements": ["FR-001", "FR-003", "FR-012"],
"invariants": ["Дата окончания > дата начала"]
\}
],
"value_objects": [
\{
"name": "Страховая сумма",
"attributes": ["валюта", "значение"],
"from_requirements": ["FR-004"]
\}
],
"relationships": [
\{
"from": "Договор страхования",
"to": "Клиент",
"type": "many-to-one",
"description": "Договор привязан к одному клиенту"
\}
]
\}

Агрегаты агент выделяет сам — по косвенным признакам в требованиях (транзакционная целостность, ссылочная целостность). Это не всегда точно, поэтому после второго гейта я обычно прогоняю модель глазами. Но 70% времени агент попадает правильно — для стартового наброска более чем достаточно.

Агент 3: от доменной модели к C4-диаграммам

Третий агент берёт доменную модель и строит C4: уровни Context, Container и Component. Это переход от «что система делает» к «как она устроена».

Промпт — самый объёмный из трёх:

Построй C4-модель на основе доменной модели.
Уровень 1 — Context:
- Система как «чёрный ящик» в окружении пользователей и внешних систем.
- Для каждого внешнего актора — тип (пользователь/система) и характер взаимодействия.
Уровень 2 — Container:
- Разбей систему на контейнеры (сервисы, БД, очереди, файловые хранилища).
- Для каждого контейнера — технологический стек и зона ответственности.
Уровень 3 — Component:
- Для каждого контейнера — ключевые компоненты и их интерфейсы.
Формат: JSON с полным описанием каждого уровня + Mermaid-код для каждой диаграммы.

Mermaid-код, который генерирует агент, я валидирую отдельным шагом — прогоняю через Mermaid-рендерер. Если синтаксис ломается — фидбек агенту с текстом ошибки. Обычно хватает одной итерации.

Что агент делает хорошо: связывает сущности из доменной модели с компонентами на уровне Component. Правило «одна Bounded Context → один контейнер» он держит стабильно. Что делает плохо: путает синхронные и асинхронные связи между контейнерами. Если в требованиях нет явного упоминания «событие» или «асинхронно» — агент по умолчанию рисует REST-вызовы. Я добавляю в промпт отдельную инструкцию: «Связи между контейнерами разных bounded context — по умолчанию асинхронные, через брокер сообщений». Помогает в 80% случаев.

Третий гейт проверяет полноту: все ли сущности доменной модели покрыты на уровне Component? Не появилось ли контейнеров, которых нет в модели? Соответствует ли количество внешних систем списку интеграций из требований?

Оркестрация: как агенты передают друг другу данные

Протокол передачи между агентами — JSON фиксированной схемы. Никакого свободного текста, никаких «резюме» на естественном языке. Почему:

  • Агент 1 передаёт агенту 2 требования → второй парсит их как структуру, а не интерпретирует текст. Интерпретация текста на каждом шаге накапливает ошибки, как испорченный телефон.
  • Гейты между агентами проверяют не «похоже ли это на правду», а конкретные поля: количество требований, покрытие ID, наличие обязательных атрибутов.
  • Если агент 3 сломался, я могу перезапустить только его — на вход подать доменную модель из кэша, а не гонять всю цепочку заново.

Это банальная вещь — разделение контрактов данных, — которую в распределённых системах знают все. Но в LLM-пайплайнах почему-то часто игнорируют и пытаются гонять промпты с «вот тебе весь предыдущий вывод, продолжай». Не надо так. JSON-контракты между агентами — ровно то, что превращает набор чат-ботов в работающий конвейер.

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

Про оркестрацию нескольких агентов в общем случае есть подробный разбор — мультиагентные системы: оркестрация нескольких AI-агентов. Здесь я показываю конкретный прикладной пайплайн.

Что идёт не так: грабли, на которые я наступил

Агент 1 любит придумывать требования. Особенно если в интервью есть фраза вроде «ну, стандартный набор функций». LLM додумывает этот «стандартный набор» исходя из обучающей выборки — вставляет авторизацию, ролевую модель, аудит. Гейт этого не ловит, потому что JSON валидный и количество требований нормальное. Лечится дополнительным промптом: «Включай только требования, явно упомянутые в интервью». Не помогает на 100%, но снижает частоту.

Доменная модель расползается. Агент 2 иногда плодит сущности-дубликаты с чуть разными названиями: «Клиент» и «Страхователь» как две разные сущности, хотя по контексту это одно лицо. Гейт сравнивает названия по нечёткому совпадению (fuzzy string matching) и подсвечивает подозрительные пары. Работает костыльно, но лучше, чем ничего.

C4-уровни путаются. Агент 3 может утащить базу данных на уровень Context или нарисовать внешний API на уровне Component. Это не ошибка синтаксиса Mermaid, это ошибка семантики уровней. Лечится перекрёстной проверкой: после генерации C4 я прошу того же агента (с другим промптом — роль «архитектор-рецензент») проверить, что каждый элемент находится на своём уровне. Цитирую критерии: «Context — только система и внешние акторы. Container — только исполняемые/хранимые единицы. Без компонентов и классов на этих уровнях».

Контекст интервью теряется к третьему агенту. Даже при JSON-контрактах информация сжимается. Живой аналитик помнит интонацию стейкхолдера: «вот это критично, а это — “хорошо бы”». Агент эту интонацию теряет на этапе формализации. Решение: в JSON от агента 1 добавляю поле stakeholder_emphasis («настойчивость заявления» — субъективная оценка по шкале 1–3). Агент 3 учитывает это при приоритизации связей на C4.

Когда это окупается, а когда — нет

Пайплайн имеет смысл, когда:

  • Проект проходит фазу discovery: несколько стейкхолдеров, с десяток интервью, объёмная предметная область. Ручная обработка займёт недели, агенты справляются за день-два.
  • Нужна быстрая итерация архитектурных гипотез: «а что если выделить расчёт тарифов в отдельный сервис?» — перегнать изменённую доменную модель через агента 3 и получить обновлённую C4 за 10 минут.
  • Вы работаете в домене с устоявшейся терминологией (банки, страхование, e-commerce). LLM понимает контекст и реже галлюцинирует.

Не окупается:

  • Когда требований — пять штук, система — один сервис с CRUD. Пайплайн из трёх агентов тут избыточен и только создаёт иллюзию работы.
  • Когда предметная область узкоспециальная и терминология не встречается в обучающей выборке LLM. Агенты будут путаться, а вы потратите больше времени на правки, чем на ручное проектирование.
  • Когда вам нужен продакшен-уровень без ручного ревью. Такого пока нет ни у кого — LLM ошибается, и архитектурные решения без проверки живым архитектором выкатывать нельзя.

Что в итоге

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

На моём проекте пайплайн сократил фазу discovery с трёх недель до четырёх дней. Три дня — автоматические прогоны и итерации. Один день — ручное ревью и финализация. Я не жму «сгенерировать и забыть» — я жму «сгенерировать, проверить, поправить и подписать».

Попробуйте собрать такой конвейер на следующем проекте. Начните с двух агентов (требования → доменная модель) и одного гейта. Когда заработает — добавляйте третий. За один вечер не соберёте, но за два — вполне.