
# 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](https://queuety.inline0.dev/sv/docs/state-machines).

## 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.

## Rekommenderade skyddsåtgärder för agentkörningar

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

- [Exempel](https://queuety.inline0.dev/sv/docs/examples)
- [Åtgärdsutlösare](https://queuety.inline0.dev/sv/docs/features/action-triggers)
- [Dynamisk For-Each](https://queuety.inline0.dev/sv/docs/workflows/for-each)
- [Asynkrona överlämningar](https://queuety.inline0.dev/sv/docs/workflows/async-handoffs)
- [Arbetsflödesberoenden](https://queuety.inline0.dev/sv/docs/workflows/dependencies)
- [Artefakter](https://queuety.inline0.dev/sv/docs/features/artifacts)
- [Arbetsflödessignaler](https://queuety.inline0.dev/sv/docs/workflows/signals)
- [Skyddsåtgärder för arbetsflöden](https://queuety.inline0.dev/sv/docs/workflows/guardrails)
