Neuron Workflows dépendants
Cet exemple répond à une question fréquente sur les agents :
Un workflow peut-il décider qu’un autre ne doit poursuivre qu’après la fin d’un workflow précédent ?
Oui. La nuance importante est que Queuety prend déjà cela en charge avec wait_for_workflow() et wait_for_workflows().
Cela signifie que :
- le workflow
Xpeut être lancé immédiatement Xpeut rester en attente danswaiting_for_workflowsXne reprend que lorsque le workflowYest terminé
Exemple : commencer par la recherche, puis rédiger
Utilisez un workflow de premier niveau pour constituer un dossier de recherche, puis un second pour rédiger le texte final.
Workflow de recherche
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',
]);
Workflow de rédaction
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',
]);
Au démarrage, le workflow de rédaction se met immédiatement en pause dans waiting_for_workflows jusqu’à ce que le workflow de recherche soit terminé avec succès.
L’étape de rédaction Neuron
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 parce que wait_for_workflow() a copié l’état public terminé du workflow de dépendance dans le workflow actuel, sous la clé research.
Quand préférer cette approche à un workflow géant
Préférez des workflows de premier niveau séparés lorsque :
- les étapes ont des responsables ou des cycles opérationnels différents
- vous souhaitez les examiner et les relancer indépendamment
- une étape ultérieure doit pouvoir être lancée avant la fin de l’étape précédente
Préférez un seul workflow lorsque :
- les étapes sont étroitement liées
- elles partagent un même cycle de vie et un même ensemble d’états
La place d’une machine à états
Si ce processus de rédaction s’inscrit dans une session éditoriale de longue durée, laissez une machine à états gérer le cycle de vie global et utilisez ces workflows pour les étapes d’exécution délimitées. Les états du cycle de vie comme awaiting_brief, researching, awaiting_review et completed restent ainsi explicites, tandis que chaque phase conserve la persistance du workflow.
Une distinction importante
Ce modèle signifie que :
Xexiste déjà, mais attendY
Cela ne signifie pas que :
Xn’est créé qu’une foisYterminé
Si vous voulez obtenir le second comportement, faites attendre un workflow parent jusqu’à Y, puis appelez start_workflows() ou start_agents() pour X.