비동기 핸드오프
워크플로가 발견된 작업을 하나의 실행 안에 두는 대신 독립적인 최상위 워크플로로 넘겨야 할 때 start_workflows()을 사용하세요.
에이전트 실행을 명시적으로 모델링한다면 start_agents()과 wait_for_agents()은 에이전트 중심 기본값을 사용하는 의미상 별칭입니다.
더 큰 규모의 종단 간 예시는 에이전트 오케스트레이션을 참조하세요.
다음과 같은 에이전트 방식의 오케스트레이션에 유용합니다:
- 플래너 워크플로가 런타임에 작업을 발견합니다
- 각 작업은 자체적인 내구성 있는 워크플로가 됩니다
- 부모는 해당 워크플로 ID를 상태에 저장합니다
- 부모는 나중에
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워크플로 하나를 실행합니다- 시작된 워크플로 ID가
$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은 상속에서 제외되므로 각 자식은 전체 작업 목록이나 최종 워크플로 ID 배열을 받지 않습니다.
각 자식이 항목 페이로드만 받아야 한다면 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 ] );