DocGen: как я сделал AI-ассистента для системного аналитика и не сошёл с ума

от автора

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

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


Введение: с какой болью мы все знакомы

Если вы системный аналитик, знаете эту картину:

Стейкхолдер говорит: «Нам надо мессенджер для доставки еды». Вы задаёте уточняющий вопрос — «А кто будет доставщиками?» — получаете ответ, задаёте ещё, и ещё… Через 3 встречи у вас есть набор разрозненных заметок, которые нужно превратить в SRS.

Я столкнулся с этим на практике и подумал: а почему бы не автоматизировать? Не заменить аналитика — а дать ему инструмент, который возьмёт на себя рутину: генерацию вопросов, структуру документа, проверку на противоречия.

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

Так родился DocGen — AI-ассистент системного аналитика, который проходит через цепочку из 7 LLM-агентов, чтобы превратить «мне надо мессенджер» в готовый черновик документации.

Расскажу, как я это сделал, с какими проблемами столкнулся и что получилось.


Архитектура: почему две цепочки, а не одна

Самое первое решение — разделить процесс на две независимые цепочки.

Цепочка 1:  Контекст → Agent 0 → Agent 1 → Вопросы для интервьюЦепочка 2:  Вопросы + Ответы → Agent 2 → Agent 3 → Agent 4 → Agent 5 → Документ

Почему не всё подряд?

Первая итерация пыталась пропустить весь pipeline за один вызов. Результат был предсказуемо ужасным — LLM теряла контекст, противоречия не ловились, документ получался поверхностным.

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

Разделение на цепочки дало три преимущества:

  1. Встреча с людьми. Между цепочками стоит человеческий фактор: аналитик проводит интервью, стейкхолдеры отвечают на вопросы. Это нельзя автоматизировать — это нужно собрать.

  2. Цикл уточнений. Если Agent 4 находит противоречие в документе, система не ломается — она генерирует уточняющие вопросы, аналитик задаёт их стейкхолдерам, и pipeline Agents 2–5 запускается повторно.

  3. Разные температуры. Каждый агент решает свою задачу, и его temperature подбирается индивидуально.


Цепочка 1: от «хотелки» к плану интервью

Agent 0 — Context Quality Assessment

Первый агент — «умный фильтр». Пока LLM думает, какие вопросы задать, Agent 0 оценивает, насколько хорош входной контекст.

class Agent0Response(BaseModel):    quality: Literal["high", "medium", "low"]    reason: str    temperature_for_agent1: float  # 0.2–0.4    suggested_questions_to_ask_before_meeting: list[str]

Что он делает:

  • Оценивает, достаточно ли информации о продукте в том, что дал стейкхолдер

  • Рекомендует температуру для Agent 1: если контекст слабый — выше температура (больше креативности), если сильный — ниже (больше точности)

  • Предлагает свои вопросы, которые стоит задать до встречи

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

Пример:

Вход:

product_type = "веб-приложение"product_domain = "логистика"intentions = "Хотим отслеживать грузы"

Выход:

quality: "low"reason: "Не указан масштаб, нет информации о пользователях и интеграциях"temperature_for_agent1: 0.4suggested_questions: ["Какой масштаб системы? (SKU, отправки в день)", ...]

Тут же возникла первая проблема: LLM не всегда возвращает валидный JSON. Я добавил graceful degradation — fallback на generate + extract_json, с логированием каждого случай.

Это уже он сам догадался при разборе полетов. Может кому пригодится эта информация.

Agent 1 — Requirements Discovery

Agent 1 получает рекомендации от Agent 0 и генерирует структурированный план интервью.

class Agent1Response(BaseModel):    stakeholders: list[str]            # Product Owner, Developer, QA...    intentions: list[IntentItem]       # original_text + questions    common_questions: list[str]        # общие для всех стейкхолдеров

Что интересно: Agent 1 группирует вопросы по стейкхолдерам. Для Product Owner он спросит про бизнес-цели, для Developer — про архитектуру, для QA — про тестирование.

Категории вопросов жёстко зафиксированы через Enum:

class QuestionCategory(str, Enum):    functionality = "functionality"    non_functional = "non_functional"    integrations = "integrations"    data = "data"    constraints = "constraints"    risks = "risks"    clarification = "clarification"

Цепочка 2: от ответов к документу

После интервью у нас есть: вопросы от Agent 1 и ответы стейкхолдеров. Начинается магия.

Agent 2 — Normalization

Из «сырых» ответов стейкхолдеров Agent 2 извлекает структурированные данные:

class Agent2Response(BaseModel):    actors: list[Actor]    glossary: list[GlossaryTerm]    metrics: list[Metric]    constraints: list[Constraint]    non_functional: list[NonFunctionalReq]    functional_requirements: list[FunctionalRequirement]

Температура 0.2 — здесь важна точность извлечения, а не креативность.

Agent 3 — Draft Generation

Из структурированных данных Agent 3 генерирует Markdown-черновик документа.

Температура 0.5 — чуть выше, чтобы документ получался связным и читаемым, а не набором списков.

Agent 4 — Validation & Consistency

Самый важный агент. Он читает черновик и ищет:

class Agent4Response(BaseModel):    issues: list[Issue]  # type: contradiction | incompleteness | inconsistency    additional_questions: list[str]    is_valid: bool    summary: str

Три типа проблем:

  • contradiction — требования противоречат друг другу

  • incompleteness — что-то упущено

  • inconsistency — терминология или формулировки не согласованы

Если is_valid=False — срабатывает ClarificationOrchestrator, который генерирует уточняющие вопросы и повторяет pipeline Agents 2–5 (максимум 3 итерации).

Кстати, только из этой статьи я увидел, что было заложено три итерации. Когда при тестировании он в десятый раз начал задавать мне дополнительные вопросы я взвыл. И сделал кнопку “Пропустить валидацию”, которая запускает цепочку без вызова Агента 4.

# Псевдокод цикла уточненийfor iteration in range(3):    draft = await run_agent3(normalized_data)    validation = await run_agent4(draft, normalized_data)        if validation.is_valid:        break        # Сохраняем уточняющие вопросы в БД    clarification_questions = save_clarification_questions_to_db(validation)        # Аналитик собирает ответы → pipeline повторяется    new_answers = collect_clarification_answers(clarification_questions)    normalized_data = await run_agent2(validation_output, new_answers)

Agent 5 — Formatting & Publishing

Финальный штрих: форматирование с учётом замечаний Agent 4.

Температура 0.1 — минимум креативности, максимум точности. Документ должен быть готов к отправке.


Document Converter — когда документ готов

Agent Document Converter (фактически Agent 6) превращает финальный Markdown в нужные форматы. В версии 1.0.9 система поддерживает 8 типов документов:

SRS, Architecture (на базе C4), API Spec (OpenAPI 3.1), README, Test Plan и три вида UML-диаграмм — Use Case, Sequence и Class.

Гибридный режим: LLM + программный код

Самое интересное нововведение v1.0.9 — гибридный режим. Для трёх типов (Architecture, Class Diagram, Use Case Diagram) я добавил программные генераторы PlantUML, которые работают в паре с LLM:

  1. LLM генерирует текстовое описание диаграммы — что изображено, какие элементы и связи

  2. Программный генератор создаёт синтаксически валидный PlantUML-код на основе структурированных данных от Agent 2

Зачем? LLM отлично пишет текст, но PlantUML — формальный язык с жёстким синтаксисом. LLM может ошибиться в скобках или ключевых словах, а программный генератор гарантирует валидность.


Как это выглядит на практике

Вот типичный воркфлоу:

1. Создать проект → «CRM-система для call-центра»2. Создать встречу, запустить «Generate Questions»   → Agent 0 оценил контекст, Agent 1 сгенерировал 24 вопроса3. Провести интервью с Product Owner, Tech Lead, QA4. Запустить «Generate Document»   → Pipeline Agents 2–5, цикл уточнений (Agent 4 нашёл 3 проблемы)   → После ответов на уточнения — is_valid=True 5. Конвертировать в нужный формат одним кликом   → SRS, Architecture на C4, API Spec, README, UML-диаграммы...

Время: от намерения до SRS — 2–3 часа вместо 1–2 дней вручную.


Теперь его статья закончена, и, как говориться в одном анекдоте «А теперь слайды»

Окно проекта

Окно проекта
Вопросы

Вопросы
Выявленное. Ниже перечень функциональных, нефункциональных требований

Выявленное. Ниже перечень функциональных, нефункциональных требований
Сгенерированные документы.

Сгенерированные документы.

Далее мои уже измышления.

Создание DocGen заняло около недели итераций. Проект пока в стадии тестирования. Так как я сейчас в процессе поиска работы, то времени навалом. Вот и решил поэкспериментировать. Что из этого в итоге выйдет — не знаю. В идеале хотелось бы полноценную CRM для аналитика: с календарём встреч, прямой интеграцией с JIRA для постановки задач и с Confluence для хранения документации. Пока же — через копипаст. Ну и можно дальше идею развить, дав стейкхолдерам доступ, чтобы они на вопросы отвечали сами. И распознавание голоса, чтобы ответы сами записывались. Идей много.

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

Во время очередного хвастовства один мой друг мне сказал:

— О, ты же делаешь замену аналитику.

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

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

ссылка на оригинал статьи https://habr.com/ru/articles/1066274/