
# Neuronの依存ワークフロー

この例では、エージェントを使う際によくある疑問に答えます。

> あるワークフローが、先行する別のワークフローの完了後にだけ続行するよう判断できますか？

はい。重要な点として、Queuetyはすでに`wait_for_workflow()`と`wait_for_workflows()`でこれをサポートしています。

つまり、次のことが可能です。

- ワークフロー`X`は今すぐディスパッチできます
- `X`は`waiting_for_workflows`で待機できます
- `X`は、ワークフロー`Y`が完了した場合にのみ再開します

## 例：まず調査し、その後に執筆

1つ目のトップレベルワークフローで調査資料を作成し、2つ目のトップレベルワークフローで最終原稿を作成します。

### 調査ワークフロー

```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`キーの下に格納したためです。

## 1つの巨大なワークフローではなく、この方法を使う場面

次の場合は、トップレベルワークフローを分けてください。

- 各段階の担当者や運用ライフサイクルが異なる
- 個別に調査して再試行したい
- 前段階の完了前でも後続段階をディスパッチ可能にしたい

次の場合は、1つのワークフローを使ってください。

- 各段階が密接に結びついている
- 1つのライフサイクルと1つの状態バッグを共有する

## ステートマシンの役割

この執筆フローが長期間続く編集セッションの一部である場合は、外側のライフサイクルを[ステートマシン](https://queuety.inline0.dev/ja/docs/state-machines)に管理させ、範囲を限定した実行段階にはこれらのワークフローを使います。これにより、各フェーズ内のワークフローの耐久性を保ちながら、`awaiting_brief`、`researching`、`awaiting_review`、`completed`のようなライフサイクル状態を明示できます。

## 重要な違い

このパターンでは、次のようになります。

- `X`は今すでに存在し、`Y`を待機する

次の意味ではありません。

- `Y`が完了するまで`X`は作成されない

後者の動作にしたい場合は、親ワークフローで`Y`を待機し、その後に`X`のために`start_workflows()`または`start_agents()`を呼び出します。

## 関連ドキュメント

- [ワークフローの依存関係](https://queuety.inline0.dev/ja/docs/workflows/dependencies)
- [非同期ハンドオフ](https://queuety.inline0.dev/ja/docs/workflows/async-handoffs)
- [エージェントのオーケストレーション](https://queuety.inline0.dev/ja/docs/workflows/agent-orchestration)
- [ステートマシン](https://queuety.inline0.dev/ja/docs/state-machines)
