Ugrás a tartalomhoz

Ügynökök összehangolása

A(z) Queuety jól illik az ügynökrendszerekhez, ha alkalmazkodó munkát szeretne, de meg akarja tartani a tartós állapotot, az újrapróbálkozásokat, a vizsgálhatóságot és a kifejezett várakozási szemantikát.

A legtöbb ügynökfolyamathoz nincs szüksége futás közben szerkeszthető DAG-motorra. A gyakorlatban a legtöbb rendszer modellezhető néhány tartós összehangolási művelettel. A(z) for_each() egy munkafolyamat-futáson belül bontja ki a munkát. A(z) start_agents() és wait_for_agents() a futás közben felfedezett feladatokat önálló, legfelső szintű munkafolyamatoknak adja át. A(z) wait_for_decision() és wait_for_input() emberi beavatkozásig szüneteltet. A(z) wait_for_workflow(), wait_for_workflows() és wait_for_agent_group() lehetővé teszi, hogy egy legfelső szintű futás megvárjon egy másikat vagy egy elindított kvórumot.

Hasznos gondolkodási modell

Az ügynökök összehangolása rétegekben átlátható a legkönnyebben. A tervező meghatározza, milyen munka van. A(z) Queuety ezt a munkát tartós feladatokká vagy munkafolyamatokká alakítja. A specializált futások eredményeket hoznak létre, és műtermékeket tárolnak. Egy felügyelő szakasz összesíti ezeket az eredményeket, és eldönti, mi történjen ezután. A futás bármely pontján egy ember jóváhagyhatja, elutasíthatja vagy korrigálhatja a folytatás előtt.

A fontos különbség az, hogy az ügynök dönti el, milyen munkát végezzen, de a(z) Queuety továbbra is azt szabályozza, hogyan történik a munka mentése, újrapróbálása, folytatása és összesítése. Ha az összehangolás célja egy hosszú életű munkamenet, nem pedig egy behatárolt futás, párosítsa ezt az Állapotgépek megoldással.

1. minta: Tervező/végrehajtó önálló ügynökfutásokkal

Használja a(z) start_agents() megoldást, ha egy tervezőlépés futás közben fedez fel feladatokat, és mindegyikből önálló, legfelső szintű munkafolyamatnak kell lennie.

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

Ebben a mintában a(z) PlanResearchTasksStep a futás közben felfedezett elemeket a(z) $state['agent_tasks'] helyre írja, a(z) start_agents() feladatonként egy tartós munkafolyamatot indít el, a(z) wait_for_agent_group() pedig parkolópályára teszi a szülőt a választott befejezési feltétel teljesüléséig. Ezután a(z) SynthesizeBriefStep a befejezett gyermekállapotokat a(z) $state['agent_results'] alatt kapja meg.

Ez a legjobb kiindulópont a tervező/végrehajtó rendszerekhez, mert minden ügynökfutás önállóan megvizsgálható és újrapróbálható marad.

2. minta: Emberi felülvizsgálat a futás folytatása előtt

Akkor használja a(z) wait_for_decision() megoldást, ha a munkafolyamatnak meg kell állnia egy tényleges igen/nem döntéshez, a(z) wait_for_input() megoldást pedig akkor, ha a kezelő strukturált visszajelzést szeretne küldeni a futásba.

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

Ha a felülvizsgáló jóváhagyja:

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

Ha a felülvizsgáló elutasítja:

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

A(z) wait_for_decision() után a munkafolyamat strukturált adattartalmat kap, amely tartalmazza a végső eredményt, a futást folytató jelzést és a felülvizsgáló által mellékelt adatokat. Ez valódi emberi ellenőrzési pontot biztosít anélkül, hogy a futás várakozása alatt nyitva kellene tartani egy PHP folyamatot.

3. minta: Egy legfelső szintű munkafolyamat megvár egy másikat

Néha nem egyetlen óriási munkafolyamat a legtisztább modell. Az egyik munkafolyamat befejezheti a kutatást, egy másik pedig megvárhatja ezt, mielőtt elindítaná a következő szakaszt.

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

Így tartós határ jön létre a kutatási és a publikálási szakasz között. Minden futásnak saját működési életciklusa van, a második munkafolyamat mégis automatikusan folytatódik, amikor a függőség teljesül.

A megfelelő alapvető építőelem kiválasztása

A(z) for_each() a megfelelő eszköz, ha a munka egy munkafolyamat-futáson belül marad, az elágazások pedig valójában csak lépésszintű párhuzamos végrehajtást jelentenek egy közös állapottárolón.

A(z) start_agents() jobb választás, ha minden felfedezett feladatból önálló, tartós, legfelső szintű futásnak kell lennie, és ezeket külön szeretné megvizsgálni, újrapróbálni vagy exportálni.

A(z) wait_for_workflow() és wait_for_workflows() akkor illik a feladathoz, ha az egyik legfelső szintű munkafolyamat egy másiktól függ, és tartós, aszinkron összehangolást szeretne az összehangolási rétegek között.

A(z) wait_for_decision() és wait_for_input() ott hasznos, ahol egy embernek jóvá kell hagynia, el kell utasítania vagy irányítania kell a futást, miközben a munkafolyamat szünetel, de nem foglal feldolgozói kapacitást.

Javasolt állapotkonvenciók

Az ügynökrendszerek hibakeresése könnyebb, ha az állapotkulcsok kiszámíthatók. A gyakorlatban a(z) agent_tasks jól használható a tervező kimenetéhez, a(z) agent_workflow_ids az elindított legfelső szintű futásokhoz, a(z) agent_results a befejezett gyermek-munkafolyamat állapotához, a(z) review vagy decision pedig a jóváhagyási vagy elutasítási adattartalomhoz. A nagyobb kimenetek, például a vázlatok, hivatkozások vagy kutatási jegyzékek általában inkább a műterméktárolóba valók, nem a fő munkafolyamat állapottárolójába.

Az ügynökmunkafolyamatoknak szinte minden más felhasználási esetnél nagyobb szükségük van védőkorlátokra, mivel természetüknél fogva dinamikusak.

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 );

Ezek a vezérlők a gyakorlatban fontos éles üzemi kérdésekre adnak választ: melyik definícióverzió hozott létre egy futást, előfordulhat-e, hogy ismétlődő külső kérések kétszer indítják el, létrehozhat-e a tervező túl sok elágazást, illetve korlátlanul növekedhet-e a munkafolyamat állapota. A legtöbb ügynökrendszernél ezeket a védőkorlátokat érdemes beállítani, mielőtt a feldolgozók számát vagy a sorok topológiáját hangolná.

Lásd még