Neuron Mașină de stări pentru sesiune
Acest model este util când ceea ce construiți se comportă mai degrabă ca o sesiune decât ca o execuție unică.
Mașinile de stări Queuety gestionează ciclul de viață al sesiunii, fluxurile de lucru Queuety execută activitățile de fundal care beneficiază de reîncercări, moduri de finalizare for-each și agregare, iar Neuron gestionează apelurile propriu-zise ale agentului și memoria conversației.
Această împărțire se potrivește bine pentru asistenți de asistență pentru clienți, asistenți interni de cercetare, agenți editoriali care se pot opri pentru revizuire umană și conversații care trec prin etape de planificare, așteptare și răspuns.
Structura ciclului de viață
În acest exemplu, o sesiune de asistență trece prin awaiting_user, planning, waiting_on_research și responding. Mașina face explicit acest ciclu de viață, în timp ce un flux de lucru de fundal adună informații și trimite un semnal sesiunii când a terminat.
Mașina de stări
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',
] );
Când un utilizator trimite un mesaj:
Queuety::machine_event(
$session_id,
'user_message',
[
'session_machine_id' => $session_id,
'message' => 'Can you compare our pricing to the main competitors?',
]
);
Mașina trece în planning, pune acțiunea sa în coadă și pornește fluxul de lucru pentru cercetare.
Acțiunea de planificare: lansați fluxul de lucru
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',
];
}
}
Această acțiune de stare nu încearcă să facă ea însăși cercetarea. Lansează un flux de lucru și înregistrează ID-ul acestuia în starea mașinii.
Pasul fluxului de lucru: semnalați mașinii când cercetarea este gata
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 [];
}
}
Când fluxul de lucru se încheie, trimite înapoi research_completed către mașină și include pachetul sintetizat în payloadul evenimentului.
Acțiunea de răspuns: apelați Neuron cu memoria sesiunii
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',
];
}
}
După generarea răspunsului, mașina revine în awaiting_user cu răspunsul actualizat în starea publică. Apoi, aceeași sesiune poate accepta un alt eveniment user_message și poate continua.
De ce este mai simplu decât un singur flux de lucru mare
Activitatea complexă se potrivește în continuare unui flux de lucru, deoarece partea de cercetare necesită planificare, execuții specializate, agregare și sinteză. Conversația de asistență de lungă durată se potrivește unei mașini de stări, deoarece sesiunea trebuie să țină evidența faptului că așteaptă un mesaj de la utilizator, așteaptă rezultatele cercetării sau poate trimite un răspuns.
Această împărțire menține codul de execuție lizibil și modelul sesiunii explicit.