Saltar al contenido

Flujos de trabajo dependientes de Neuron

Este ejemplo responde a una pregunta habitual sobre agentes:

¿Puede un flujo de trabajo decidir que otro solo continúe después de que termine uno anterior?

Sí. El matiz importante es que Queuety ya admite esto con wait_for_workflow() y wait_for_workflows().

Esto significa que:

  • el flujo de trabajo X se puede iniciar ahora
  • X puede quedar en espera en waiting_for_workflows
  • X solo se reanuda cuando se completa el flujo de trabajo Y

Ejemplo: investigar primero y escribir después

Usa un flujo de trabajo de nivel superior para preparar un paquete de investigación y un segundo flujo de trabajo de nivel superior para redactar el texto final.

Flujo de investigación

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

Flujo de redacción

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

Cuando se inicia el flujo de redacción, se pausa de inmediato en waiting_for_workflows hasta que el flujo de investigación se completa correctamente.

El paso de redacción 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'] está disponible porque wait_for_workflow() copió el estado público completado del flujo de trabajo dependiente al flujo actual, bajo la clave research.

Cuándo usar esto en lugar de un único flujo de trabajo enorme

Prefiere flujos de trabajo de nivel superior separados cuando:

  • las etapas tienen responsables o ciclos operativos diferentes
  • quieres inspeccionarlas y volver a ejecutarlas de forma independiente
  • se debería poder iniciar una etapa posterior antes de que termine la anterior

Prefiere un solo flujo de trabajo cuando:

  • las etapas están estrechamente vinculadas
  • comparten un ciclo de vida y un conjunto de estado

El lugar de una máquina de estados

Si este flujo de redacción forma parte de una sesión editorial de larga duración, deja que una máquina de estados gestione el ciclo de vida general y usa estos flujos de trabajo para las etapas de ejecución acotadas. Así se mantienen explícitos los estados del ciclo de vida, como awaiting_brief, researching, awaiting_review y completed, y se conserva la durabilidad del flujo de trabajo dentro de cada fase.

Una distinción importante

Este patrón significa que:

  • X existe ahora, pero espera a Y

No significa que:

  • X no se cree hasta que termine Y

Si quieres el segundo comportamiento, haz que un flujo de trabajo principal espere a Y y solo entonces llame a start_workflows() o start_agents() para X.