> For the complete documentation index, see [llms.txt](https://docs.neuron-ai.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.neuron-ai.dev/neuron-v3-es/flujo-de-trabajo/streaming.md).

# Streaming

Los flujos de trabajo pueden ser complejos; están diseñados para manejar lógica compleja y ramificada, iterable, lo que significa que pueden tardar en ejecutarse por completo. Para brindar a tu usuario una buena experiencia, puede que quieras proporcionar una indicación del progreso transmitiendo eventos a medida que ocurren. Los flujos de trabajo tienen soporte integrado para esto directamente desde dentro de los nodos.

### Emitir eventos desde nodos

Vamos a configurar un nuevo evento para manejar la transmisión de nuestro progreso a medida que avanzamos:

```php
namespace App\Neuron;

class ProgressEvent implements Event 
{
    public function __construct(protected string $msg){}
}
```

Tomaremos nuestro ejemplo MyWorkflow con múltiples nodos del tutorial anterior y modificaremos los nodos para transmitir actualizaciones en lugar de imprimir la salida directamente.

{% hint style="warning" %}
**Nota**: Para transmitir eventos desde un nodo, necesitas agregar `\Generator` como tipo de retorno adicional de la `__invoke` método.
{% endhint %}

```php
namespace App\Neuron;

use NeuronAI\Workflow\Node;
use NeuronAI\Workflow\StartEvent;
use NeuronAI\Workflow\StopEvent;

class InitialNode extends Node
{
    public function __invoke(StartEvent $event, WorkflowState $state): \Generator|FirstEvent
    {
        yield new ProgressEvent("Manejando StartEvent");
        
        return new FirstEvent("InitialNode complete");
    }
}

class NodeOne extends Node
{
    public function __invoke(FirstEvent $event, WorkflowState $state): \Generator|SecondEvent
    {
        yield new ProgressEvent($event->firstMsg);
        
        return new SecondEvent("NodeOne complete");
    }
}

class NodeTwo extends Node
{
    public function __invoke(SecondEvent$event, WorkflowState $state): \Generator|StopEvent
    {
        yield new ProgressEvent($event->secondMsg);
        
        yield new ProgressEvent("NodeTwo completo");
        
        $state->set('message', 'Fin de la transmisión');
        
        return new StopEvent();
    }
}
```

Para obtener realmente esta salida, necesitamos iniciar el flujo de trabajo y escuchar los eventos, así:

```php
$handler = Workflow::make()
    ->addNodes([
        new InitialNode(),
        new NodeOne(),
        new NodeTwo(),
    ])
    ->init();

$stream = $handler->events();

foreach ($stream as $event) {
    if ($event instanceof ProgressEvent) {
        echo "\n- ".$event->message;
    }
}

$finalState = $stream->getResult();

// Imprimirá "Fin de la transmisión"
echo "\n- ".$finalState->get('message');
```

La salida completa será:

```
- Manejo de StartEvent
- InitialNode complete
- NodeOne complete
- NodeTwo complete
- Fin de la transmisión
```

### Salida en transmisión del agente

Ejecutar agentes dentro de los nodos es uno de los casos de uso más comunes al trabajar con flujos de trabajo. Puede que te interese transmitir directamente la salida de un agente interno al cliente para ofrecer retroalimentación en tiempo real sobre la generación subyacente. Puedes hacerlo simplemente transmitiendo la salida del agente desde dentro del nodo.

```php
class InitialNode extends Node
{
    public function __invoke(StartEvent $event, WorkflowState $state): \Generator|FirstEvent
    {
        // Ejecutar un agente con transmisión
        yield from Agent::make()
            ->stream(new UserMessage($state->get('prompt')))
            ->events();
        
        return new FirstEvent("InitialNode complete");
    }
}
```

Para obtener esta salida, puedes escuchar los eventos del flujo de trabajo como de costumbre:

```php
$handler = MyWorkflow::make()->init();

foreach ($handler->events() as $event) {
    echo match($event::class) {
        TextChunk::class => "\n- ".$event->content,
        ...
    }
}
```

### Monitorización y depuración

Muchas de las aplicaciones que construyas con Neuron contendrán varios pasos con múltiples invocaciones de llamadas a LLM. A medida que estas aplicaciones se vuelven cada vez más complejas, resulta crucial poder inspeccionar exactamente qué está ocurriendo dentro de tu sistema agéntico. La mejor manera de hacerlo es con [Inspector](https://inspector.dev/).

{% embed url="<https://docs.inspector.dev/guides/neuron-ai>" %}
