Зачем вообще это нужно? (Спойлер: потому что диаграммы стали нечитаемыми)
Откройте любой BPMN-файл из реального проекта. Что вы видите? Десятки параллельных шлюзов, сотни задач, стрелки, которые пересекаются так плотно, что напоминают схему метро в час пик. Бизнес-аналитик, который это рисовал, давно уволился. Технические специалисты смотрят на это и плачут. Руководитель хочет «быстро понять суть процесса».
Типичная ситуация: у вас есть BPMN-диаграмма на 150 элементов. Новый разработчик приходит в проект и тратит неделю, чтобы просто понять, что там происходит. А потом ещё неделю — чтобы найти ошибку в логике.
LLM здесь не панацея. Но это мощный увеличитель ваших аналитических способностей. Представьте, что у вас есть ассистент, который за секунды:
- Находит логические противоречия в параллельных процессах
- Выделяет ключевые этапы из сотен задач
- Генерирует человекочитаемое описание на русском (да, без канцелярита)
- Предлагает упрощения — какие элементы можно удалить без потери смысла
И самое главное — этот ассистент не устаёт, не просит повышения зарплаты и работает 24/7. Звучит как утопия? Сейчас покажу, как это сделать.
Первое препятствие: как засунуть диаграмму в LLM?
BPMN — это XML. Счастливые обладатели .bpmn файлов могут сразу парсить. Остальные (у кого PNG, PDF или, не дай бог, Visio) — сначала конвертируют. Я предпочитаю работать с XML — там структура, а не картинка.
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 анализ. И что дальше? Варианты:
- Автоматическое создание тикетов — LLM находит проблему → система создаёт задачу в Jira/Trello
- Генерация тестов — на основе процесса создаются тестовые сценарии
- Сравнение версий — загружаете старую и новую версию BPMN, LLM показывает различия
- Обучение новых сотрудников — автоматические гайды по процессам
Мой любимый кейс: интеграция с системой мониторинга. 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 раз эффективнее. А в мире, где процессы усложняются быстрее, чем мы успеваем их документировать, это уже не роскошь, а необходимость.