Анализ BPMN-диаграмм с LLM: промпты, код и упрощение процессов | AiManual
AiManual Logo Ai / Manual.
15 Янв 2026 Гайд

LLM как супер-линза для BPMN: как заставить нейросеть читать диаграммы вместо вас

Пошаговое руководство по использованию LLM для анализа сложных BPMN-диаграмм. Готовые промпты, код на Python и автоматизация документооборота.

Зачем вообще это нужно? (Спойлер: потому что диаграммы стали нечитаемыми)

Откройте любой BPMN-файл из реального проекта. Что вы видите? Десятки параллельных шлюзов, сотни задач, стрелки, которые пересекаются так плотно, что напоминают схему метро в час пик. Бизнес-аналитик, который это рисовал, давно уволился. Технические специалисты смотрят на это и плачут. Руководитель хочет «быстро понять суть процесса».

Типичная ситуация: у вас есть BPMN-диаграмма на 150 элементов. Новый разработчик приходит в проект и тратит неделю, чтобы просто понять, что там происходит. А потом ещё неделю — чтобы найти ошибку в логике.

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

  • Находит логические противоречия в параллельных процессах
  • Выделяет ключевые этапы из сотен задач
  • Генерирует человекочитаемое описание на русском (да, без канцелярита)
  • Предлагает упрощения — какие элементы можно удалить без потери смысла

И самое главное — этот ассистент не устаёт, не просит повышения зарплаты и работает 24/7. Звучит как утопия? Сейчас покажу, как это сделать.

Первое препятствие: как засунуть диаграмму в LLM?

BPMN — это XML. Счастливые обладатели .bpmn файлов могут сразу парсить. Остальные (у кого PNG, PDF или, не дай бог, Visio) — сначала конвертируют. Я предпочитаю работать с XML — там структура, а не картинка.

💡
Если у вас только изображение — используйте Camunda Modeler для обратной конвертации или специализированные OCR-инструменты для BPMN. Но будьте готовы к ошибкам распознавания.

1 Парсим BPMN XML как нормальные люди

import xml.etree.ElementTree as ET
from typing import Dict, List, Any
import json

def parse_bpmn_xml(file_path: str) -> Dict[str, Any]:
    """
    Извлекает структуру BPMN-диаграммы из XML.
    Возвращает словарь с процессами, задачами, шлюзами и потоками.
    """
    tree = ET.parse(file_path)
    root = tree.getroot()
    
    # BPMN использует пространства имён
    namespaces = {
        'bpmn': 'http://www.omg.org/spec/BPMN/20100524/MODEL',
        'bpmndi': 'http://www.omg.org/spec/BPMN/20100524/DI'
    }
    
    result = {
        'processes': [],
        'total_elements': 0,
        'complexity_score': 0
    }
    
    # Находим все процессы
    for process in root.findall('.//bpmn:process', namespaces):
        process_data = {
            'id': process.get('id'),
            'name': process.get('name', 'Unnamed'),
            'tasks': [],
            'gateways': [],
            'events': [],
            'sequence_flows': []
        }
        
        # Задачи
        for task in process.findall('.//bpmn:task', namespaces):
            process_data['tasks'].append({
                'id': task.get('id'),
                'name': task.get('name'),
                'type': 'task'
            })
        
        # Шлюзы (ветвления)
        for gateway in process.findall('.//bpmn:gateway', namespaces):
            process_data['gateways'].append({
                'id': gateway.get('id'),
                'name': gateway.get('name'),
                'type': gateway.get('gatewayDirection', 'unspecified')
            })
        
        # Потоки управления
        for flow in process.findall('.//bpmn:sequenceFlow', namespaces):
            process_data['sequence_flows'].append({
                'id': flow.get('id'),
                'source': flow.get('sourceRef'),
                'target': flow.get('targetRef'),
                'name': flow.get('name')
            })
        
        # Считаем сложность: задачи + шлюзы * 2 (шлюзы сложнее)
        complexity = len(process_data['tasks']) + len(process_data['gateways']) * 2
        process_data['complexity'] = complexity
        result['complexity_score'] += complexity
        
        result['processes'].append(process_data)
        result['total_elements'] = len(process_data['tasks']) + \
                                  len(process_data['gateways']) + \
                                  len(process_data['events']) + \
                                  len(process_data['sequence_flows'])
    
    return result

# Пример использования
if __name__ == "__main__":
    bpmn_data = parse_bpmn_xml("complex_process.bpmn")
    print(f"Всего процессов: {len(bpmn_data['processes'])}")
    print(f"Всего элементов: {bpmn_data['total_elements']}")
    print(f"Оценка сложности: {bpmn_data['complexity_score']}")

Этот код — база. Он достаёт сырые данные. Но сырые данные LLM не съест. Нужно приготовить.

2 Готовим промпт-коктейль для LLM

Самый важный этап. Неправильный промпт = мусор на выходе. Я перепробовал десятки вариантов и вывел формулу, которая работает с GPT-4, Claude 3.5 и даже с локальными моделями вроде Llama 3.1.

Что нужно Как получить Пример из жизни
Структура процесса Список задач в порядке выполнения "Заявка → Валидация → Проверка KYC → Одобрение"
Точки принятия решений Шлюзы с условиями "Если сумма > 100к → ручная проверка, иначе → авто"
Проблемные места Циклы, тупики, избыточные проверки "Три одинаковые проверки подряд — удалить две"
def prepare_llm_prompt(bpmn_data: Dict, analysis_type: str = "simplify") -> str:
    """
    Подготавливает промпт для LLM на основе данных BPMN.
    
    analysis_type может быть:
    - "simplify": упрощение диаграммы
    - "explain": объяснение процесса
    - "validate": проверка логики
    - "optimize": предложение оптимизаций
    """
    
    # Базовый контекст
    prompt = """Ты — senior бизнес-аналитик с 10-летним опытом работы с BPMN 2.0.
Твоя задача — проанализировать бизнес-процесс и дать рекомендации.

ДАННЫЕ ПРОЦЕССА:
"""
    
    # Добавляем структурированные данные
    for i, process in enumerate(bpmn_data['processes']):
        prompt += f"\n\nПРОЦЕСС #{i+1}: {process['name']}"
        prompt += f"\nЗадачи ({len(process['tasks'])}): "
        prompt += ", ".join([task['name'] for task in process['tasks'] if task['name']])
        
        if process['gateways']:
            prompt += f"\nТочки ветвления ({len(process['gateways'])}): "
            prompt += ", ".join([f"{gw['name'] or gw['id']} ({gw['type']})" 
                               for gw in process['gateways']])
        
        if process['sequence_flows']:
            prompt += f"\nСвязи между элементами: {len(process['sequence_flows'])}"
    
    # Добавляем инструкции в зависимости от типа анализа
    if analysis_type == "simplify":
        prompt += """

ИНСТРУКЦИЯ ПО УПРОЩЕНИЮ:
1. Найди избыточные элементы (дублирующиеся задачи, лишние шлюзы)
2. Предложи объединение последовательных задач в одну
3. Если есть параллельные ветки, которые можно сделать последовательными — предложи
4. Удали элементы, не влияющие на результат
5. Предложи новую структуру с оценкой упрощения (например, "было 20 элементов → стало 12")

Формат ответа:
- Проблемы найденные (список)
- Предлагаемые изменения (конкретные)
- Новая структура процесса (текстовое описание)
- Оценка упрощения
"""
    elif analysis_type == "explain":
        prompt += """

ИНСТРУКЦИЯ ПО ОБЪЯСНЕНИЮ:
1. Опиши процесс простыми словами, как будто объясняешь стажёру
2. Выдели ключевые этапы (не больше 5-7)
3. Укажи, кто отвечает за каждый этап (если в данных есть роли)
4. Отметь критические точки (где чаще всего возникают ошибки)
5. Оцени общее время выполнения (если есть данные о времени)

Формат ответа:
- Краткое описание (1 абзац)
- Пошаговый алгоритм
- Роли участников
- Риски и узкие места
"""
    
    prompt += """\n\nВАЖНО: Будь конкретен. Не говори общими фразами. 
Ссылайся на конкретные ID элементов из данных выше.
Используй markdown для структурирования ответа."""
    
    return prompt

# Готовим промпт для упрощения
bpmn_data = parse_bpmn_xml("order_processing.bpmn")
prompt = prepare_llm_prompt(bpmn_data, "simplify")
print("Длина промпта:", len(prompt))  # Обычно 500-2000 токенов

Ключевой момент — структура промпта. Сначала даём роль («senior бизнес-аналитик»), потом данные, потом конкретную инструкцию. LLM любит конкретику.

Три уровня анализа: от простого к сложному

Не пытайтесь сделать всё сразу. Начните с малого, потом усложняйте.

Уровень 1: Текстовое описание

Простейший вариант. Берём структуру BPMN, кормим в LLM, получаем человеческое описание. Полезно для документации или для объяснения процесса новичкам.

Промпт для быстрого объяснения: «Объясни этот бизнес-процесс так, чтобы понял десятилетний ребёнок. Выдели 3 главных этапа. Опиши, что происходит на каждом этапе. Не используй профессиональный жаргон.»

Уровень 2: Поиск аномалий

Здесь уже интереснее. LLM ищет:

  • Dead ends — задачи, от которых нет исходящих потоков
  • Циклы без условий выхода
  • Дублирование функционала (например, три проверки одного документа)
  • Слишком сложные ветвления (шлюз с 5+ исходящими потоками)

Для этого нужен более продвинутый промпт с примерами аномалий. Я обычно даю LLM «памятку проверяющего».

Уровень 3: Предложение оптимизаций

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

optimization_prompt = """
Найди в процессе эти паттерны неэффективности:
1. Последовательные задачи, которые можно выполнять параллельно
2. Параллельные задачи без реальной необходимости в параллельности
3. Ручные утверждения там, где можно автоматизировать
4. Избыточные проверки данных
5. Отсутствие обработки ошибок в критичных местах

Для каждой найденной проблемы предложи:
- Конкретное изменение в BPMN (какой элемент удалить/объединить/переместить)
- Ожидаемый эффект (ускорение на X%, снижение ошибок на Y%)
- Сложность внедрения (низкая/средняя/высокая)
"""

Интеграция с LangChain: когда одного промпта мало

Если ваш BPMN настолько сложен, что не помещается в контекст одной модели (да, бывает), используйте цепочки. Разбиваем диаграмму на подпроцессы, анализируем по частям, потом сводим результаты.

from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain_community.llms import Ollama  # или OpenAI, Anthropic и т.д.

class BPMNAnalyzer:
    def __init__(self, model_name="llama3.1"):
        self.llm = Ollama(model=model_name)
        
    def analyze_complex_process(self, bpmn_data: Dict) -> str:
        """
        Анализирует сложный процесс через несколько цепочек
        """
        # Шаг 1: Общий обзор
        overview_prompt = PromptTemplate(
            input_variables=["process_data"],
            template="""
            Дай общий обзор этого бизнес-процесса:
            {process_data}
            
            Ответь:
            1. Основная цель процесса
            2. Ключевые участники
            3. Основные этапы (максимум 5)
            """
        )
        
        overview_chain = LLMChain(llm=self.llm, prompt=overview_prompt)
        overview = overview_chain.run(process_data=str(bpmn_data))
        
        # Шаг 2: Анализ проблемных мест
        problem_prompt = PromptTemplate(
            input_variables=["process_data", "overview"],
            template="""
            На основе общего обзора:
            {overview}
            
            И детальных данных процесса:
            {process_data}
            
            Найди потенциальные проблемы:
            - Узкие места
            - Риски
            - Избыточные операции
            """
        )
        
        problem_chain = LLMChain(llm=self.llm, prompt=problem_prompt)
        problems = problem_chain.run(
            process_data=str(bpmn_data),
            overview=overview
        )
        
        # Шаг 3: Рекомендации по упрощению
        simplify_prompt = PromptTemplate(
            input_variables=["process_data", "overview", "problems"],
            template="""
            Процесс:
            {overview}
            
            Проблемы:
            {problems}
            
            Предложи 3-5 конкретных упрощений.
            Для каждого укажи:
            - Что изменить
            - Как изменить
            - Ожидаемый эффект
            """
        )
        
        simplify_chain = LLMChain(llm=self.llm, prompt=simplify_prompt)
        recommendations = simplify_chain.run(
            process_data=str(bpmn_data),
            overview=overview,
            problems=problems
        )
        
        return f"""ОБЗОР:\n{overview}\n\nПРОБЛЕМЫ:\n{problems}\n\nРЕКОМЕНДАЦИИ:\n{recommendations}"""

# Использование
analyzer = BPMNAnalyzer()
result = analyzer.analyze_complex_process(bpmn_data)
print(result)

Такая многоэтапная обработка даёт гораздо более качественные результаты, чем один мега-промпт. Особенно с локальными моделями, у которых контекст ограничен.

Ошибки, которые все совершают (и вы тоже их совершите)

Ошибка №1: Слишком много деталей. Не загружайте в промпт все атрибуты всех элементов. LLM захлебнётся. Берите только id, name, type и связи.

Ошибка №2: Отсутствие контекста. «Проанализируй этот процесс» — плохо. «Это процесс обработки заявок на кредит в банке. Клиент подаёт заявку, менеджер проверяет, скоринговая система оценивает риск» — хорошо.

Ошибка №3: Верить LLM на слово. Нейросеть может придумать связи, которых нет в диаграмме. Всегда проверяйте её предложения на реальной схеме.

Самая частая проблема: LLM начинает «сочинять». Видит задачу «Проверить документы» и шлюз «Документы верны?» и выдумывает между ними связь, которой нет в XML. Защита простая — просите LLM указывать ID элементов, которые она упоминает. Потом проверяете по исходным данным.

Готовые промпты для копипаста

Берите, меняйте под свои нужды.

Промпт для быстрого объяснения

Ты — опытный бизнес-аналитик. Объясни этот процесс так, чтобы понял нетехнический руководитель.

Данные процесса:
{process_structure}

Инструкции:
1. Начни с одной фразы: что делает этот процесс
2. Перечисли этапы простыми словами (без BPMN-терминов)
3. Укажи, кто за что отвечает (если данные есть)
4. Назови самую долгую и самую критичную часть
5. Закончи рекомендацией: что можно улучшить сразу

Формат: маркдаун, не больше 10 предложений.

Промпт для поиска узких мест

Ты — инженер по оптимизации процессов. Найди узкие места и предложи улучшения.

Процесс:
{process_data}

Что искать:
1. Задачи, которые всегда выполняются последовательно, но могут выполняться параллельно
2. Шлюзы с более чем 3 исходящими потоками — упростить
3. Циклы без чёткого условия выхода
4. Задачи, которые занимают 80% времени процесса (если есть временные метрики)

Для каждой проблемы:
- Опиши её простыми словами
- Предложи конкретное изменение
- Оцени эффект (высокий/средний/низкий)

Будь конкретен. Ссылайся на ID элементов.

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

На основе BPMN-диаграммы создай документацию для разработчиков.

Структура документации:
1. Краткое описание процесса
2. Список всех задач с описанием (что делает, входные данные, выходные данные)
3. Бизнес-правила (условия в шлюзах)
4. Обработка ошибок (где и какие ошибки могут возникнуть)
5. API-эндпоинты или сервисы, если упоминаются
6. Тестовые сценарии (3-5 ключевых кейсов)

Данные процесса:
{process_data}

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

Что делать с результатами? (Практическое применение)

Получили от LLM анализ. И что дальше? Варианты:

  1. Автоматическое создание тикетов — LLM находит проблему → система создаёт задачу в Jira/Trello
  2. Генерация тестов — на основе процесса создаются тестовые сценарии
  3. Сравнение версий — загружаете старую и новую версию BPMN, LLM показывает различия
  4. Обучение новых сотрудников — автоматические гайды по процессам

Мой любимый кейс: интеграция с системой мониторинга. LLM анализирует BPMN, находит потенциальные узкие места, система мониторинга ставит датчики именно на эти участки. Предсказательная аналитика в действии.

Локальные модели vs облачные: что выбрать?

GPT-4 и Claude 3.5 справляются с анализом BPMN на ура. Но они дорогие и требуют отправки данных в облако. Для конфиденциальных процессов это неприемлемо.

Локальные модели (через LM Studio или llama.cpp) — медленнее, но данные никуда не уходят. Для анализа BPMN достаточно моделей 7B-13B параметров. Llama 3.1 8B справляется с диаграммами до 50 элементов вполне сносно.

💡
Секрет: локальные модели лучше работают с структурированными промптами. Разбейте анализ на этапы, каждый этап — отдельный запрос. Результаты объединяйте вручную или через простой скрипт.

Если нужна максимальная точность — используйте кастомные промпты из коллекции промптов для тестирования LLM. Там есть шаблоны именно для структурного анализа.

Куда это движется? (Спойлер: к полной автоматизации)

Сейчас мы используем LLM как помощника для анализа. Через год-два будет обратный процесс — LLM будет генерировать BPMN из текстового описания. Уже сейчас есть эксперименты, где GPT-4 создаёт корректные .bpmn файлы по описанию процесса.

Но главное не это. Главное — LLM становится мостом между бизнесом (который думает текстом) и разработчиками (которые думают диаграммами). Один промпт — и вы получаете анализ, который раньше требовал недели работы аналитика.

Самый неочевидный совет в конце: начните с самого сложного, запутанного процесса в вашей компании. Того, который все ненавидят. Проанализируйте его с помощью LLM. Даже если результат будет неидеальным — вы увидите проблемы, которые не замечали годами. Иногда взгляд со стороны (даже искусственного) ценнее сотни часов рефакторинга.

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