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

от автора

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

Если вы системный аналитик, то знакомы с ситуацией, когда приходит бизнес с очередной хотелкой. Начинаете задавать вопросы, получаете ответы, потом еще, и еще. Через несколько встреч у вас набор разных заметок, записок, писем, страниц в Confluence. Если используете современный подходи и используете Чат-бот — то и несколько чатов. А когда одновременно несколько проектов, то все это превращается в мешанину.

И вот, под девизом «Хватит это терпеть» с помощью ИИ-агента в IDE родилось приложение DocGen, или AI-ассистент системного аналитика.

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

Общие вводные сведения.

Есть несколько проектов. Каждый проект — отдельная система, CRM, сайт, приложение . Короче, некий продукт. В моем случае это будет моя же небольшая программка для управления медиа контентом при проведение конференций, шоу и так далее. Описываем при создании краткое описание проекта, его задачи и цели.

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

В результате у нас есть описание продукта, его домен и описание первоначальных намерений. С этим уже можно работать.

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

Для начала нам надо сформировать пул вопросов для интервью. Затем сформировать из ответов документацию.

На Хабре видел несколько проектов, в которых есть перечень таких вопросов по типам интервью, вот и взял их за основу и сам принцип. Казалось бы, что проще еще, вопросы есть, ответы есть, проси документацию у AI-агента. Сделал набросок, отправил сформированное.

И получилось… Ну, что-то такое. Каша. Общего назначения, которая часто даже отношения не имела к намерениям. Тут же проверяю этот же промт через Чат-бот и получаю красивое. Даже начал тот самый Чат-бот допрашивать, почему это у него красивое, а у меня нет.

Путем экспериментов и чтений документаций, общения с тем же ИИ чатом дошел до идеи двух цепочек агентов. Одна для формирования вопросов, другая для формирования документации.

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

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

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

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

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

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

Agent 0: Context Quality Assessment

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

Поэтому появился Агент 0 для вычисления температуры для Агента 1.

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: ["Какой масштаб системы? (откуда берем, какие протоколы)", ...]

Итак, температура получена, едем дальше.

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.

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

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 генерирует черновик документа.

Температура 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 итерации). Снова открывается окно для ввода ответов и аналитик повторно задает вопросы. Если время встречи позволяет, то эту операцию можно выполнять сразу на месте, чтоб потом не согласовывать новую встречу для ввода ответов.

# Псевдокод цикла уточнений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 — минимум креативности, максимум точности. Документ должен быть готов к отправке.

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

Agent Document Converter превращает финальный Markdown от Агента 4 в нужные форматы. Поддерживает 8 типов документов: SRS, Architecture (на базе C4), API Spec (OpenAPI 3.1), README, Test Plan и три вида UML-диаграмм — Use Case, Sequence и Class. Для каждого документа свой промт, который выбирается после выбора типа документа. Форматы, соответственно, так же разные. Можно экспортировать для Jira, Confluence, Notion. PDF/DOCX пока не сделал, в планах.

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

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

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

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

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

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

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

  1. Создать проект → «Yerick Player»

  2. Создать встречу, заполнить описание, запустить «Generate Questions» → Agent 0 оценил контекст, Agent 1 сгенерировал 24 вопроса

  3. Провести интервью с Product Owner, Tech Lead, QA

  4. Запустить «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 дней вручную.

Сложности, которые я не предвидел

  1. Про температуру я уже писал.

  2. Не всегда валидный json в ответе. Пришлось мудрить проверки, парсеры, обработчики.

  3. В первых вариантах не было сквозной передачи контекста продукта и встречи. Ответы так же приходили обрезанными, общими и не полными. После того, как добавил в каждый агент product_typeproduct_domainintentions ответы начали приходить более качественными.

Итого

Делал для себя в первую очередь. Получилось неплохое веб приложение. Крепко сбитое, под капотом FastAPI, Pydantic v2, LLM провайдеры для разных агентов, переключать можно в settings, React 18 и много чего еще. Если сложить потраченное время, то вышло около недели. Все равно нахожусь в поисках работы, так что времени навалом. Делал все с помощью ИИ-агента в IDE. Так как в разработке более 20 лет, то сложностей не возникало, знал куда смотреть и какие границы ставить, какие правила настроить и так далее.

Ниже несколько скринов из приложения.

Окно проекта

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

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

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

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

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

Протестировал на проекте, о котором говорил в самом начале, на медиа плеере. Надо было добавить туда новую функциональность. Составил хотелки, ответил на вопросы. Потом итоговый документ загнал в ИИ-агента в IDE и получил за одну итерацию именно то, что хотел.

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

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

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

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

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