Антипаттерны
Антипаттерны — это повторяющиеся ошибки проектирования workflow, которые приводят к сломанным, неэффективным или неподдерживаемым workflow. Workflow Management Flow (WMF) автоматически проверяет их при создании и редактировании.
Каталог антипаттернов
Заголовок раздела «Каталог антипаттернов»#1: Кругооборот данных
Заголовок раздела «#1: Кругооборот данных»Директива говорит агенту собрать данные, затем inputSchema просит агента вернуть эти же данные как структурированный вывод. Агент работает как оператор ввода данных, копируя из вывода инструмента в поля схемы.
Обнаружение: inputSchema повторяет структуру данных, которые агенту было поручено собрать.
❌ Directive: "Get project info from package.json" inputSchema: { project_name: string, version: string, description: string } // Агент копирует данные из файла в поля схемы — бессмысленный кругооборот
✅ Use expression node to extract data, or capture agent's ANALYSIS in inputSchema inputSchema: { architecture_assessment: string, risks_identified: string[] }#2: Пустая InputSchema с побочными эффектами
Заголовок раздела «#2: Пустая InputSchema с побочными эффектами»У узла нет inputSchema, но директива указывает агенту выполнить побочные эффекты (создать файлы, запустить команды). Никаких свидетельств о выполненном не сохраняется.
Обнаружение: Узел agent-directive без inputSchema, где директива описывает действия с наблюдаемыми результатами.
❌ Directive: "Create test files for auth module" (no inputSchema) // Workflow не знает, что было создано и было ли выполнено успешно
✅ inputSchema: { files_created: string[], tests_passing: boolean } // Свидетельства завершения сохраняются в контексте workflow#3: Вложенный формат InitialData
Заголовок раздела «#3: Вложенный формат InitialData»Системное соображение. Движок хранит переменные как объекты {description, value}. Не применимо на уровне отдельного workflow — следуйте формату, который ожидает движок.
#4: Цикл ревью через InputSchema вместо файлов
Заголовок раздела «#4: Цикл ревью через InputSchema вместо файлов»Обратная связь при ревью передаётся через текстовые поля inputSchema вместо персистентных файлов. Агент теряет контекст между итерациями.
Обнаружение: Цикл ревью/исправления, где узел исправления получает обратную связь только через текст inputSchema, а не через персистентный файл.
❌ Review node → inputSchema: { feedback: string } → Fix node reads feedback from input // Обратная связь эфемерна, теряется при повторе
✅ Review node writes review.md → Fix node reads review.md // Результаты сохраняются между итерациями и повторами#5: Неявные циклы исправлений
Заголовок раздела «#5: Неявные циклы исправлений»Директива говорит «исправляй пока не будет готово» без явной структуры цикла в графе. Агент повторяет попытки внутренне без контроля workflow.
Обнаружение: Слова вроде «retry», «keep trying», «fix until» в директиве без соответствующего условного узла, создающего цикл в графе.
❌ Directive: "Keep fixing tests until they all pass" // Нет структуры графа, агент зацикливается внутренне без контроля workflow
✅ [fix] → [run-tests] → condition(passed?) → [fix] / [next] // Явный цикл в графе с видимостью каждой итерации для workflow#6: Неограниченные циклы
Заголовок раздела «#6: Неограниченные циклы»Циклы валидации без лимитов итераций или путей эскалации. Могут выполняться бесконечно, если условие никогда не будет выполнено.
Обнаружение: Цикл в графе без переменной-счётчика итераций или без условия проверки лимита итераций.
❌ Loop: [action] → [check] → [fix] → [action] (бесконечно, если качество никогда не пройдёт)
✅ Expression node increments counter → Condition: iterations > max → escalation path // Агент не может застрять — после N попыток эскалация пользователю#7: Динамические данные в переменных workflow
Заголовок раздела «#7: Динамические данные в переменных workflow»Хранение динамических данных, генерируемых в ходе выполнения workflow (содержимое файлов, ответы API, HTML-вывод, результаты извлечения) в переменных workflow. Эти переменные внедряются в каждую директиву через шаблоны, раздувая контекст потенциально неограниченным содержимым.
Обнаружение: Переменные, получающие динамический контент через inputSchema во время выполнения, особенно контент >1KB или контент, растущий неограниченно.
Область применения: Этот антипаттерн относится к данным, передаваемым между шагами workflow — НЕ к статической конфигурации, хранящейся в initialData при запуске workflow. См. паттерн Статическая конфигурация workflow для понимания различия.
❌ inputSchema: { html_content: string } Next directive: "Publish {{step.html_content}}" // Целая HTML-страница хранится в переменной, внедряется в каждую последующую директиву
❌ inputSchema: { extraction_results: object } Next directive: "Analyze {{extraction_results}}" // Потенциально большие данные извлечения передаются туда-обратно через переменные
✅ Directive: "Save HTML to {{workspace_path}}/report.html" inputSchema: { file_path: string } Next directive: "Publish file at {{step.file_path}}" // В переменной хранится только путь, агент читает файл по необходимостиИсключение: Статический инструктивный контент в initialData (правила, стандарты, чек-листы) — это правильный паттерн, а не злоупотребление переменными. Они намеренно размещены, чтобы агент видел их на каждом соответствующем шаге. См. Статическая конфигурация workflow.
#8: Модификация SystemReminder
Заголовок раздела «#8: Модификация SystemReminder»Системное соображение. systemReminder статичен и применяется ко ВСЕМ шагам. Инструкции для конкретных шагов должны быть в директивах узлов, а не в systemReminder.
#9: Ручное управление индексами агентом
Заголовок раздела «#9: Ручное управление индексами агентом»Агент вручную отслеживает индексы массивов, счётчики или пагинацию через inputSchema. Подвержено ошибкам и ломается при повторе.
Обнаружение: inputSchema с полями вроде current_index, next_item_number или значениями счётчиков, которые агент должен вычислять.
❌ inputSchema: { current_index: number, next_item: string } // Агент выполняет арифметику, подвержен ошибкам
✅ Expression node: current_index = {current_index} + 1 Directive: "Process {{items[{current_index}]}}" // Движок workflow обрабатывает арифметику детерминированно#10: Загрузка файла через контент
Заголовок раздела «#10: Загрузка файла через контент»Передача всего JSON workflow через параметры MCP-инструмента для больших workflow. Упирается в лимиты размера.
Обнаружение: manage({ action: "create", workflow: <large JSON> }) с workflow >50KB.
❌ manage({ action: "create", workflow: <50KB JSON> }) // Может упереться в лимиты размера параметров
✅ token({ action: "upload" }) → HTTP PUT with file content // Загрузка по токену обрабатывает любой размер#11: Дублирование контекста
Заголовок раздела «#11: Дублирование контекста»Копирование информации, уже имеющейся в контексте агента, в переменные workflow. Избыточно и раздувает контекст.
Обнаружение: inputSchema, захватывающая данные, которые агент уже имеет в контексте разговора (например, списки директорий, информация о проекте из предыдущего анализа).
❌ variable: project_structure = "<output of tree command>" // Агент уже имеет это в контексте; повторное хранение тратит токены
✅ Let agent re-read current data when needed. Store only stable references (paths, IDs).#12: Вынесение критических инструкций в файлы
Заголовок раздела «#12: Вынесение критических инструкций в файлы»Перемещение важных инструкций и стандартов агента из initialData во внешние файлы с ожиданием, что агент будет читать их каждый раз. Это создаёт риск галлюцинаций и добавляет лишний ввод-вывод.
Обнаружение: Директива говорит «прочитай правила из файла X» для контента, который должен быть стабильно доступен. Инструкции, критичные для поведения агента, хранятся вне workflow.
❌ Directive: "Read planning standards from ./standards.md before creating plan" // Агент может пропустить чтение, вспомнить из обучающих данных или прочитать выборочно // Дополнительная операция ввода-вывода на каждом шаге, требующем этих правил
✅ Store in initialData variable: planning_standards = "1. Each step must... 2. Tests built-in..." Directive: "Create plan following {{planning_standards}}" // Движок workflow гарантирует доставку; нет ввода-вывода; нет риска галлюцинацийПравильные паттерны
Заголовок раздела «Правильные паттерны»Паттерн динамического индекса массива
Заголовок раздела «Паттерн динамического индекса массива»Правильный способ итерации по элементам массива:
1. Store array: items = ["a", "b", "c"]2. Store index: current_index = 03. Directive: "Process item {{items[{current_index}]}}"4. Expression: current_index = {current_index} + 15. Condition: {current_index} < items.length → loop / continueПаттерн ревью через файлы
Заголовок раздела «Паттерн ревью через файлы»[implement] → [review-to-file] → [check-issues] → [fix-from-file] → [review-to-file] ↓ no issues → [next]