
# Planificador / ejecutor Neuron

Este ejemplo usa Queuety para la orquestación y Neuron para ejecutar el agente.

El patrón es sencillo. Un paso planificador de Queuety decide qué tareas hay que realizar, `start_agents()` las convierte en flujos de trabajo independientes de nivel superior, cada flujo secundario ejecuta un agente Neuron y `wait_for_agents()` reúne los resultados en el flujo principal.

## Por qué funciona bien esta separación

Neuron permite cambiar de proveedor con pocos cambios en el código y encapsular las instrucciones, las herramientas y la memoria de un agente especializado. Queuety gestiona bien la ejecución duradera para cada elemento y los modos de finalización, los reintentos, la capacidad de reanudar y las interfaces de inspección o revisión humana de la ejecución.

## Paso 1: crea un agente Neuron con proveedores intercambiables

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

Lo útil aquí es que el flujo de trabajo puede elegir el proveedor durante la ejecución pasando `provider` en el estado del flujo.

## Paso 2: ejecuta el agente Neuron dentro de un paso 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 [];
    }
}
```

Este es el punto clave de integración: Neuron gestiona la llamada al LLM, pero Queuety sigue siendo responsable del límite del paso y del estado persistido del flujo de trabajo.

## Paso 3: deja que el planificador inicie ejecuciones de agentes

```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` devuelve:

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

Queuety creará un flujo de trabajo de nivel superior para cada tarea, esperará a que todos terminen y pasará el estado final de los flujos secundarios bajo `$state['agent_results']`.

## ¿Por qué no llamar simplemente a Neuron en un bucle?

Podrías hacerlo, pero perderías las ventajas de la orquestación:

Ya no se podría inspeccionar cada ejecución del agente por separado, un fallo parcial probablemente reiniciaría todo el lote y no habría un punto de finalización claro para las etapas posteriores.

Este patrón mantiene sencillo el código del agente y permite que Queuety gestione la orquestación duradera.

Si el planificador forma parte de una sesión de agente de larga duración, usa este patrón de flujo de trabajo para la capa de ejecución y deja que una [máquina de estados](https://queuety.inline0.dev/es/docs/state-machines) gestione el ciclo de vida general.

## Documentación relacionada

- [Transferencias asíncronas](https://queuety.inline0.dev/es/docs/workflows/async-handoffs)
- [Orquestación de agentes](https://queuety.inline0.dev/es/docs/workflows/agent-orchestration)
- [Máquinas de estados](https://queuety.inline0.dev/es/docs/state-machines)
