Разделение ролей READ, ANALYZE, DRAFT и EXECUTE в бизнес-агенте необходимо для предотвращения галлюцинаций, разгрузки контекста и повышения точности решений. Это достигается физическим или логическим разделением потоков данных: агент сначала собирает факты (READ), затем формирует гипотезы на их основе (ANALYZE), создает черновик ответа или плана действий (DRAFT) и только после проверки выполняет финальное действие (EXECUTE). Такой подход позволяет изолировать ошибки анализа от ошибок исполнения и дает возможность корректировать логику до момента изменения реального состояния системы.
Разделение ролей в архитектуре бизнес-агента: READ, ANALYZE, DRAFT, EXECUTE
Архитектура бизнес-агента строится на четком разделении функций обработки информации. Разделение ролей READ (чтение), ANALYZE (анализ), DRAFT (черновик) и EXECUTE (выполнение) позволяет избежать хаоса в логике принятия решений. Каждая стадия выполняет строго определенную задачу, что снижает вероятность ошибок и повышает предсказуемость результата.
READ отвечает за сбор и первичную фильтрацию данных. На этом этапе агент извлекает информацию из внешних источников или внутренней базы знаний, проверяет актуальность запроса и формирует контекст для дальнейшей работы. Результатом этой стадии является структурированный набор фактов без интерпретации.
ANALYZE занимается логической обработкой полученных данных. Здесь происходит сопоставление фактов с правилами бизнеса, выявление противоречий в запросе клиента и оценка рисков. Эта стадия не генерирует готовые ответы, а формирует план действий или набор гипотез для проверки.
DRAFT создает варианты текстовых или логических решений на основе выводов анализа. На этом этапе формируется черновик ответа, скрипт действия или структура документа. Важно, что на стадии DRAFT еще не происходит взаимодействия с внешними системами — это только подготовка контента.
EXECUTE реализует запланированные действия. Это финальная стадия, где черновик отправляется клиенту, данные сохраняются в базе, платежный шлюз обрабатывается или документ подписывается цифровым ключом. Эта роль требует строгой проверки прав доступа и подтверждения транзакции перед выполнением.
Разделение потоков данных между этими ролями критично для безопасности. Если агент сразу переходит от чтения к выполнению без анализа, он может совершить ошибку на основе недостоверной информации или некорректно интерпретированный запрос. Изоляция стадий позволяет легко отлаживать каждый этап отдельно.
В практической реализации это означает создание отдельных модулей или цепочек вызовов для каждой роли. Модуль READ возвращает сырые данные, модуль ANALYZE выдает метаданные и вердикты, модуль DRAFT генерирует текст, а модуль EXECUTE инициирует внешние API-вызовы. Такая структура упрощает поддержку системы и позволяет масштабировать отдельные компоненты независимо.
Техническая реализация разделения потоков данных и логики
Разделение архитектуры на четыре роли — READ, ANALYZE, DRAFT, EXECUTE — требует физической изоляции их выполнения в коде. Это достигается за счет создания отдельных функций или классов для каждого этапа обработки запроса. Модуль READ отвечает исключительно за получение данных из источников: баз данных, внешних API или файловых систем. Он не должен содержать логику анализа или генерации текста. Его задача — вернуть структурированный объект с сырыми данными и метаданными о источнике.
Модуль ANALYZE принимает данные от READ и выполняет их обработку. На этом этапе происходит валидация, фильтрация и формирование контекста для дальнейшей работы. Результатом работы этого модуля является не просто текст, а структурированный объект, содержащий выводы, метаданные и вердикты относительно полученных данных. Он передает этот объект модулю DRAFT, который отвечает за генерацию текста ответа или документа.
Модуль DRAFT использует контекст от ANALYZE для создания итогового контента. Этот этап может включать в себя как простую генерацию текста, так и работу с шаблонами. Важно, чтобы этот модуль не пытался выполнять действия в реальном мире, такие как отправка писем или изменение записей в базе данных. Эти операции делегируются модулю EXECUTE.
Модуль EXECUTE получает готовый текст от DRAFT и выполняет внешние действия: отправляет уведомления, сохраняет файлы, обновляет статусы заказов или делает вызовы к платежным шлюзам. Он работает с результатами генерации, но не участвует в их создании. Такая последовательность гарантирует, что ошибка на этапе анализа не приведет к выполнению вредоносных команд, а ошибка генерации текста не изменит состояние базы данных.
В коде это реализуется через цепочку вызовов или паттерн Pipeline. Каждый шаг возвращает объект с данными и статусом выполнения. Если на каком-то этапе возникает ошибка, система может вернуть сигнал назад в цепочку для обработки исключения или перезапуска конкретного модуля. Это позволяет изолировать сбои: падение модуля DRAFT не должно блокировать работу READ или ANALYZE.
Для передачи данных между модулями используется единый формат обмена, например JSON. Он должен содержать поля с сырыми данными, метаданными о источнике и статусом обработки. Это упрощает отладку, так как можно проследить путь данных от момента их получения до момента выполнения действия. Логи каждого модуля фиксируют входные данные и выходные параметры, что помогает выявлять узкие места в обработке.
При работе с локальными моделями, такими как Ollama, эта архитектура позволяет гибко настраивать потоки данных. Модуль READ может формировать запрос к API модели для получения информации, модуль ANALYZE — обрабатывать ответ и формировать промпт для генерации, а модуль EXECUTE — отправлять результат пользователю или в систему учета. Использование HTTP-интерфейса REST API обеспечивает стандартизацию взаимодействия между компонентами.
Изоляция окружения через Docker позволяет запускать каждый модуль как отдельный контейнер или объединять их в единый сервис с четким разделением зон ответственности. Это гарантирует, что зависимости одного этапа не конфликтуют с другими. Например, модуль ANALYZE может требовать специфичных библиотек для обработки данных, а модуль EXECUTE — драйверов для работы с базами данных. Контейнеризация решает эти проблемы автоматически.
Такая структура упрощает поддержку системы и позволяет масштабировать отдельные компоненты независимо. Если нагрузка на генерацию текста возрастает, можно добавить больше инстансов модуля DRAFT без изменения логики READ или ANALYZE. Это критически важно для бизнеса, где требования к производительности могут меняться со временем.
Критерии выбора границ между этапами для предотвращения ошибок
Границы между модулями READ, ANALYZE, DRAFT и EXECUTE определяются не линией кода, а изменением типа данных и цели обработки. Ошибка возникает, когда данные из одного контекста передаются в другой без трансформации их формата или семантики. Например, сырые текстовые логи (READ) нельзя напрямую использовать для принятия логических решений (ANALYZE), так как там отсутствует структурированная информация о статусе и приоритетах.
Первый критерий — изменение структуры данных. Модуль READ возвращает необработанные данные: текст, изображения, метадаты запроса. Граница с ANALYZE наступает в момент конвертации этого потока в объекты с полями типа «статус», «категория», «уровень риска». Если система пытается анализировать сырой текст без предварительной разметки, нейросеть будет выдавать галлюцинации или игнорировать контекст. Разделение происходит там, где данные становятся машиночитаемыми объектами.
Второй критерий — переход от анализа к генерации контента. Граница между ANALYZE и DRAFT пролегает в момент формирования шаблона ответа. До этого этапа система накапливает факты и формирует план действий. После пересечения границы модуль DRAFT начинает работать с переменными, подставляя их в заранее утвержденные структуры (шаблоны писем, отчетов, скриптов). Попытка генерировать текст без четкого плана анализа приводит к несогласованности тона и фактических ошибок.
Третий критерий — переход от текста к действию. Граница между DRAFT и EXECUTE является самой жесткой. Здесь происходит конвертация текстового описания действия в исполняемую команду или API-запрос. Любая неопределенность в тексте плана (DRAFT) недопустима на этом этапе. Если модуль DRAFT выдал текст с вариантами выбора, а EXECUTE должен был выполнить одно конкретное действие, система должна вернуть ошибку или запросить уточнение, не переходя к исполнению.
Практический пример ошибки: клиент пишет «отправьте счет». Модуль READ фиксирует это. Модуль ANALYZE определяет, что речь о коммерческом предложении, и формирует план. Если граница между анализом и генерацией размыта, модуль DRAFT может сразу сгенерировать текст счета, не проверив наличие реквизитов клиента в базе. Затем EXECUTE попытается отправить файл с пустыми полями или неверными данными. Четкая граница требует, чтобы на выходе ANALYZE был готовый набор данных (JSON-объект), который DRAFT использует только для заполнения шаблона.
Четвертый критерий — уровень неопределенности. Границы должны сужаться по мере удаления от источника данных к точке исполнения. В READ допустимы противоречия и шум. В ANALYZE они должны быть выделены в отдельные метки. В DRAFT они трансформируются в комментарии или альтернативные варианты текста. В EXECUTE неопределенность должна быть полностью устранена или явно обозначена как условие для остановки процесса. Если модуль EXECUTE получает команду с пометкой «вероятность успеха 60%», он должен запросить подтверждение у оператора, а не пытаться выполнить действие автоматически.
Пятый критерий — обратная связь и цикличность. Границы между этапами должны быть проницаемыми для ошибок. Если EXECUTE не смог выполнить действие (например, API-сервер недоступен), сигнал должен вернуться в модуль ANALYZE или DRAFT для пересмотра стратегии. Это означает, что данные о результате исполнения становятся входными данными для следующего цикла чтения и анализа. Разделение потоков должно обеспечивать возможность возврата на предыдущий этап без потери контекста.
Оценка правильности выбора границ проводится через тестирование на граничных случаях. Создайте сценарии, где данные содержат неполную информацию или противоречия. Проверьте, не переходит ли модуль DRAFT к генерации текста, пока ANALYZE еще не завершил сбор всех фактов. Убедитесь, что EXECUTE никогда не запускается без валидированного объекта плана. Если система работает стабильно на таких тестах, границы выбраны корректно.
Ограничения локальных моделей усугубляют необходимость четких границ. Локальные модели Ollama имеют лимиты по памяти и времени вывода. Если модуль ANALYZE будет пытаться обработать слишком большой объем сырых данных сразу, это приведет к переполнению контекста или зависанию процесса. Разделение потоков позволяет ограничивать нагрузку на каждом этапе: READ фильтрует шум, ANALYZE структурирует оставшееся, DRAFT генерирует только необходимый фрагмент, а EXECUTE выполняет точечные действия.
В бизнес-среде ошибки на стыке модулей стоят дороже всего. Если модуль DRAFT сгенерировал текст, основанный на неверном анализе, это может привести к отправке ошибочного коммерческого предложения. Четкое разделение ответственности между этапами позволяет локализовать ошибку: если ANALYZE не нашел ключевого факта, система не должна генерировать ответ, а должна запросить уточнение у пользователя или оператора.
Рекомендация по реализации: используйте явные маркеры завершения этапов. В коде это могут быть специфичные типы возвращаемых значений или флаги состояния. Например, объект с полем «status»: «ready_for_draft» сигнализирует о готовности к переходу на следующий этап. Избегайте передачи сырых строк между модулями. Всегда конвертируйте данные в промежуточные структуры, которые содержат только необходимую для следующего этапа информацию.
Итоговый принцип: граница существует там, где меняется природа данных и цели обработки. READ работает с фактами, ANALYZE — с выводами, DRAFT — с контентом, EXECUTE — с действиями. Пересечение этих зон без трансформации данных является главной причиной нестабильности агентов. Соблюдение этого правила позволяет строить системы, которые не просто генерируют текст, а решают задачи бизнеса с минимальным риском ошибок.
4. Примеры сценариев обработки запросов клиента
Разделение ролей READ, ANALYZE, DRAFT и EXECUTE становится очевидным при анализе конкретных ситуаций взаимодействия с клиентом. В каждом случае поток данных проходит через четкие границы: от получения фактов до выполнения действия. Ниже приведены три типичных сценария, демонстрирующих, как агент должен распределять задачи между модулями.
Сценарий 1: Обработка входящей заявки на консультацию. Клиент пишет в чат: «Хочу узнать стоимость разработки сайта под интернет-магазин». Модуль READ фиксирует факт обращения и извлекает ключевые параметры: тип услуги (разработка сайта), цель (интернет-магазин). Эти данные передаются в модуль ANALYZE, который сверяет запрос с базой знаний о тарифах и возможностях компании. Если клиент уточняет детали («нужен каталог до 100 товаров»), анализ корректирует параметры задачи. Модуль DRAFT формирует ответ: «Стоимость зависит от функционала. Для каталога до 100 товаров базовый вариант начинается от Х рублей, но точную смету подготовим после анализа ТЗ». Ответ не содержит конкретных цифр без подтверждения, а предлагает следующий шаг. Модуль EXECUTE не вмешивается на этом этапе, так как действие (отправка письма или создание задачи) еще не инициировано клиентом.
Сценарий 2: Автоматизация ответа на частый вопрос о домене. Клиент спрашивает: «Как выбрать доменное имя?». Модуль READ получает текст вопроса и проверяет наличие в базе знаний информации о влиянии домена на доверие. Модуль ANALYZE структурирует ответ, опираясь на подтвержденный факт: «Доменное имя формирует первое впечатление о компании и влияет на доверие клиента». Модуль DRAFT создает текст ответа с рекомендациями по выбору короткого и понятного имени. Здесь важно не выдать за готовое решение пример из кейса, а дать универсальный совет. Если клиент просит «подобрать варианты», модуль EXECUTE может инициировать поиск свободных доменов через внешний API или создание задачи для менеджера, но только после явного подтверждения пользователя.
Сценарий 3: Работа с ошибкой в процессе заказа. Клиент сообщает: «Не могу добавить товар в корзину». Модуль READ фиксирует ошибку и данные о клиенте. Модуль ANALYZE проверяет логику корзины и доступность товара на складе. Если ошибка вызвана отсутствием товара, анализ формирует сообщение об этом. Модуль DRAFT готовит текст: «Товар временно недоступен, но мы можем предложить аналог». Модуль EXECUTE отправляет это сообщение клиенту и создает задачу для отдела закупок по пополнению ассортимента. Ключевой момент: модуль EXECUTE не предпринимает действий без явного разрешения или четкого алгоритма, заложенного в анализе.
В этих примерах видно, что переход от READ к ANALYZE происходит при необходимости интерпретации фактов, а от DRAFT к EXECUTE — только после формирования готового контента и получения триггера для действия. Нарушение этой последовательности, например, когда модуль EXECUTE пытается выполнить действие без завершения этапа DRAFT, приводит к ошибкам: клиент получает неготовый ответ или действие выполняется в неподходящий момент. Правильное распределение ролей позволяет агенту оставаться гибким и безопасным.
При построении таких сценариев важно учитывать ограничения локальных моделей. Если задача требует доступа к внешним базам данных или сложной логики, модуль ANALYZE должен четко формулировать запрос к инструментам, а не полагаться на галлюцинации модели. Модуль DRAFT отвечает за стиль и тон общения, но не за фактологическую точность — это зона ответственности ANALYZE. Модуль EXECUTE выполняет только те действия, которые были явно одобрены результатами анализа.
Для оценки качества работы агента в этих сценариях используйте метрику: сколько раз модуль EXECUTE предпринял действие без подтверждения на этапе ANALYZE. В идеале таких случаев должно быть ноль. Также проверяйте, не «перепрыгивает» ли агент этап DRAFT, пытаясь сразу выполнить задачу. Если клиент просит «написать письмо», а агент сразу отправляет его — это ошибка архитектуры. Письмо должно быть сгенерировано DRAFT и проверено на соответствие требованиям перед передачей в EXECUTE.
Практический совет: при тестировании агента создайте набор из 20–30 типовых запросов, включая нестандартные ситуации (ошибки, уточнения, отказ от услуги). Проанализируйте логи каждого сценария и убедитесь, что переход между модулями происходит строго по границам. Если в процессе работы обнаруживается необходимость изменения границ — например, когда анализ требует больше времени, чем планировалось — пересмотрите архитектуру. Иногда проще добавить промежуточный этап проверки, чем допускать ошибки на этапе исполнения.
Ограничения локальных моделей при выполнении сложных задач
Локальные языковые модели, развернутые на стороне клиента (например, через Ollama), обладают фундаментальными ограничениями по сравнению с облачными решениями. Эти ограничения диктуют границы применимости архитектуры агента и требуют четкого разделения ответственности между этапами READ, ANALYZE, DRAFT и EXECUTE.
Главное ограничение — объем контекстного окна и способность удерживать информацию о предыдущих шагах. Локальная модель может «забыть» детали из начала длинной переписки или потерять связь с исходными данными, если они не помещаются в текущий контекст. Это приводит к ошибкам на этапе ANALYZE, когда агент пытается синтезировать ответ без учета всей истории взаимодействия.
Второй критический фактор — вычислительная мощность и скорость генерации. Локальные модели требуют значительных ресурсов оперативной памяти (RAM) и видеопамяти (VRAM). При попытке выполнить сложную аналитику или обработку больших объемов данных в реальном времени, модель может начать «думать» слишком долго, что нарушает требования к интерактивности бизнес-приложения. В таких случаях этап ANALYZE следует выносить за пределы локального агента или использовать упрощенные алгоритмы.
Третье ограничение — отсутствие доступа к внешним инструментам в реальном времени без явного вызова. Локальная модель не может самостоятельно искать актуальные данные в интернете, проверять статусы API или читать файлы с диска, если это не настроено через специальные инструменты (tools). Если архитектура агента предполагает выполнение действий EXECUTE (отправка письма, создание записи в CRM), локальная модель должна строго следовать инструкциям и не пытаться имитировать эти действия текстом.
Четвертое ограничение — качество знаний о специфических бизнес-процессах. Модель обучена на общих данных и может не знать внутренних регламентов компании, если они не были явно переданы в контекст. Попытка выполнить задачу, требующую знания уникальных процедур без их предварительного описания, приведет к галлюцинациям или отказу от выполнения.
Практический совет: при проектировании агента с локальной моделью всегда предусматривайте возможность деградации функционала. Если модель не справляется со сложным анализом, система должна автоматически переключаться на упрощенный шаблон ответа или перенаправлять запрос в облако, если это предусмотрено архитектурой. Не полагайтесь на то, что одна и та же модель будет одинаково хорошо справляться с генерацией текста и выполнением кода.
Для минимизации рисков используйте модульный подход: этап READ может быть реализован через простой парсер данных, а этап EXECUTE — через вызов готовых API-интерфейсов. Локальная модель отвечает только за синтез ответа (DRAFT) на основе предоставленных ей фактов. Это снижает нагрузку на систему и повышает предсказуемость поведения агента.
Оценка результата работы локального агента должна включать проверку не только текстового вывода, но и корректности выполнения действий. Если агент должен был отправить уведомление, а модель просто написала «Я отправил уведомление», это ошибка реализации этапа EXECUTE. Локальная модель не может подтвердить факт выполнения действия без явного сигнала от внешнего сервиса.
В заключение: локальные модели отлично подходят для задач генерации текста, суммаризации и простых логических выводов в рамках заданного контекста. Для сложных аналитических задач или работы с большими объемами данных их следует использовать с осторожностью, дополняя внешними инструментами и четкими правилами разделения ответственности между этапами.
Вопросы и ответы
Как определить момент перехода от ANALYZE к DRAFT?
Переход происходит, когда сырые данные и выводы анализа трансформируются в структурированный план действий или черновик ответа. На этом этапе формируется конкретная последовательность шагов для выполнения (EXECUTE), а не просто констатация фактов.
Что делать, если локальная модель не может выполнить сложную задачу EXECUTE?
Архитектура должна предусматривать возможность делегирования этапа EXECUTE внешнему инструменту или API. Модуль DRAFT формирует запрос к этому инструменту, а модуль READ получает результат выполнения и возвращает его в общий контекст для финальной сборки ответа.
Можно ли объединять этапы ANALYZE и DRAFT?
Объединение возможно только при низкой сложности задачи, но это снижает надежность системы. Если анализ требует поиска противоречий или оценки рисков, а черновик — формулировки ответа клиенту, их разделение предотвращает попадание внутренних рассуждений модели в финальный текст.


