
# Serah Terima Asinkron

Gunakan `start_workflows()` ketika alur kerja perlu menyerahkan pekerjaan yang ditemukan ke alur kerja tingkat atas yang independen, alih-alih menyimpan semuanya dalam satu proses.

Jika Anda secara khusus memodelkan proses agen, `start_agents()` dan `wait_for_agents()` adalah alias semantik dengan nilai default yang berorientasi pada agen.

Untuk contoh end-to-end yang lebih lengkap, lihat [Orkestrasi Agen](https://queuety.inline0.dev/id/docs/workflows/agent-orchestration).

Ini berguna untuk orkestrasi bergaya agen:

- alur kerja perencana menemukan tugas saat runtime
- setiap tugas menjadi alur kerja persisten tersendiri
- proses induk menyimpan ID alur kerja tersebut dalam status
- proses induk kemudian dapat menunggu hingga `all`, `any`, `quorum`, atau grup bernama yang telah dimulai

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

Dalam contoh tersebut:

1. `PlanTopicsStep` menulis larik payload topik ke `$state['topics']`
2. `start_workflows()` men-dispatch satu alur kerja `agent_task` untuk setiap topik
3. ID alur kerja yang dimulai ditulis ke `$state['child_workflow_ids']`
4. `wait_for_workflow_group()` menjeda proses hingga grup yang dimulai memenuhi kondisi penyelesaian yang dipilih
5. `SynthesizeBriefStep` menerima status anak yang telah selesai di bawah `$state['child_results']`

## Payload anak

Setiap item di `items_key` menjadi payload awal untuk satu alur kerja yang dimulai.

Jika item berupa larik, kunci publiknya digabungkan ke payload anak:

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

Jika item berupa skalar, Queuety menyimpannya di bawah `payload_key`:

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

## Mewarisi status induk

Secara default, `start_workflows()` menggabungkan status publik alur kerja induk ke setiap payload anak.

Artinya, konteks bersama seperti `brief_id`, `account_id`, atau `campaign` tersedia secara otomatis di setiap alur kerja yang dimulai.

Sumber `items_key` dan `result_key` tidak disertakan dalam pewarisan agar setiap anak tidak menerima seluruh daftar tugas atau larik ID alur kerja akhir.

Tetapkan `inherit_state: false` ketika setiap anak seharusnya hanya menerima payload itemnya.

## Mengapa bukan `run_workflow()`?

`run_workflow()` membuat hubungan induk-anak yang membuat induk menunggu pada langkah tersebut hingga anak selesai.

`start_workflows()` lebih longgar:

- alur kerja yang dimulai adalah alur kerja tingkat atas yang independen
- setiap alur kerja yang dimulai dapat diperiksa, dicoba ulang, atau diekspor secara mandiri
- proses induk menentukan kemudian apakah dan bagaimana cara menunggunya

Dengan demikian, `start_workflows()` lebih cocok untuk serah terima tugas agen asinkron, sedangkan `run_workflow()` tetap lebih cocok untuk komposisi bertingkat dalam satu pohon orkestrasi.

## Menunggu kemudian

`start_workflows()` dirancang untuk dipasangkan dengan [Dependensi Alur Kerja](https://queuety.inline0.dev/id/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` mengumpulkan semua status anak yang telah selesai
- `WaitMode::Any` dilanjutkan saat alur kerja anak pertama berhasil

Ini memungkinkan orkestrasi perencana/pelaksana tanpa memerlukan mesin DAG lengkap yang dapat diedit saat runtime.

## Alias yang ramah bagi agen

`start_agents()` adalah alias untuk `start_workflows()` dengan nilai default yang disesuaikan untuk alur perencana/pelaksana:

- `result_key` menggunakan default `agent_workflow_ids`
- `payload_key` menggunakan default `agent_task`
- `name` menggunakan default `start_agents`

`wait_for_agents()` adalah alias untuk `wait_for_workflows()` dengan nilai default yang disesuaikan untuk mengumpulkan hasil agen:

- `workflows` menggunakan default `agent_workflow_ids`
- `result_key` menggunakan default `agent_results`
- `name` menggunakan default `wait_for_agents`

`wait_for_agent_group()` adalah alias untuk `wait_for_workflow_group()` dengan nilai default yang disesuaikan untuk batch agen.

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