
# Asinhrone predaje

Uporabite `start_workflows()`, kadar mora potek dela odkrita opravila predati neodvisnim potekom dela na najvišji ravni, namesto da bi vse zadržal v enem zagonu.

Če izrecno modelirate zagone agentov, sta `start_agents()` in `wait_for_agents()` pomenska vzdevka s privzetimi nastavitvami, prilagojenimi agentom.

Večje primere od začetka do konca najdete v temi [Orkestracija agentov](https://queuety.inline0.dev/sl/docs/workflows/agent-orchestration).

To je uporabno za orkestracijo v slogu agentov:

- načrtovalni potek dela med izvajanjem odkrije opravila
- vsako opravilo postane lasten trajen potek dela
- nadrejeni potek shrani ID-je teh potekov v stanje
- nadrejeni lahko pozneje počaka na `all`, `any`, `quorum` ali poimenovano zagnano skupino

## Metoda `->start_workflows()`

```php
use Queuety\Enums\WaitMode;
use Queuety\Queuety;

$agent_task = Queuety::workflow( 'agent_task' )
    ->then( ResearchTopicStep::class )
    ->then( SummarizeTopicStep::class );

Queuety::workflow( 'brief_research' )
    ->then( PlanTopicsStep::class )
    ->start_workflows(
        items_key: 'topics',
        workflow_builder: $agent_task,
        result_key: 'child_workflow_ids',
        group_key: 'researchers',
    )
    ->wait_for_workflow_group( 'researchers', WaitMode::All, result_key: 'child_results' )
    ->then( SynthesizeBriefStep::class )
    ->dispatch( [ 'brief_id' => 42 ] );
```

V tem primeru:

1. `PlanTopicsStep` zapiše polje tovorov s temami v `$state['topics']`
2. `start_workflows()` sproži en potek dela `agent_task` za vsako temo
3. ID-ji zagnanih potekov dela se zapišejo v `$state['child_workflow_ids']`
4. `wait_for_workflow_group()` počaka, dokler zagnana skupina ne izpolni izbranega pogoja dokončanja
5. `SynthesizeBriefStep` prejme dokončana stanja podrejenih potekov pod `$state['child_results']`

## Tovori podrejenih potekov

Vsak element v `items_key` postane začetni tovor enega zagnanega poteka dela.

Če je element polje, se njegovi javni ključi združijo s tovorom podrejenega poteka:

```php
[
    [ 'topic' => 'pricing', 'source' => 'competitors' ],
    [ 'topic' => 'reviews', 'source' => 'customers' ],
]
```

Če je element skalar, ga Queuety shrani pod `payload_key`:

```php
->start_workflows(
    items_key: 'topic_names',
    workflow_builder: $agent_task,
    payload_key: 'topic',
)
```

## Dedovanje stanja nadrejenega poteka

Privzeto `start_workflows()` združi javno stanje nadrejenega poteka dela v tovor vsakega podrejenega poteka.

To pomeni, da je skupni kontekst, kot so `brief_id`, `account_id` ali `campaign`, samodejno na voljo v vsakem zagnanem poteku dela.

Izvor `items_key` in `result_key` sta izključena iz dedovanja, tako da vsak podrejeni potek ne prejme celotnega seznama opravil ali končnega polja ID-jev potekov dela.

Nastavite `inherit_state: false`, kadar naj vsak podrejeni potek prejme samo svoj tovor elementa.

## Zakaj ne `run_workflow()`?

`run_workflow()` ustvari odnos med nadrejenim in podrejenim potekom, pri katerem se nadrejeni ustavi pri tem koraku in čaka, da se podrejeni dokonča.

`start_workflows()` je bolj ohlapno povezan:

- zagnani poteki dela so neodvisni poteki na najvišji ravni
- vsak zagnani potek dela je mogoče pregledati, ponoviti ali izvoziti neodvisno
- nadrejeni pozneje odloči, ali in kako bo čakal nanje

Zato je `start_workflows()` primernejši za asinhrono predajo opravil agentom, medtem ko je `run_workflow()` primernejši za gnezdeno sestavljanje znotraj enega drevesa orkestracije.

## Poznejše čakanje

`start_workflows()` je zasnovan za uporabo skupaj z [Odvisnostmi potekov dela](https://queuety.inline0.dev/sl/docs/workflows/dependencies):

```php
use Queuety\Enums\WaitMode;

Queuety::workflow( 'review_board' )
    ->start_workflows( 'review_tasks', $review_task_workflow, 'review_workflow_ids' )
    ->wait_for_workflows( 'review_workflow_ids', WaitMode::Any, 'winner' )
    ->then( FinalizeDecisionStep::class )
    ->dispatch( $payload );
```

- `WaitMode::All` zbere vsa dokončana stanja podrejenih potekov
- `WaitMode::Any` se nadaljuje ob prvem uspešnem podrejenem poteku dela

Tako dobite orkestracijo načrtovalnika in izvajalnika brez potrebe po mehanizmu DAG, ki ga je mogoče urejati med izvajanjem.

## Vzdevki za agente

`start_agents()` je vzdevek za `start_workflows()` s privzetimi nastavitvami, prilagojenimi potekom dela načrtovalnika in izvajalnika:

- `result_key` je privzeto nastavljen na `agent_workflow_ids`
- `payload_key` je privzeto nastavljen na `agent_task`
- `name` je privzeto nastavljen na `start_agents`

`wait_for_agents()` je vzdevek za `wait_for_workflows()` s privzetimi nastavitvami, prilagojenimi zbiranju rezultatov agentov:

- `workflows` je privzeto nastavljen na `agent_workflow_ids`
- `result_key` je privzeto nastavljen na `agent_results`
- `name` je privzeto nastavljen na `wait_for_agents`

`wait_for_agent_group()` je vzdevek za `wait_for_workflow_group()` s privzetimi nastavitvami, prilagojenimi paketni obdelavi agentov.

```php
use Queuety\Enums\WaitMode;

$agent_run = Queuety::workflow( 'agent_run' )
    ->then( ResearchTopicStep::class )
    ->then( SummarizeTopicStep::class );

Queuety::workflow( 'brief_research' )
    ->then( PlanTopicsStep::class )
    ->start_agents( 'agent_tasks', $agent_run, group_key: 'researchers' )
    ->wait_for_agent_group( 'researchers', WaitMode::Quorum, 2 )
    ->then( SynthesizeBriefStep::class )
    ->dispatch( [ 'brief_id' => 42 ] );
```
