
# Neuron Planificateur / exécuteur

Cet exemple utilise Queuety pour l’orchestration et Neuron pour l’exécution de l’agent.

Le modèle est simple. Une étape de planification Queuety détermine les tâches à effectuer, `start_agents()` les transforme en workflows de premier niveau indépendants, chaque workflow enfant exécute un agent Neuron, puis `wait_for_agents()` rassemble les résultats dans le workflow parent.

## Pourquoi cette répartition fonctionne bien

Neuron permet de changer de fournisseur avec un minimum de modifications du code et d’encapsuler l’invite, les outils et la mémoire d’un agent spécialisé. Queuety gère efficacement les boucles for-each durables, les modes d’achèvement, les nouvelles tentatives, la reprise, ainsi que l’inspection et la révision humaine de l’exécution.

## Étape 1 : créer un agent Neuron dont le fournisseur peut être changé

```php
namespace App\Neuron;

use NeuronAI\Agent\Agent;
use NeuronAI\Providers\AIProviderInterface;
use NeuronAI\Providers\Anthropic\Anthropic;
use NeuronAI\Providers\Gemini\Gemini;
use NeuronAI\Providers\OpenAI\Responses\OpenAIResponses;
use NeuronAI\SystemPrompt;

final class ResearchAgent extends Agent
{
    public function __construct(
        private readonly string $providerName = 'openai',
    ) {}

    protected function provider(): AIProviderInterface
    {
        return match ($this->providerName) {
            'anthropic' => new Anthropic(
                key: $_ENV['ANTHROPIC_API_KEY'],
                model: $_ENV['ANTHROPIC_MODEL'],
            ),
            'gemini' => new Gemini(
                key: $_ENV['GEMINI_API_KEY'],
                model: $_ENV['GEMINI_MODEL'],
            ),
            default => new OpenAIResponses(
                key: $_ENV['OPENAI_API_KEY'],
                model: $_ENV['OPENAI_MODEL'],
            ),
        };
    }

    public function instructions(): string
    {
        return (string) new SystemPrompt(
            background: [
                'You are a research agent.',
                'Return concise, source-aware summaries for the assigned topic.',
            ],
        );
    }
}
```

L’intérêt ici est que le workflow peut choisir le fournisseur à l’exécution en transmettant `provider` dans l’état du workflow.

## Étape 2 : exécuter l’agent Neuron dans une étape Queuety

```php
namespace App\Workflow\Steps;

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

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

        $message = $agent->chat(
            new UserMessage(sprintf(
                "Research the topic '%s' for brief %d. Return a compact bullet summary.",
                $state['topic'],
                $state['brief_id'],
            ))
        )->getMessage();

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

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

C’est le point d’intégration essentiel : Neuron gère l’appel au LLM, tandis que Queuety conserve la responsabilité de la limite de l’étape et de l’état persistant du workflow.

## Étape 3 : laisser le planificateur lancer les exécutions des agents

```php
use Queuety\Enums\WaitMode;
use Queuety\Queuety;

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

Queuety::workflow('brief_research')
    ->version('brief-research.v1')
    ->then(PlanResearchTasksStep::class) // writes $state['agent_tasks']
    ->start_agents('agent_tasks', $agent_workflow)
    ->wait_for_agents(mode: WaitMode::All, result_key: 'agent_results')
    ->then(SynthesizeBriefStep::class)
    ->dispatch([
        'brief_id' => 42,
        'provider' => 'anthropic',
    ]);
```

Si `PlanResearchTasksStep` renvoie :

```php
[
    'agent_tasks' => [
        ['topic' => 'pricing'],
        ['topic' => 'customer reviews'],
        ['topic' => 'recent launches'],
    ],
]
```

Queuety créera un workflow de premier niveau pour chaque tâche, attendra qu’ils soient tous terminés, puis transmettra l’état final des workflows enfants sous `$state['agent_results']`.

## Pourquoi ne pas simplement appeler Neuron dans une boucle ?

C’est possible, mais vous perdriez les avantages de l’orchestration :

Chaque exécution d’agent ne serait plus inspectable individuellement, un plantage partiel pourrait relancer tout le lot et les étapes suivantes ne disposeraient d’aucun point d’achèvement fiable.

Ce modèle garde le code de l’agent simple tout en laissant Queuety gérer l’orchestration durable.

Si le planificateur fait partie d’une session d’agent de longue durée, gardez ce modèle de workflow pour la couche d’exécution et laissez une [machine à états](https://queuety.inline0.dev/fr/docs/state-machines) gérer le cycle de vie global.

## Documentation associée

- [Transferts asynchrones](https://queuety.inline0.dev/fr/docs/workflows/async-handoffs)
- [Orchestration d’agents](https://queuety.inline0.dev/fr/docs/workflows/agent-orchestration)
- [Machines à états](https://queuety.inline0.dev/fr/docs/state-machines)
