异步交接
当工作流需要将发现的工作交给独立的顶层工作流,而不是将所有内容保留在单次运行中时,使用 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_idspayload_key默认值为agent_taskname默认值为start_agents
wait_for_agents() 是 wait_for_workflows() 的别名,采用适合收集智能体结果的默认值:
workflows默认值为agent_workflow_idsresult_key默认值为agent_resultsname默认值为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 ] );