Детерминированное поведение и стейт‑машины для ваших ИИ‑агентов
Агенты на базе больших языковых моделей блестяще работают там, где задача чёткая и узкая: написать функцию, оформить короткий текст, сгенерировать SQL‑запрос, придумать тест‑кейс. Но как только мы поручаем им сложный многошаговый процесс, начинаются систематические сбои. Чем выше уровень абстракции, тем чаще агент:
- перепрыгивает через важные шаги,
- путает последовательность действий,
- неверно трактует инструкции,
- «забывает» о ранее принятых решениях.
Ошибки накапливаются и усиливают друг друга: один неверный шаг искажает контекст, на основе искажённого контекста принимается следующее решение, и в итоге результат всё сильнее уходит от задуманного. Чем крупнее задача, отданная агенту «одним куском», тем выше вероятность, что итог придётся полностью переделывать вручную.
Высокоуровневая работа более алгоритмична, чем кажется
Если внимательно разобрать, как люди выполняют сложные интеллектуальные задачи, обнаруживается любопытный парадокс.
1. Большинство высокоуровневой работы куда более алгоритмично, чем мы думаем.
Проектирование, анализ, оптимизация процессов, принятие решений — почти всё это укладывается в повторяющиеся циклы:
- сформулировать цель,
- собрать данные,
- проанализировать,
- предложить варианты,
- выбрать,
- проверить и откорректировать.
Эту идею формализуют известные управленческие циклы: PDCA, OODA, DMAIC, 8D и многие другие. По сути, это простые мета‑алгоритмы: всегда делай шаг 1, затем шаг 2 и т.д., пока не выполнено условие завершения.
2. Большинство низкоуровневой работы, наоборот, хуже алгоритмизируется, чем кажется.
Вроде бы написать функцию или абзац текста — это «механика»: получил ТЗ — выдал код или текст. Но реальность сложнее. Внутри каждого «простого» шага скрывается множество решений:
- как именно интерпретировать требования,
- какую структуру кода выбрать,
- какие граничные случаи предусмотреть,
- какой тон и стиль соблюсти.
Здесь требуется творческое, вероятностное поведение — именно сильная сторона современных языковых моделей.
Отсюда вытекает ключевая стратегия:
**высокоуровневые процессы описывать как алгоритм (стейт‑машину),
а самим агентам отдавать небольшие, приземлённые низкоуровневые задачи с ясным контекстом.**
Почему простого «хорошего промпта» недостаточно
Попытка решить проблему сложных процессов через «супер‑промпт» или цепочку текстовых инструкций работает плохо по нескольким причинам:
- Модель не хранит и не контролирует «состояние процесса» в явном виде.
Каждый шаг — это независимый запрос, где контекст передаётся текстом, а не структурой.
- Вероятностная природа вывода делает следование инструкциям нестабильным:
небольшое изменение формулировки или контекста может привести к нарушению шага.
- Невозможно надёжно реализовать ветвления и циклы: модель может «решить», что уже всё сделала, или, наоборот, зациклиться по смыслу.
Чтобы получить предсказуемость, нужен отдельный слой управления: кто‑то должен помнить, на каком шаге мы находимся, какие условия выполнены и куда нужно переходить дальше. Эту задачу традиционно решают стейт‑машины.
Стейт‑машина как «скелет» для работы агента
Стейт‑машина (конечный автомат) — это структура, которая:
- описывает набор состояний (шагов) процесса,
- фиксирует переходы между ними (что делать после какого шага),
- хранит текущий статус и стек вызовов,
- чётко задаёт, какие операции возможны в какой момент.
Если наложить стейт‑машину на работу агента, получается разделение ролей:
- стейт‑машина отвечает за логику процесса: порядок шагов, ветвления, циклы, условия выхода;
- агент отвечает за выполнение конкретных, локальных задач в каждом состоянии: сгенерировать текст, написать функцию, придумать тесты, проанализировать данные.
Таким образом, мы убираем из области ответственности модели то, что она делает плохо (длинное планирование, строгий контроль алгоритма), и оставляем то, в чём она сильна (локальный интеллект и генерация).
Donna: утилита, которая исполняет стейт‑машины вместо агентов
В результате нескольких месяцев экспериментов родилась утилита Donna. Её идея проста:
пусть агент занимается только конкретными действиями, а Donna управляет процессом, как интерпретатор стейт‑машин.
Что делает Donna:
- хранит текущее состояние и стек вызовов;
- контролирует переходы между состояниями;
- реализует ветвления, циклы, вложенные и рекурсивные вызовы;
- передаёт агенту строго ограниченный контекст и конкретную задачу на каждом шаге.
В отличие от подходов, где агенту подсаживают длинные мета‑инструкции в виде текста и надеются, что он им «в целом» будет следовать, Donna не пытается убедить модель быть дисциплинированной. Она просто не доверяет ей управление процессом:
- агент не решает, какой будет следующий шаг;
- агент не управляет циклом;
- агент не определяет критерии завершения.
Всё это зашито в стейт‑машину, которую исполняет Donna. Модель лишь получает чётко сформулированный локальный запрос и возвращает результат.
Формат workflow: Markdown + Jinja2
Workflow (стейт‑машина) в Donna — это обычный Markdown‑файл, расширенный шаблонизатором Jinja2. Такой формат даёт несколько преимуществ:
- Читабельность для людей.
Можно открыть файл в любом редакторе, прочитать описание шагов как текст и сразу понять логику процесса.
- Гибкость для шаблонизации.
Jinja2 позволяет:
- использовать переменные,
- генерировать повторяющиеся блоки,
- подставлять данные из контекста,
- динамически формировать промпты.
- Удобство для агентов.
Поскольку формат простой и текстовый, агенты сами могут:
- читать существующие workflow,
- модифицировать их,
- создавать новые стейт‑машины.
Это открывает дорогу к самопрограммированию агентов: модель не только исполняет процессы, но и проектирует собственные алгоритмы работы.
Самопрограммирование на практике: цепочка вокруг RFC
В комплекте с Donna есть пример рабочего процесса, который показывает, как несколько стейт‑машин могут выстраиваться в цепочку:
1. Выбор подходящего workflow для формирования RFC (Request for Change).
Агент на основе задачи и контекста выбирает нужный сценарий создания RFC и запускает его.
2. Генерация RFC по выбранному сценарию.
В рамках этого workflow модель последовательно:
- собирает требования,
- формализует изменения,
- описывает мотивацию,
- фиксирует риски и критерии приёмки.
3. Создание workflow для реализации изменений из RFC.
На основе полученного документа агент проектирует новый стейт‑машин:
- какие компоненты правим,
- какие шаги разработки нужны,
- где встраивается тестирование и деплой,
- какие проверки обязательны.
4. Запуск workflow реализации.
Donna исполняет новую стейт‑машину: вызывает агента для написания кода, написания тестов, обновления документации и т.п.
5. Выбор и запуск workflow для «полировки» кода.
Следующий сценарий отвечает за улучшение стиля, рефакторинг, устранение запахов кода.
6. Выбор и запуск workflow для обновления CHANGELOG.
Ещё один workflow автоматически приводит историю изменений в порядок.
Каждый из этих процессов может быть описан отдельной стейт‑машиной, а Donna шьёт их в единую цепочку алгоритмически, не полагаясь на «память» агента.
Пример: упрощённый workflow для полировки Python‑кода
Рассмотрим упрощённый сценарий (без конкретного синтаксиса), чтобы понять идею:
1. Состояние «Анализ входного кода»
- Агенту даётся фрагмент Python‑кода и задача:
- определить потенциальные проблемы,
- перечислить участки, требующие улучшения,
- зафиксировать стиль проекта (по существующему коду).
2. Состояние «Предложение плана улучшений»
- На основе анализа агент составляет:
- список шагов по рефакторингу,
- приоритеты (что критично, что желательно),
- пример ожидаемого результата.
3. Состояние «Пошаговый рефакторинг» (цикл)
- Для каждого шага из плана:
- агент изменяет код,
- поясняет, что именно сделано и почему,
- возвращает обновлённый фрагмент.
- Donna контролирует, что все элементы плана обработаны.
4. Состояние «Финальная проверка»
- Агент проверяет:
- читаемость кода,
- соответствие стилю,
- отсутствие явных ошибок и регрессий,
- возможные дальнейшие улучшения (как список рекомендаций).
5. Состояние «Результат»
- Donna фиксирует финальный код, промежуточные пояснения и возвращает результат наружу.
Такая стейт‑машина гарантирует, что:
- будут пройдены все шаги, а не только «самые интересные» для модели;
- ни одно важное действие не будет пропущено из‑за случайной генерации;
- можно в любой момент восстановить, что и на каком этапе было сделано.
Чем подход со стейт‑машинами лучше «цепочек промптов»
Снаружи может показаться, что это просто «чуть более аккуратная цепочка промптов». Но различия принципиальны:
- Жёсткая структура вместо скрытого плана.
Стейт‑машина задаёт структуру явно и независимо от модели. Агент не может «передумать» и пропустить шаг.
- Контролируемые ветвления.
Решение о том, куда идти дальше, принимает не модель «по ощущению», а конкретное условие в автомате.
- Возможность отладки.
Путь по стейт‑машине можно логировать, анализировать и воспроизводить: если что‑то пошло не так, легко увидеть, на каком шаге.
- Повторяемость.
Один и тот же workflow при разных запусках ведёт процесс одинаково, а вариативность ограничивается только локальными решениями агента внутри состояний.
Фактически, Donna превращает «хаотичного умного собеседника» в исполнителя внутри предсказуемого алгоритма.
Где детерминированные агенты особенно полезны
Применений у такого подхода много, особенно там, где важны надёжность и повторяемость:
1. Инженерные процессы и разработка ПО.
- генерация RFC и архитектурных документов,
- шаблонные изменения в коде по заранее описанным правилам,
- автоматизация типовых задач ревью и рефакторинга,
- подготовка релизов и сопроводительной документации.
2. Обработка данных и аналитика.
- последовательная очистка и нормализация данных,
- построение отчётов по фиксированному сценарию,
- многошаговый анализ (сбор → проверка → анализ → выводы → рекомендации).
3. Техническая поддержка и внутренние регламенты.
- ведение заявок по стандартным скриптам,
- диагностика типовых проблем по «дереву решений»,
- структурированное общение с пользователем с обязательными вопросами и проверками.
4. Тестирование и валидация.
- генерация тестов на основе спецификаций,
- пошаговое проведение тест‑планов,
- фиксирование результатов и формирование отчётов.
Везде, где вы можете описать процесс как алгоритм с шагами и ветвлениями, Donna позволяет переложить выполнение низкоуровневых действий на агента, сохранив детерминированность общей логики.
Практические советы по проектированию стейт‑машин для агентов
Чтобы workflow получались устойчивыми и полезными, стоит придерживаться нескольких принципов:
- Дробите шаги.
Один шаг — одна понятная задача для агента. Лучше больше мелких состояний, чем одно «сделай всё».
- Минимизируйте контекст.
Передавайте только то, что действительно нужно для текущего шага. Это снижает риск того, что модель «уплывёт» в сторону.
- Явно фиксируйте входы и выходы.
Для каждого состояния полезно описать:
- какие данные оно принимает,
- какие данные должно вернуть,
- какие поля обновляет в общем контексте.
- Закладывайте проверки.
Включайте состояния‑валидации: пусть агент пересматривает свои же результаты или проверяет, выполнены ли критерии завершения шага.
- Начинайте с простого.
Сначала опишите короткие процессы из 3–5 шагов, обкатайте подход, а уже потом усложняйте стейт‑машину, добавляя ветвления и циклы.
Ограничения и риски
Несмотря на преимущества, важно трезво понимать ограничения:
- Качество зависит от модели.
Если сама LLM выдаёт слабые результаты, никакая стейт‑машина не сделает волшебства: она лишь гарантирует, что слабые ответы будут выданы во всех нужных местах.
- Не всё можно алгоритмизировать.
Есть задачи, где попытка загнать работу в жёсткий автомат только мешает (чистое творчество, мозговой штурм, поиск идей без заранее заданной структуры).
- Стоимость разработки workflow.
Хорошая стейт‑машина — это труд: нужно продумать шаги, ошибки, ветвления, проверки. Зато потом такой сценарий можно многократно переиспользовать и масштабировать.
Куда можно развивать подход
Детерминированные агенты на основе стейт‑машин открывают широкий простор для дальнейшего развития:
- Автоматическое извлечение процессов из текстовых инструкций и регламентов.
- Обучение агентов проектированию и улучшению собственных стейт‑машин по результатам работы.
- Интеграция с системами управления задачами и CI/CD, чтобы агенты становились полноценной частью инженерной инфраструктуры.
- Создание библиотек типовых workflow для разных доменов: разработка, аналитика, поддержка, маркетинг.
Главное, что даёт такой подход, — управляемость. Вместо того чтобы надеяться, что достаточно «хитро» описанный промпт заставит модель вести себя как надо, мы выносим логику процесса в отдельный, детерминированный слой. Агенты остаются тем, чем они и являются по природе, — вероятностными генераторами. Но теперь они встроены в предсказуемый, прозрачный и контролируемый алгоритм.



