
# 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](https://queuety.inline0.dev/it/docs/state-machines) 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`.

## Documentazione correlata

- [Dipendenze del workflow](https://queuety.inline0.dev/it/docs/workflows/dependencies)
- [Passaggi asincroni](https://queuety.inline0.dev/it/docs/workflows/async-handoffs)
- [Orchestrazione degli agenti](https://queuety.inline0.dev/it/docs/workflows/agent-orchestration)
- [Macchine a stati](https://queuety.inline0.dev/it/docs/state-machines)
