Pular para o conteúdo

Neuron Fluxos de trabalho dependentes

Este exemplo responde a uma pergunta comum sobre agentes:

Um fluxo de trabalho pode decidir que outro só deve continuar depois que um fluxo anterior terminar?

Sim. A nuance importante é que Queuety já oferece suporte a isso com wait_for_workflow() e wait_for_workflows().

Isso significa que:

  • o fluxo de trabalho X pode ser despachado agora
  • X pode aguardar em waiting_for_workflows
  • X só retoma quando o fluxo de trabalho Y é concluído

Exemplo: pesquisar primeiro, escrever depois

Use um fluxo de trabalho de nível superior para montar um conjunto de pesquisa e um segundo fluxo de trabalho de nível superior para redigir o texto final.

Fluxo de trabalho de pesquisa

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

$research_agent = Queuety::workflow('research_agent')
    ->then(ResearchTopicStep::class);

$research_id = Queuety::workflow('research_packet')
    ->then(PlanResearchTasksStep::class)
    ->start_agents('agent_tasks', $research_agent)
    ->wait_for_agents(mode: WaitMode::All, result_key: 'agent_results')
    ->then(SynthesizeResearchPacketStep::class)
    ->dispatch([
        'brief_id' => 42,
        'provider' => 'anthropic',
    ]);

Fluxo de trabalho de redação

PHP
Queuety::workflow('write_brief')
    ->wait_for_workflow('research_workflow_id', 'research')
    ->then(WriteBriefWithNeuronStep::class)
    ->wait_for_decision(result_key: 'editor_review')
    ->then(PublishBriefStep::class)
    ->dispatch([
        'brief_id' => 42,
        'research_workflow_id' => $research_id,
        'provider' => 'openai',
    ]);

Quando o fluxo de trabalho de redação começa, ele pausa imediatamente em waiting_for_workflows até que o fluxo de trabalho de pesquisa seja concluído com sucesso.

A etapa de redação Neuron

PHP
namespace App\Workflow\Steps;

use App\Neuron\WriterAgent;
use NeuronAI\Chat\Messages\UserMessage;
use Queuety\Step;

final class WriteBriefWithNeuronStep implements Step
{
    public function handle(array $state): array
    {
        $agent = new WriterAgent(
            providerName: $state['provider'] ?? 'openai',
        );

        $message = $agent->chat(
            new UserMessage(sprintf(
                "Write the final brief for brief %d using this research packet:\n\n%s",
                $state['brief_id'],
                json_encode($state['research'], JSON_PRETTY_PRINT),
            ))
        )->getMessage();

        return [
            'draft_markdown' => $message->getContent(),
        ];
    }

    public function config(): array
    {
        return [];
    }
}

$state['research'] está disponível porque wait_for_workflow() copiou o estado público concluído do fluxo de trabalho de dependência para o fluxo de trabalho atual, usando a chave research.

Quando usar isso em vez de um único fluxo de trabalho enorme

Prefira fluxos de trabalho de nível superior separados quando:

  • as etapas têm responsáveis ou ciclos operacionais diferentes
  • você quer inspecioná-las e tentar executá-las novamente de forma independente
  • uma etapa posterior deve poder ser despachada antes mesmo da conclusão da anterior

Prefira um único fluxo de trabalho quando:

  • as etapas são fortemente interligadas
  • elas compartilham um ciclo de vida e um conjunto de estados

Onde uma máquina de estados se encaixa

Se esse fluxo de redação fizer parte de uma sessão editorial de longa duração, deixe uma máquina de estados gerenciar o ciclo de vida externo e use estes fluxos de trabalho para as etapas de execução com escopo definido. Assim, estados do ciclo de vida como awaiting_brief, researching, awaiting_review e completed ficam explícitos, preservando a durabilidade do fluxo de trabalho em cada fase.

Uma distinção importante

Este padrão significa que:

  • X existe agora, mas aguarda por Y

Isso não significa que:

  • X só é criado depois que Y termina

Se você quiser o segundo comportamento, faça um fluxo de trabalho pai aguardar por Y e só então chamar start_workflows() ou start_agents() para X.