File size: 9,807 Bytes
deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 deed5a7 1833177 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
from pydantic import BaseModel
import re
class DiagramRequest(BaseModel):
description: str
class DiagramResponse(BaseModel):
plantuml_code: str
def preprocess_description(desc: str) -> str:
"""
Улучшенный препроцессинг:
- Убираем лишние пустые строки в начале/конце
- Нормализуем множественные пробелы и табы
- Сохраняем \n внутри — это важно для таблиц "Шаг | Роль" и списков
- Убираем только trailing/leading whitespace
"""
# Удаляем BOM, если есть
desc = desc.strip().lstrip('\ufeff')
# Заменяем множественные пробелы/табы на один, но сохраняем строки
desc = re.sub(r'[ \t]+', ' ', desc)
# Убираем пустые строки в начале и конце, но оставляем внутри
lines = [line.rstrip() for line in desc.splitlines() if line.strip()]
desc = '\n'.join(lines).strip()
return desc
def get_prompt(description: str) -> list[dict]:
"""
Возвращает список сообщений в формате ChatML для Qwen2.5-Instruct.
Это сильно улучшает качество по сравнению с plain text.
"""
system_prompt = """You are an expert PlantUML diagram generator. Your ONLY task is to convert the given process description into a valid, complete PlantUML activity diagram.
Rules you MUST follow strictly:
- Always output ONLY the PlantUML code: from @startuml to @enduml inclusive.
- NEVER add explanations, comments, markdown, extra text, apologies or anything else.
- Use the new activity diagram syntax (beta).
- Use swimlanes/partitions (|Actor|) for different roles or actors when mentioned (Шаг | Роль, Actor: action, etc.).
- Use start / stop / (*) / (*) for begin/end.
- Use :action; for steps.
- Use if (Condition?) then (yes) ... else (no) ... endif for decisions.
- Use -> [label]; for arrows with conditions if needed.
- Make diagrams clean, logical and complete — close all branches, ifs, etc.
- Detect type: simple sequence → linear; table Шаг/Роль → swimlanes; branches (Найдена?, Автоматически?) → if/else.
Examples follow. Follow their style and completeness exactly."""
messages = [
{"role": "system", "content": system_prompt},
]
# Few-shot примеры (полные, без '...', валидные)
examples = [
# Пример 1: Таблица с ролями (тех. стек)
{
"user": """Шаг | Роль
1. Создание запроса | Инициатор
2. Внесение технологии в тех. стек в статусе "Consideration" | Координатор
3. Оценка по техническим критериям | Инициатор
4. Уточнение требований к технологии | Совет по технологиям, Координатор, Владелец продукта
5. Оценка ограничений и рисков принятия новой мажорной версии | Координатор
6. Презентация новой мажорной версии | Инициатор
7. Принятие решения | Главный корпоративный архитектор, Совет по технологиям
8. Внесение записи в тех. стек, оповещение | Координатор
9. Перевод прошлой мажорной версии в статус Deprecated | Координатор
10. Оповещение | Координатор
11. Планирование обновления продукта | Координатор
12. Планирование автоматизации ресурсов | Координатор
13. Изменение атрибутов технологии в стеке | Координатор""",
"assistant": """@startuml
skinparam shadowing false
skinparam monochrome true
|Инициатор|
start
:Создание запроса;
|Координатор|
:Внесение технологии в тех. стек (Consideration);
|Инициатор|
:Оценка по техническим критериям;
|Совет по технологиям, Координатор, Владелец продукта|
:Уточнение требований к технологии;
|Координатор|
:Оценка ограничений и рисков;
|Инициатор|
:Презентация новой мажорной версии;
|Главный корпоративный архитектор, Совет по технологиям|
:Принятие решения;
|Координатор|
:Внесение записи в тех. стек;
:Оповещение;
:Перевод прошлой версии в Deprecated;
:Оповещение;
:Планирование обновления продукта;
:Планирование автоматизации ресурсов;
:Изменение атрибутов технологии;
stop
@enduml"""
},
# Пример 2: Ещё одна таблица с ролями
{
"user": """Шаг | Роль
1. Создание запроса | Инициатор
2. Подтверждение потребности в изменении условий использования | Координатор
3. Определение пользователей технологии | Совет по технологиям
4. Оценка трудозатрат | Совет по технологиям
5. Принятие решения | Главный корпоративный архитектор, Совет по технологиям
6. Изменение статуса технологии | Координатор
7. Оповещение клиентов | Команда разработки
8. Выполнение работ | ДЭиС""",
"assistant": """@startuml
skinparam shadowing false
|Инициатор|
start
:Создание запроса;
|Координатор|
:Подтверждение потребности в изменении;
|Совет по технологиям|
:Определение пользователей технологии;
:Оценка трудозатрат;
|Главный корпоративный архитектор, Совет по технологиям|
:Принятие решения;
|Координатор|
:Изменение статуса технологии;
|Команда разработки|
:Оповещение клиентов;
|ДЭиС|
:Выполнение работ;
stop
@enduml"""
},
# Пример 3: Простая последовательность без ролей
{
"user": """Шаг
1. Создание запроса
2. Рассмотрение запроса
3. Анализ запроса
4. Принятие решения о реализации изменения
5. Реализация улучшений и исправление несоответствий
6. Оценка результатов""",
"assistant": """@startuml
start
:Создание запроса;
:Рассмотрение запроса;
:Анализ запроса;
:Принятие решения о реализации;
:Реализация улучшений и исправлений;
:Оценка результатов;
stop
@enduml"""
},
# Пример 4: Чайник с событием и ветвлением
{
"user": """Шаг
1. Начало
2. Наполнить чайник
3. Включить чайник
4. Ждать закипания
5. Событие: Чайник закипел
6. Таймер: 30 секунд
7. Автовыключение
8. Ручное выключение
9. Чай готов""",
"assistant": """@startuml
start
:Наполнить чайник;
:Включить чайник;
:Ждать закипания;
note right: Событие: Чайник закипел
:Таймер: 30 секунд;
if (Выключен автоматически?) then (да)
:Автовыключение;
else (нет)
:Ручное выключение;
endif
:Чай готов;
stop
@enduml"""
},
# Пример 5: Решение с ветвлением (работа/учёба)
{
"user": """Шаг
1. Зачисление
2. Обновить резюме
3. Искать гибкую работу
4. Решение: Найдена?
5. Договориться о графике
6. Совмещение работы и учебы
7. Фокус на учебе
8. Только учеба""",
"assistant": """@startuml
start
:Зачисление;
:Обновить резюме;
:Искать гибкую работу;
if (Работа найдена?) then (да)
:Договориться о графике;
:Совмещение работы и учебы;
else (нет)
:Фокус на учебе;
:Только учеба;
endif
stop
@enduml"""
},
]
# Добавляем все few-shot
for ex in examples:
messages.append({"role": "user", "content": ex["user"]})
messages.append({"role": "assistant", "content": ex["assistant"]})
# Финальный запрос
messages.append(
{"role": "user", "content": f"Generate PlantUML activity diagram for this description:\n\n{description}"})
return messages |