For the complete documentation index, see llms.txt. This page is also available as Markdown.

Bucles y ramas

Workflow hace que la lógica de ramificación y bucles sea fácil de implementar gracias a su diseño orientado a eventos. Una vez que entiendes cómo los nodos pertenecen a los eventos, es fácil empezar a imaginar cómo puedes crear bucles y ramificaciones, que consiste simplemente en decidir qué evento debe devolverse en una "condición if" o cualquier otra lógica.

Bucles

Para crear un bucle, simplemente devuelve el evento de entrada de un nodo anterior como el evento de salida del nodo actual. También puedes usar el mismo evento de entrada como evento de salida del nodo actual para recorrer en bucle el nodo actual.

Echa un vistazo al ejemplo de abajo. El NodeOne puede tener dos eventos como tipo de retorno, FirstEvent y SecondEvent. Si el nodo devuelve FirstEvent, provocará otra ejecución del mismo nodo porque FirstEvent es manejado por sí mismo, creando un bucle.

Si el nodo devuelve SecondEvent finalmente avanzará la ejecución hacia otro nodo.

class NodeOne extends Node
{
    public function __invoke(FirstEvent $event, WorkflowState $state): FirstEvent|SecondEvent
    {
        echo "\n- ".$event->firstMsg;
        
        if (rand(0, 1) === 1) {
            // Al devolver FirstEvent se activará otra ejecución de NodeOne
            return new FirstEvent("Running a loop on NodeOne");
        }
        
        return new SecondEvent("NodeOne complete, move forward");
    }
}

Devolver FirstEvent activará otra ejecución de NodeOne. Así que la salida final podría ser:

Puedes crear un bucle desde cualquier nodo hacia cualquier otro nodo del flujo de trabajo definiendo el evento de entrada apropiado y los eventos de retorno del método invoke.

El NodeOne incluso puede devolver un StartEvent para saltar directamente al primer nodo del Workflow. La arquitectura orientada a eventos te permite apuntar directamente a cualquier nodo del flujo de trabajo tanto hacia adelante como hacia atrás.

Ramas

Como ya has visto, puedes devolver condicionalmente distintos eventos desde un nodo para definir flujos de ejecución personalizados. En esta sección veremos un ejemplo de un flujo de trabajo que se ramifica en dos rutas diferentes.

Primero vamos a crear algunos eventos personalizados:

En el nodo inicial del flujo de trabajo decidimos por qué rama queremos pasar. Recuerda definir siempre los tipos de retorno apropiados en la __invoke firma del método:

Los otros nodos avanzarán secuencialmente.

Por supuesto, puedes combinar ramas y bucles en cualquier orden para satisfacer las necesidades de tu aplicación.

Ramas en paralelo

Cuando quieras invocar la ejecución de múltiples ramas en paralelo, necesitas devolver el evento especial ParallelEvent desde tu nodo.

El ParallelEvent debe construirse con un array de <branch_name> => <FirstInputEvent>:

Los nodos que manejan los eventos que declares para cada rama deben registrarse en el flujo de trabajo:

Una rama puede ser solo un nodo, o una lista de múltiples nodos siempre conectados con eventos.

Gestiona el FINAL de las ramas

El último nodo de tu rama debe devolver el StopEvent.

En el ejemplo anterior TextRefactorNode y AddWatermarkNode declararán el final de su rama devolviendo StopEvent:

Nota: StopEvent también puede llevar algunos resultados.

Obtén el resultado de las ramas

El ParallelEvent devuelto por el DocumentProcessing nodo básicamente espera el final de la ejecución de las ramas antes de ser encaminado al siguiente nodo.

En el ejemplo anterior, el MergeNode se encarga finalmente de gestionar el ParallelEvent:

Este nodo puede leer el resultado final de cada rama con el getResult() método pasando el <branch_name>.

Como de costumbre, el nodo de fusión puede detener el flujo de trabajo o devolver otros eventos que lo hagan avanzar.

Aislamiento del estado de las ramas

Un detalle que vale la pena señalar: cada rama obtiene una copia aislada del estado del flujo de trabajo. Empiezan con la misma instantánea, pero las mutaciones dentro de una rama no se propagan a las ramas hermanas ni al flujo de trabajo principal. La única forma de devolver datos es a través del StopEvent resultado.

Esto es intencional, evita toda una clase de errores de concurrencia en los que las ramas interfieren con el estado de las demás.

Ejecutor asíncrono

También proporcionamos una implementación del ejecutor interno del flujo de trabajo que te permite ejecutar múltiples ramas de forma concurrente. Para usar el Ejecutor asíncrono necesitas instalar el Amp paquete:

Esto es especialmente útil si quieres ejecutar múltiples tareas agenticas en paralelo, ya que Neuron AI ya proporciona el AmpHttpClient que puedes inyectar en todos los componentes.

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.

Última actualización