Hoppa till innehåll

Orkestrering av agenter

Queuety passar bra för agentsystem när du vill ha anpassningsbart arbete utan att ge upp beständigt tillstånd, återförsök, inspektion och uttrycklig väntelogik.

För de flesta agentflöden behöver du ingen DAG-motor som kan redigeras under körning. I praktiken kan de flesta system modelleras med ett litet antal beständiga orkestreringsåtgärder. for_each() utökar arbetet inom en och samma arbetsflödeskörning. start_agents() och wait_for_agents() lämnar över arbete som upptäcks under körningen till fristående arbetsflöden på toppnivå. wait_for_decision() och wait_for_input() pausar för mänsklig kontroll. wait_for_workflow(), wait_for_workflows() och wait_for_agent_group() gör att en körning på toppnivå kan vänta på en annan körning eller på en startad grupp som uppfyller ett kvorum.

En användbar tankemodell

Agentorkestrering är enklast att förstå i lager. En planerare avgör vilket arbete som finns. Queuety omvandlar arbetet till beständiga jobb eller arbetsflöden. Specialistkörningar skapar resultat och sparar artefakter. Ett övervakande steg sammanställer resultaten och avgör vad som ska hända härnäst. När som helst kan en människa godkänna, avvisa eller korrigera körningen innan den fortsätter.

Den viktiga skillnaden är att agenten avgör vilket arbete som ska utföras, medan Queuety fortfarande avgör hur arbetet sparas beständigt, görs om vid fel, återupptas och sammanställs. När orkestreringsmålet är en långlivad session snarare än en avgränsad körning kan du kombinera detta med Tillståndsmaskiner.

Mönster 1: Planerare och utförare med fristående agentkörningar

Använd start_agents() när ett planeringssteg upptäcker uppgifter under körning och varje uppgift ska bli ett eget arbetsflöde på toppnivå.

PHP
use Queuety\Enums\WaitMode;
use Queuety\Queuety;

$agent_run = Queuety::workflow( 'agent_run' )
    ->then( FetchSourcesStep::class )
    ->then( DraftFindingStep::class );

Queuety::workflow( 'brief_research' )
    ->version( 'brief-research.v1' )
    ->idempotency_key( 'brief:42:research' )
    ->max_transitions( 20 )
    ->then( PlanResearchTasksStep::class )
    ->start_agents( 'agent_tasks', $agent_run, group_key: 'researchers' )
    ->wait_for_agent_group( 'researchers', WaitMode::Quorum, 2, 'agent_results' )
    ->then( SynthesizeBriefStep::class )
    ->dispatch( [ 'brief_id' => 42 ] );

I det här mönstret skriver PlanResearchTasksStep objekt som upptäcks under körning till $state['agent_tasks'], start_agents() startar ett beständigt arbetsflöde för varje uppgift och wait_for_agent_group() parkerar det överordnade arbetsflödet tills det valda slutföringsvillkoret är uppfyllt. SynthesizeBriefStep tar sedan emot de slutförda tillståndena från underordnade arbetsflöden i $state['agent_results'].

Det här är den tydligaste startpunkten för system med planerare och utförare, eftersom varje agentkörning kan granskas och göras om separat.

Mönster 2: Mänsklig granskning innan körningen fortsätter

Använd wait_for_decision() när arbetsflödet ska stanna för ett faktiskt ja- eller nejbeslut, och wait_for_input() när operatören behöver skicka strukturerad återkoppling tillbaka till körningen.

PHP
use Queuety\Queuety;

$workflow_id = Queuety::workflow( 'brief_review' )
    ->then( DraftBriefStep::class )
    ->wait_for_decision( result_key: 'review' )
    ->then( HandleReviewDecisionStep::class )
    ->wait_for_input( result_key: 'revision_notes' )
    ->then( ApplyRevisionNotesStep::class )
    ->dispatch( [ 'brief_id' => 42 ] );

Om granskaren godkänner:

PHP
Queuety::approve_workflow(
    $workflow_id,
    [
        'reviewer' => 'editor@example.com',
        'notes' => 'Looks good, publish after legal check',
    ],
    'approved'
);

Om granskaren avvisar:

PHP
Queuety::reject_workflow(
    $workflow_id,
    [
        'reviewer' => 'editor@example.com',
        'reason' => 'Needs citations and a stronger conclusion',
    ],
    'rejected'
);

Efter wait_for_decision() får arbetsflödet en strukturerad nyttolast med det slutliga utfallet, signalen som återupptog körningen och eventuella granskaruppgifter som följde med den. Det ger dig en verklig kontrollpunkt med en människa i loopen utan att hålla en PHP-process öppen medan körningen väntar.

Mönster 3: Ett arbetsflöde på toppnivå väntar på ett annat

Ibland är den tydligaste modellen inte ett enda jättestort arbetsflöde. Ett arbetsflöde kan slutföra research, och ett annat kan vänta på det innan nästa steg startar.

PHP
use Queuety\Enums\WaitMode;
use Queuety\Queuety;

$research_id = Queuety::workflow( 'research_brief' )
    ->then( PlanResearchTasksStep::class )
    ->start_agents( 'agent_tasks', $agent_run )
    ->wait_for_agents( mode: WaitMode::All, result_key: 'agent_results' )
    ->then( SynthesizeBriefStep::class )
    ->dispatch( [ 'brief_id' => 42 ] );

Queuety::workflow( 'publish_brief' )
    ->wait_for_workflow( $research_id, 'research' )
    ->wait_for_decision( result_key: 'editor_review' )
    ->then( PublishBriefStep::class )
    ->dispatch( [ 'brief_id' => 42 ] );

Det ger en beständig gräns mellan researchfasen och publiceringsfasen. Varje körning har sin egen operativa livscykel, men det andra arbetsflödet återupptas ändå automatiskt när beroendet har slutförts.

Välj rätt primitiv

for_each() är rätt verktyg när arbetet hör hemma i en och samma arbetsflödeskörning och grenarna egentligen bara är parallell körning på stegnivå mot ett gemensamt tillståndsobjekt.

start_agents() passar bättre när varje upptäckt uppgift ska bli en egen beständig körning på toppnivå och du vill granska, göra om eller exportera körningarna separat.

wait_for_workflow() och wait_for_workflows() passar när ett arbetsflöde på toppnivå är beroende av ett annat och du vill ha beständig asynkron samordning mellan orkestreringslagren.

wait_for_decision() och wait_for_input() hör hemma där en människa behöver godkänna, avvisa eller styra körningen medan arbetsflödet förblir pausat utan att ta upp arbetarkapacitet.

Rekommenderade konventioner för tillstånd

Agentbaserade system är enklare att felsöka när tillståndsnycklarna är förutsägbara. I praktiken fungerar agent_tasks bra för utdata från planeraren, agent_workflow_ids för startade körningar på toppnivå, agent_results för slutfört tillstånd från underordnade arbetsflöden och review eller decision för godkännande- eller avvisningsdata. Större utdata, som utkast, källhänvisningar eller researchmanifest, hör vanligtvis hemma i artefaktlagret i stället för i arbetsflödets huvudsakliga tillståndsobjekt.

Agentarbetsflöden har större nytta av skyddsåtgärder än nästan alla andra användningsfall, eftersom de till sin natur är dynamiska.

PHP
Queuety::workflow( 'agent_research' )
    ->version( 'agent-research.v2' )
    ->idempotency_key( 'brief:42:agent-research' )
    ->max_transitions( 20 )
    ->max_for_each_items( 12 )
    ->max_state_bytes( 32768 );

De här kontrollerna besvarar praktiska frågor som är viktiga i produktion: vilken definitionsversion som skapade en körning, om dubbla externa förfrågningar kan starta den två gånger, om en planerare kan skapa för många grenar och om arbetsflödestillståndet kan växa utan gräns. För de flesta agentbaserade system bör du börja med de skyddsåtgärderna innan du justerar antalet arbetare eller kötopologin.

Se även