Pular para o conteúdo

Orquestração de agentes

Queuety é adequado para sistemas de agentes quando você quer um trabalho adaptável sem abrir mão de estado duradouro, novas tentativas, inspeção e semântica explícita de espera.

Você não precisa de um mecanismo DAG editável em tempo de execução para a maioria dos fluxos de agentes. Na prática, a maioria dos sistemas pode ser modelada com um pequeno conjunto de operações de orquestração duradouras. for_each() expande o trabalho dentro de uma execução de workflow. start_agents() e wait_for_agents() encaminham o trabalho descoberto em tempo de execução para workflows independentes de nível superior. wait_for_decision() e wait_for_input() pausam para permitir controle humano. wait_for_workflow(), wait_for_workflows() e wait_for_agent_group() permitem que uma execução de nível superior aguarde outra execução ou que um grupo iniciado alcance o quórum definido.

Um modelo mental útil

É mais fácil raciocinar sobre a orquestração de agentes quando ela é dividida em camadas. Um planejador decide qual trabalho existe. Queuety transforma esse trabalho em jobs ou workflows duradouros. As execuções especializadas produzem resultados e armazenam artefatos. Uma etapa supervisora agrega esses resultados e decide o que acontece em seguida. A qualquer momento, uma pessoa pode aprovar, rejeitar ou corrigir a execução antes que ela continue.

A distinção importante é que o agente decide qual trabalho realizar, mas Queuety continua decidindo como esse trabalho é persistido, repetido, retomado e agregado. Quando o destino da orquestração é uma sessão duradoura, em vez de uma execução limitada, combine isso com Máquinas de Estado.

Padrão 1: planejador e executor com execuções independentes de agentes

Use start_agents() quando uma etapa do planejador descobrir tarefas em tempo de execução e cada tarefa precisar se tornar seu próprio workflow de nível superior.

PHP
use Queuety\Enums\WaitMode;
use Queuety\Queuety;

$agent_run = Queuety::workflow( 'agent_run' )
    ->then( FetchSourcesStep::class )
    ->then( DraftFindingStep::class );

Queuety::workflow( 'brief_research' )
    ->version( 'brief-research.v1' )
    ->idempotency_key( 'brief:42:research' )
    ->max_transitions( 20 )
    ->then( PlanResearchTasksStep::class )
    ->start_agents( 'agent_tasks', $agent_run, group_key: 'researchers' )
    ->wait_for_agent_group( 'researchers', WaitMode::Quorum, 2, 'agent_results' )
    ->then( SynthesizeBriefStep::class )
    ->dispatch( [ 'brief_id' => 42 ] );

Nesse padrão, PlanResearchTasksStep grava os itens descobertos em tempo de execução em $state['agent_tasks'], start_agents() despacha um workflow duradouro por tarefa e wait_for_agent_group() suspende o processo pai até que a condição de conclusão escolhida seja satisfeita. Em seguida, SynthesizeBriefStep recebe os estados dos filhos concluídos em $state['agent_results'].

Esse é o ponto de partida mais simples para sistemas de planejador e executor, pois cada execução de agente continua sendo inspecionável e pode ser repetida de forma independente.

Padrão 2: revisão humana antes da continuação da execução

Use wait_for_decision() quando o workflow precisar parar para uma decisão real de sim ou não e wait_for_input() quando a pessoa responsável precisar enviar feedback estruturado de volta à execução.

PHP
use Queuety\Queuety;

$workflow_id = Queuety::workflow( 'brief_review' )
    ->then( DraftBriefStep::class )
    ->wait_for_decision( result_key: 'review' )
    ->then( HandleReviewDecisionStep::class )
    ->wait_for_input( result_key: 'revision_notes' )
    ->then( ApplyRevisionNotesStep::class )
    ->dispatch( [ 'brief_id' => 42 ] );

Se a pessoa revisora aprovar:

PHP
Queuety::approve_workflow(
    $workflow_id,
    [
        'reviewer' => 'editor@example.com',
        'notes' => 'Looks good, publish after legal check',
    ],
    'approved'
);

Se a pessoa revisora rejeitar:

PHP
Queuety::reject_workflow(
    $workflow_id,
    [
        'reviewer' => 'editor@example.com',
        'reason' => 'Needs citations and a stronger conclusion',
    ],
    'rejected'
);

Depois de wait_for_decision(), o workflow recebe um payload estruturado com o resultado final, o sinal que retomou a execução e quaisquer dados da pessoa revisora. Isso oferece um verdadeiro ponto de verificação com participação humana, sem manter um processo PHP aberto enquanto a execução aguarda.

Padrão 3: um workflow de nível superior aguarda outro

Às vezes, o modelo mais simples não é um workflow enorme. Um workflow pode concluir a pesquisa, e outro workflow pode aguardar essa conclusão antes de iniciar a próxima etapa.

PHP
use Queuety\Enums\WaitMode;
use Queuety\Queuety;

$research_id = Queuety::workflow( 'research_brief' )
    ->then( PlanResearchTasksStep::class )
    ->start_agents( 'agent_tasks', $agent_run )
    ->wait_for_agents( mode: WaitMode::All, result_key: 'agent_results' )
    ->then( SynthesizeBriefStep::class )
    ->dispatch( [ 'brief_id' => 42 ] );

Queuety::workflow( 'publish_brief' )
    ->wait_for_workflow( $research_id, 'research' )
    ->wait_for_decision( result_key: 'editor_review' )
    ->then( PublishBriefStep::class )
    ->dispatch( [ 'brief_id' => 42 ] );

Isso cria um limite duradouro entre a etapa de pesquisa e a etapa de publicação. Cada execução tem seu próprio ciclo de vida operacional, mas o segundo workflow ainda é retomado automaticamente quando a dependência é concluída.

Escolha da primitiva certa

for_each() é a ferramenta certa quando o trabalho pertence a uma única execução de workflow e as ramificações são apenas execuções paralelas no nível das etapas, usando um único conjunto de estado compartilhado.

start_agents() é mais adequado quando cada tarefa descoberta deve ser sua própria execução duradoura de nível superior e você quer inspecionar, repetir ou exportar essas execuções separadamente.

wait_for_workflow() e wait_for_workflows() são adequados quando um workflow de nível superior depende de outro e você quer coordenação assíncrona duradoura entre essas camadas de orquestração.

wait_for_decision() e wait_for_input() são adequados nos pontos em que uma pessoa precisa aprovar, rejeitar ou orientar a execução enquanto o workflow permanece pausado sem consumir capacidade de workers.

Convenções de estado sugeridas

Sistemas de agentes são mais fáceis de depurar quando as chaves de estado são previsíveis. Na prática, agent_tasks funciona bem para a saída do planejador, agent_workflow_ids para as execuções de nível superior iniciadas, agent_results para o estado dos workflows filhos concluídos e review ou decision para os payloads de aprovação ou rejeição. Saídas maiores, como rascunhos, citações ou manifestos de pesquisa, geralmente devem ficar no armazenamento de artefatos, em vez do conjunto de estado principal do workflow.

Workflows de agentes se beneficiam de proteções mais do que quase qualquer outro caso de uso, pois são dinâmicos por natureza.

PHP
Queuety::workflow( 'agent_research' )
    ->version( 'agent-research.v2' )
    ->idempotency_key( 'brief:42:agent-research' )
    ->max_transitions( 20 )
    ->max_for_each_items( 12 )
    ->max_state_bytes( 32768 );

Esses controles respondem às perguntas práticas que importam em produção: qual versão da definição produziu uma execução, se solicitações externas duplicadas podem despachá-la duas vezes, se um planejador pode criar ramificações demais e se o estado do workflow pode crescer sem limite. Na maioria dos sistemas de agentes, comece por essas proteções antes de ajustar a quantidade de workers ou a topologia das filas.

Veja também