Асинхронная передача задач
Используйте start_workflows(), когда рабочему процессу нужно передать обнаруженные задачи независимым рабочим процессам верхнего уровня, а не выполнять всё в одном запуске.
Если вы явно моделируете запуски агентов, start_agents() и wait_for_agents() — семантические псевдонимы со значениями по умолчанию для сценариев с агентами.
Примеры полного цикла см. в разделе Оркестрация агентов.
Это полезно для оркестрации в стиле агентов:
- рабочий процесс планировщика обнаруживает задачи во время выполнения
- каждая задача становится отдельным надёжным рабочим процессом
- родительский процесс сохраняет идентификаторы этих рабочих процессов в состоянии
- родительский процесс может позже дождаться
all,any,quorumили именованной запущенной группы
Метод ->start_workflows()
use Queuety\Enums\WaitMode;
use Queuety\Queuety;
$agent_task = Queuety::workflow( 'agent_task' )
->then( ResearchTopicStep::class )
->then( SummarizeTopicStep::class );
Queuety::workflow( 'brief_research' )
->then( PlanTopicsStep::class )
->start_workflows(
items_key: 'topics',
workflow_builder: $agent_task,
result_key: 'child_workflow_ids',
group_key: 'researchers',
)
->wait_for_workflow_group( 'researchers', WaitMode::All, result_key: 'child_results' )
->then( SynthesizeBriefStep::class )
->dispatch( [ 'brief_id' => 42 ] );
В этом примере:
PlanTopicsStepзаписывает массив полезных нагрузок тем в$state['topics']start_workflows()запускает отдельный рабочий процессagent_taskдля каждой темы- Идентификаторы запущенных рабочих процессов записываются в
$state['child_workflow_ids'] wait_for_workflow_group()приостанавливается, пока запущенная группа не выполнит выбранное условие завершенияSynthesizeBriefStepполучает завершённые состояния дочерних процессов в$state['child_results']
Полезные нагрузки дочерних процессов
Каждый элемент в items_key становится исходной полезной нагрузкой для одного запущенного рабочего процесса.
Если элемент является массивом, его публичные ключи объединяются с полезной нагрузкой дочернего процесса:
[
[ 'topic' => 'pricing', 'source' => 'competitors' ],
[ 'topic' => 'reviews', 'source' => 'customers' ],
]
Если элемент является скалярным значением, Queuety сохраняет его в payload_key:
->start_workflows(
items_key: 'topic_names',
workflow_builder: $agent_task,
payload_key: 'topic',
)
Наследование состояния родительского процесса
По умолчанию start_workflows() объединяет публичное состояние родительского рабочего процесса с полезной нагрузкой каждого дочернего процесса.
Это означает, что общий контекст, например brief_id, account_id или campaign, автоматически доступен в каждом запущенном рабочем процессе.
Исходные данные items_key и result_key исключаются из наследования, чтобы каждый дочерний процесс не получал весь список задач или итоговый массив идентификаторов рабочих процессов.
Задайте inherit_state: false, если каждый дочерний процесс должен получать только полезную нагрузку своего элемента.
Почему не run_workflow()?
run_workflow() создаёт связь родительского и дочернего процессов: родитель приостанавливается на этом шаге до завершения дочернего процесса.
start_workflows() действует более независимо:
- запущенные рабочие процессы являются независимыми процессами верхнего уровня
- каждый из них можно отдельно проверять, повторять или экспортировать
- родительский процесс позднее решает, нужно ли ждать их и каким образом
Поэтому start_workflows() лучше подходит для асинхронной передачи задач агентам, а run_workflow() — для вложенной композиции в одном дереве оркестрации.
Ожидание на более позднем этапе
start_workflows() предназначен для совместного использования с Зависимостями рабочего процесса:
use Queuety\Enums\WaitMode;
Queuety::workflow( 'review_board' )
->start_workflows( 'review_tasks', $review_task_workflow, 'review_workflow_ids' )
->wait_for_workflows( 'review_workflow_ids', WaitMode::Any, 'winner' )
->then( FinalizeDecisionStep::class )
->dispatch( $payload );
WaitMode::Allсобирает все завершённые состояния дочерних процессовWaitMode::Anyвозобновляется после первого успешно завершившегося дочернего рабочего процесса
Это позволяет организовать работу планировщика и исполнителя без полноценного механизма DAG с возможностью менять структуру во время выполнения.
Псевдонимы для сценариев с агентами
start_agents() — это псевдоним start_workflows() со значениями по умолчанию для сценариев с планировщиком и исполнителем:
- Для
result_keyпо умолчанию заданоagent_workflow_ids - Для
payload_keyпо умолчанию заданоagent_task - Для
nameпо умолчанию заданоstart_agents
wait_for_agents() — это псевдоним wait_for_workflows() со значениями по умолчанию для сбора результатов агентов:
- Для
workflowsпо умолчанию заданоagent_workflow_ids - Для
result_keyпо умолчанию заданоagent_results - Для
nameпо умолчанию заданоwait_for_agents
wait_for_agent_group() — это псевдоним wait_for_workflow_group() со значениями по умолчанию для пакетов задач агентов.
use Queuety\Enums\WaitMode;
$agent_run = Queuety::workflow( 'agent_run' )
->then( ResearchTopicStep::class )
->then( SummarizeTopicStep::class );
Queuety::workflow( 'brief_research' )
->then( PlanTopicsStep::class )
->start_agents( 'agent_tasks', $agent_run, group_key: 'researchers' )
->wait_for_agent_group( 'researchers', WaitMode::Quorum, 2 )
->then( SynthesizeBriefStep::class )
->dispatch( [ 'brief_id' => 42 ] );