
# Orchestrarea agenților

Queuety se potrivește bine sistemelor cu agenți când doriți activitate adaptivă fără să renunțați la starea durabilă, reîncercări, inspectare și semantica explicită a așteptării.

Nu aveți nevoie de un motor DAG editabil în timpul execuției pentru majoritatea fluxurilor de lucru cu agenți. În practică, majoritatea sistemelor pot fi modelate cu un set restrâns de acțiuni durabile de orchestrare. `for_each()` extinde activitatea în cadrul unei singure execuții de flux de lucru. `start_agents()` și `wait_for_agents()` transferă activitatea descoperită în timpul execuției către fluxuri de lucru independente, de nivel superior. `wait_for_decision()` și `wait_for_input()` se pun pe pauză pentru control uman. `wait_for_workflow()`, `wait_for_workflows()` și `wait_for_agent_group()` permit unei execuții de nivel superior să aștepte o alta sau un grup început din care s-a pornit un număr suficient de execuții.

## Un model mental util

Orchestrarea agenților este cel mai ușor de înțeles pe straturi. Un planificator decide ce activitate trebuie desfășurată. Queuety transformă activitatea în joburi sau fluxuri de lucru durabile. Execuțiile specializate produc rezultate și stochează artefacte. O etapă de supervizare agregă rezultatele și decide ce urmează. În orice moment, o persoană poate aproba, respinge sau corecta execuția înainte ca aceasta să continue.

Distincția importantă este că agentul decide ce activitate să desfășoare, dar Queuety decide în continuare cum este aceasta păstrată, reîncercată, reluată și agregată. Când ținta de orchestrare este o sesiune de lungă durată, nu o execuție cu limite definite, folosiți împreună cu aceasta [Mașini cu stări](https://queuety.inline0.dev/ro/docs/state-machines).

## Modelul 1: planificator/executor cu execuții independente de agenți

Folosiți `start_agents()` când o etapă a planificatorului descoperă sarcini în timpul execuției, iar fiecare sarcină trebuie să devină propriul flux de lucru de nivel superior.

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

În acest model, `PlanResearchTasksStep` scrie elementele descoperite în timpul execuției în `$state['agent_tasks']`, `start_agents()` pornește câte un flux de lucru durabil pentru fiecare sarcină, iar `wait_for_agent_group()` pune în așteptare fluxul părinte până când este îndeplinită condiția de finalizare aleasă. Apoi, `SynthesizeBriefStep` primește stările finalizate ale copiilor în `$state['agent_results']`.

Acesta este cel mai bun punct de plecare pentru sistemele planificator/executor, deoarece fiecare execuție a agentului poate fi inspectată și reîncercată independent.

## Modelul 2: verificare umană înainte ca execuția să continue

Folosiți `wait_for_decision()` când fluxul de lucru trebuie să se oprească pentru o decizie clară, de tip da sau nu, și `wait_for_input()` când operatorul trebuie să trimită feedback structurat înapoi în execuție.

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

Dacă persoana care verifică aprobă:

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

Dacă persoana care verifică respinge:

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

După `wait_for_decision()`, fluxul de lucru primește un set structurat de date cu rezultatul final, semnalul care a reluat execuția și orice date de la persoana care verifică. Astfel, aveți un punct de verificare în care intervine o persoană, fără să mențineți un proces PHP deschis în timp ce execuția așteaptă.

## Modelul 3: un flux de lucru de nivel superior așteaptă un altul

Uneori, cel mai clar model nu este un singur flux de lucru uriaș. Un flux de lucru poate încheia cercetarea, iar un altul poate aștepta finalizarea acestuia înainte să înceapă etapa următoare.

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

Astfel, există o delimitare durabilă între etapa de cercetare și cea de publicare. Fiecare execuție are propriul ciclu de viață operațional, însă al doilea flux de lucru se reia automat când dependența este îndeplinită.

## Alegerea primitivei potrivite

`for_each()` este instrumentul potrivit când activitatea aparține unei singure execuții de flux de lucru, iar ramurile sunt doar pași executați în paralel pe baza unui set comun de stări.

`start_agents()` este mai potrivit când fiecare sarcină descoperită trebuie să devină propria execuție durabilă de nivel superior și doriți să inspectați, reîncercați sau exportați separat execuțiile.

`wait_for_workflow()` și `wait_for_workflows()` sunt potrivite când un flux de lucru de nivel superior depinde de un alt flux de lucru de nivel superior și doriți coordonare asincronă durabilă între aceste straturi de orchestrare.

`wait_for_decision()` și `wait_for_input()` se folosesc în punctele în care o persoană trebuie să aprobe, să respingă sau să ghideze execuția, în timp ce fluxul de lucru rămâne în pauză fără să consume capacitatea lucrătorilor.

## Convenții recomandate pentru stări

Sistemele cu agenți sunt mai ușor de depanat când cheile de stare sunt previzibile. În practică, `agent_tasks` funcționează bine pentru rezultatul planificatorului, `agent_workflow_ids` pentru execuțiile pornite de nivel superior, `agent_results` pentru starea finalizată a fluxului de lucru copil și `review` sau `decision` pentru datele de aprobare sau respingere. Rezultatele mai mari, precum schițele, citările sau manifestele de cercetare, ar trebui de obicei stocate în depozitul de artefacte, nu în setul principal de stări al fluxului de lucru.

## Măsuri de protecție recomandate pentru execuțiile agenților

Fluxurile de lucru cu agenți beneficiază de măsuri de protecție mai mult decât aproape orice alt caz de utilizare, deoarece sunt dinamice prin natura lor.

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

Aceste controale răspund întrebărilor practice importante în producție: ce versiune a definiției a generat o execuție, dacă cererile externe duplicate o pot porni de două ori, dacă un planificator poate crea prea multe ramuri și dacă starea fluxului de lucru poate crește fără limite. Pentru majoritatea sistemelor cu agenți, începeți cu aceste măsuri de protecție înainte să ajustați numărul de lucrători sau topologia cozii.

## Consultați și

- [Exemple](https://queuety.inline0.dev/ro/docs/examples)
- [Declanșatoare de acțiuni](https://queuety.inline0.dev/ro/docs/features/action-triggers)
- [For-Each dinamic](https://queuety.inline0.dev/ro/docs/workflows/for-each)
- [Transferuri asincrone](https://queuety.inline0.dev/ro/docs/workflows/async-handoffs)
- [Dependențe între fluxuri de lucru](https://queuety.inline0.dev/ro/docs/workflows/dependencies)
- [Artefacte](https://queuety.inline0.dev/ro/docs/features/artifacts)
- [Semnale de flux de lucru](https://queuety.inline0.dev/ro/docs/workflows/signals)
- [Măsuri de protecție pentru fluxuri de lucru](https://queuety.inline0.dev/ro/docs/workflows/guardrails)
