
# Neuron 종속 워크플로

이 예제는 에이전트 관련 흔한 질문에 답합니다.

> 한 워크플로가 먼저 실행된 워크플로의 완료 후에만 다른 워크플로를 계속 진행하게 할 수 있나요?

가능합니다. 중요한 점은 Queuety이 이미 `wait_for_workflow()` 및 `wait_for_workflows()`를 통해 이를 지원한다는 것입니다.

즉, 다음과 같습니다.

- 워크플로 `X`은 지금 디스패치할 수 있습니다
- `X`은 `waiting_for_workflows`에서 대기할 수 있습니다
- `X`은 워크플로 `Y`이 완료된 경우에만 재개됩니다

## 예제: 먼저 조사하고, 다음에 작성하기

최상위 워크플로 하나로 조사 자료를 만들고, 두 번째 최상위 워크플로로 최종 문안을 작성합니다.

### 조사 워크플로

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

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

$research_id = Queuety::workflow('research_packet')
    ->then(PlanResearchTasksStep::class)
    ->start_agents('agent_tasks', $research_agent)
    ->wait_for_agents(mode: WaitMode::All, result_key: 'agent_results')
    ->then(SynthesizeResearchPacketStep::class)
    ->dispatch([
        'brief_id' => 42,
        'provider' => 'anthropic',
    ]);
```

### 작성 워크플로

```php
Queuety::workflow('write_brief')
    ->wait_for_workflow('research_workflow_id', 'research')
    ->then(WriteBriefWithNeuronStep::class)
    ->wait_for_decision(result_key: 'editor_review')
    ->then(PublishBriefStep::class)
    ->dispatch([
        'brief_id' => 42,
        'research_workflow_id' => $research_id,
        'provider' => 'openai',
    ]);
```

작성 워크플로가 시작되면 조사 워크플로가 성공적으로 완료될 때까지 즉시 `waiting_for_workflows`에서 일시 중지됩니다.

## Neuron 작성 단계

```php
namespace App\Workflow\Steps;

use App\Neuron\WriterAgent;
use NeuronAI\Chat\Messages\UserMessage;
use Queuety\Step;

final class WriteBriefWithNeuronStep implements Step
{
    public function handle(array $state): array
    {
        $agent = new WriterAgent(
            providerName: $state['provider'] ?? 'openai',
        );

        $message = $agent->chat(
            new UserMessage(sprintf(
                "Write the final brief for brief %d using this research packet:\n\n%s",
                $state['brief_id'],
                json_encode($state['research'], JSON_PRETTY_PRINT),
            ))
        )->getMessage();

        return [
            'draft_markdown' => $message->getContent(),
        ];
    }

    public function config(): array
    {
        return [];
    }
}
```

`$state['research']`을 사용할 수 있는 이유는 `wait_for_workflow()`이 종속 워크플로의 완료된 공개 상태를 `research` 키 아래 현재 워크플로에 복사했기 때문입니다.

## 거대한 워크플로 하나 대신 이 방식을 사용할 때

다음과 같은 경우 최상위 워크플로를 분리하는 것이 좋습니다.

- 단계마다 담당자나 운영 수명 주기가 다를 때
- 각 단계를 독립적으로 검사하고 재시도하려는 경우
- 앞 단계가 끝나기 전에도 다음 단계를 디스패치할 수 있어야 하는 경우

다음과 같은 경우 워크플로 하나를 사용하는 것이 좋습니다.

- 단계 간 결합도가 높을 때
- 단계들이 하나의 수명 주기와 상태 저장소를 공유할 때

## 상태 머신의 역할

이 작성 흐름이 장기 실행되는 편집 세션의 일부라면 [상태 머신](https://queuety.inline0.dev/ko/docs/state-machines)이 전체 수명 주기를 담당하게 하고, 이 워크플로는 범위가 정해진 실행 단계에 사용하세요. 그러면 각 단계 내 워크플로의 지속성을 유지하면서 `awaiting_brief`, `researching`, `awaiting_review` 및 `completed` 같은 수명 주기 상태를 명시적으로 관리할 수 있습니다.

## 중요한 차이점

이 패턴의 의미는 다음과 같습니다.

- `X`은 지금 생성되지만 `Y`을 기다립니다

다음과 같은 의미는 아닙니다.

- `X`은 `Y`이 끝나야 생성됩니다

두 번째 동작을 원한다면 상위 워크플로가 `Y`을 기다린 다음 `X`을 위해 `start_workflows()` 또는 `start_agents()`를 호출하도록 하세요.

## 관련 문서

- [워크플로 종속성](https://queuety.inline0.dev/ko/docs/workflows/dependencies)
- [비동기 핸드오프](https://queuety.inline0.dev/ko/docs/workflows/async-handoffs)
- [에이전트 오케스트레이션](https://queuety.inline0.dev/ko/docs/workflows/agent-orchestration)
- [상태 머신](https://queuety.inline0.dev/ko/docs/state-machines)
