Neuron Statusmachine voor sessies
Dit patroon is handig wanneer wat je bouwt meer op een sessie lijkt dan op een eenmalige run.
Queuety-statusmachines beheren de levenscyclus van de sessie, Queuety-workflows doen achtergrondwerk dat baat heeft bij nieuwe pogingen, voltooiingsmodi voor elke iteratie en aggregatie, en Neuron verzorgt de daadwerkelijke agentaanroepen en het gespreksgeheugen.
Die verdeling past goed bij supportcopilots, interne onderzoeksassistenten, redactieagenten die kunnen pauzeren voor menselijke beoordeling en chatgesprekken die wisselen tussen plannen, wachten en reageren.
Vorm van de levenscyclus
In dit voorbeeld doorloopt één supportsessie awaiting_user, planning, waiting_on_research en responding. De statusmachine houdt die levenscyclus expliciet bij, terwijl een achtergrondworkflow onderzoek verzamelt en de sessie laat weten wanneer dat klaar is.
De statusmachine
use Queuety\Queuety;
$session_id = Queuety::machine( 'support_session' )
->version( 'support-session.v1' )
->state( 'awaiting_user' )
->on( 'user_message', 'planning' )
->state( 'planning' )
->action( DispatchResearchWorkflowAction::class )
->on( 'research_dispatched', 'waiting_on_research' )
->state( 'waiting_on_research' )
->on( 'research_completed', 'responding' )
->state( 'responding' )
->action( RespondWithNeuronAction::class )
->on( 'response_ready', 'awaiting_user' )
->dispatch( [
'thread_id' => 'support:customer-42',
] );
Wanneer een gebruiker een bericht stuurt:
Queuety::machine_event(
$session_id,
'user_message',
[
'session_machine_id' => $session_id,
'message' => 'Can you compare our pricing to the main competitors?',
]
);
De machine schakelt over naar planning, zet de actie in de wachtrij en start de onderzoeksworkflow.
Planningsactie: de workflow starten
namespace App\StateMachines\Actions;
use Queuety\Contracts\StateAction;
use Queuety\Enums\WaitMode;
use Queuety\Queuety;
final class DispatchResearchWorkflowAction implements StateAction
{
public function handle( array $state, ?string $event = null, array $event_payload = [], array $payload = [] ): array|string
{
$message = trim( (string) ( $event_payload['message'] ?? '' ) );
$agent_workflow = Queuety::workflow( 'support_research_agent' )
->then( ResearchTopicStep::class );
$research_workflow = Queuety::workflow( 'support_research_packet' )
->then( PlanResearchTasksStep::class )
->start_agents( 'agent_tasks', $agent_workflow )
->wait_for_agents( mode: WaitMode::All, result_key: 'agent_results' )
->then( SynthesizeResearchPacketStep::class )
->then( NotifySessionResearchReadyStep::class );
$workflow_id = $research_workflow->dispatch( [
'machine_id' => $state['session_machine_id'],
'thread_id' => $state['thread_id'],
'customer_prompt' => $message,
] );
return [
'latest_user_message' => $message,
'research_workflow_id' => $workflow_id,
'_event' => 'research_dispatched',
];
}
}
Deze statusactie probeert het onderzoek niet zelf uit te voeren. Ze start een workflow en registreert de workflow-ID in de machinestatus.
Workflowstap: de machine laten weten wanneer het onderzoek klaar is
namespace App\Workflow\Steps;
use Queuety\Queuety;
use Queuety\Step;
final class NotifySessionResearchReadyStep implements Step
{
public function handle( array $state ): array
{
Queuety::machine_event(
$state['machine_id'],
'research_completed',
[
'research_packet' => $state['research_packet'],
]
);
return [];
}
public function config(): array
{
return [];
}
}
Wanneer de workflow is voltooid, stuurt die research_completed terug naar de machine en voegt het samengestelde pakket toe als gebeurtenisinhoud.
Antwoordactie: Neuron aanroepen met sessiegeheugen
namespace App\StateMachines\Actions;
use App\Neuron\SupportAgent;
use NeuronAI\Chat\Messages\UserMessage;
use Queuety\Contracts\StateAction;
final class RespondWithNeuronAction implements StateAction
{
public function handle( array $state, ?string $event = null, array $event_payload = [], array $payload = [] ): array|string
{
// Queuety creates actions with `new RespondWithNeuronAction()`, so build dependencies here.
$pdo = new \PDO( $_ENV['NEURON_DB_DSN'], $_ENV['NEURON_DB_USER'], $_ENV['NEURON_DB_PASSWORD'] );
$agent = new SupportAgent(
threadId: $state['thread_id'],
pdo: $pdo,
);
$message = $agent->chat(
new UserMessage(
sprintf(
"Answer the user message '%s' using this research packet:\n\n%s",
$state['latest_user_message'],
json_encode( $state['research_packet'] ?? [], JSON_PRETTY_PRINT )
)
)
)->getMessage();
return [
'assistant_reply' => $message->getContent(),
'_event' => 'response_ready',
];
}
}
Nadat het antwoord is gegenereerd, schakelt de machine terug naar awaiting_user met het bijgewerkte antwoord in de openbare status. Dezelfde sessie kan daarna nog een user_message-gebeurtenis ontvangen en doorgaan.
Waarom dit overzichtelijker is dan één grote workflow
Het zware werk heeft nog steeds de vorm van een workflow, omdat het onderzoeksdeel planning, specialistische runs, aggregatie en synthese vereist. Het langdurige supportgesprek heeft de vorm van een statusmachine, omdat de sessie moet bijhouden of ze wacht op een gebruikersbeurt, op onderzoek wacht of een antwoord mag geven.
Door die verdeling blijft de runtime leesbaar en het sessiemodel expliciet.