Vai al contenuto

Neuron Workflow dipendenti

Questo esempio risponde a una domanda comune sugli agenti:

Un workflow può decidere che un altro debba proseguire solo dopo che è terminato un workflow precedente?

Sì. La sfumatura importante è che Queuety supporta già questa funzionalità con wait_for_workflow() e wait_for_workflows().

Questo significa che:

  • il workflow X può essere avviato subito
  • X può restare in attesa in waiting_for_workflows
  • X riprende solo quando il workflow Y è completato

Esempio: prima la ricerca, poi la scrittura

Usa un workflow di livello superiore per creare un dossier di ricerca e un secondo workflow di livello superiore per redigere il testo finale.

Workflow di ricerca

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',
    ]);

Workflow di scrittura

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 il workflow di scrittura si avvia, si mette subito in pausa in waiting_for_workflows finché il workflow di ricerca non è stato completato correttamente.

Il passaggio di scrittura 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'] è disponibile perché wait_for_workflow() ha copiato lo stato pubblico completato del workflow dipendente nel workflow corrente, sotto la chiave research.

Quando usare questo approccio invece di un unico workflow enorme

Preferisci workflow separati di livello superiore quando:

  • le fasi hanno responsabili o cicli operativi diversi
  • vuoi esaminarle e riprovare a eseguirle in modo indipendente
  • una fase successiva deve poter essere avviata anche prima che termini quella precedente

Preferisci un unico workflow quando:

  • le fasi sono strettamente collegate
  • condividono un ciclo di vita e un unico contenitore di stato

Il ruolo di una macchina a stati

Se questo flusso di scrittura fa parte di una sessione editoriale di lunga durata, lascia che una macchina a stati gestisca il ciclo di vita esterno e usa questi workflow per le fasi di esecuzione circoscritte. In questo modo stati del ciclo di vita come awaiting_brief, researching, awaiting_review e completed restano espliciti, mantenendo la durabilità del workflow all'interno di ogni fase.

Una distinzione importante

Questo schema significa che:

  • X esiste già, ma attende Y

Questo non significa che:

  • X non viene creato finché Y non è terminato

Se vuoi ottenere il secondo comportamento, fai attendere un workflow principale a Y e solo dopo invoca start_workflows() o start_agents() per X.