본문으로 건너뛰기

비동기 핸드오프

워크플로가 발견된 작업을 하나의 실행 안에 두는 대신 독립적인 최상위 워크플로로 넘겨야 할 때 start_workflows()을 사용하세요.

에이전트 실행을 명시적으로 모델링한다면 start_agents()과 wait_for_agents()은 에이전트 중심 기본값을 사용하는 의미상 별칭입니다.

더 큰 규모의 종단 간 예시는 에이전트 오케스트레이션을 참조하세요.

다음과 같은 에이전트 방식의 오케스트레이션에 유용합니다:

  • 플래너 워크플로가 런타임에 작업을 발견합니다
  • 각 작업은 자체적인 내구성 있는 워크플로가 됩니다
  • 부모는 해당 워크플로 ID를 상태에 저장합니다
  • 부모는 나중에 all, any, quorum 또는 이름이 지정된 시작 그룹을 기다릴 수 있습니다

->start_workflows() 메서드

PHP
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 ] );

이 예제에서는 다음과 같습니다.

  1. PlanTopicsStep이 주제 페이로드 배열을 $state['topics']에 기록합니다
  2. start_workflows()가 주제마다 agent_task 워크플로 하나를 실행합니다
  3. 시작된 워크플로 ID가 $state['child_workflow_ids']에 기록됩니다
  4. 시작된 그룹이 선택한 완료 조건을 충족할 때까지 wait_for_workflow_group()가 일시 중지됩니다
  5. SynthesizeBriefStep이 완료된 자식 상태를 $state['child_results'] 아래에 받습니다

자식 페이로드

items_key의 각 항목은 시작된 워크플로 하나의 초기 페이로드가 됩니다.

항목이 배열이면 공개 키가 자식 페이로드에 병합됩니다:

PHP
[
    [ 'topic' => 'pricing', 'source' => 'competitors' ],
    [ 'topic' => 'reviews', 'source' => 'customers' ],
]

항목이 스칼라면 Queuety이 이를 payload_key 아래에 저장합니다:

PHP
->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()은 워크플로 종속성과 함께 사용하도록 설계되었습니다:

PHP
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()의 별칭입니다.

PHP
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 ] );