# How to Implement Multi-Agent Orchestration in Jido: A Complete Guide

> Master multi-agent orchestration in Jido by returning SpawnAgent directives. This guide details creating child agents, bidirectional communication, and managing them effectively.

- Repository: [agentjido/jido](https://github.com/agentjido/jido)
- Tags: how-to-guide
- Published: 2026-03-09

---

**Multi-agent orchestration in Jido is achieved by returning `SpawnAgent` directives from an agent's `cmd/2` function, which creates child `AgentServer` processes tracked in the parent's `state.children` map and enables bidirectional parent-child communication via signals.**

Jido (agentjido/jido) is an Elixir framework where agents are pure decision-making modules that communicate with the runtime exclusively through **directives**. To implement multi-agent orchestration, you compose agent hierarchies by returning `SpawnAgent` directives from a parent agent's `cmd/2` function, creating supervised child processes that maintain parent references for upstream signaling.

## How Multi-Agent Orchestration Works in Jido

Jido treats agents as stateless decision functions (`cmd/2`) that produce directives. The `Jido.AgentServer` GenServer executes these directives to mutate runtime state. When an agent returns a `%Jido.Agent.Directive.SpawnAgent{}` struct, the `DirectiveExec` implementation in [`lib/jido/agent_server/directive_executors.ex`](https://github.com/agentjido/jido/blob/main/lib/jido/agent_server/directive_executors.ex) (lines 85-131) creates a new child process and registers it in the parent's `state.children` map via `State.add_child/3` from [`lib/jido/agent_server/state.ex`](https://github.com/agentjido/jido/blob/main/lib/jido/agent_server/state.ex).

The orchestration flow follows four steps:

1. Start the root agent with `Jido.AgentServer.start/1`.
2. Return `SpawnAgent` directives from `cmd/2` to declare child agents.
3. The runtime stores `%ChildInfo{}` structs (defined in [`lib/jido/agent_server/child_info.ex`](https://github.com/agentjido/jido/blob/main/lib/jido/agent_server/child_info.ex)) containing the child's PID, monitor reference, and metadata.
4. Parents address children by tag using `StopChild` directives or direct PID signals, while children emit upstream via `emit_to_parent/3`.

## Spawning Child Agents with SpawnAgent

The `SpawnAgent` directive, defined in [`lib/jido/agent/directive.ex`](https://github.com/agentjido/jido/blob/main/lib/jido/agent/directive.ex) (lines 31-57), is a Zoi-validated struct with four fields:

- `agent`: The module to instantiate.
- `tag`: A unique atom identifier for later reference.
- `opts`: Initialization options passed to the child.
- `meta`: Contextual data stored in the parent's `ChildInfo`.

### Orchestrator Agent Example

```elixir
defmodule OrchestratorAgent do
  use Jido.Agent

  def start_workers(count) do
    Jido.Signal.new!("orchestrator.start", %{count: count})
    |> Jido.AgentServer.cast(__MODULE__)
  end

  @impl true
  def cmd(%__MODULE__{} = state, %Jido.Signal{type: "orchestrator.start", payload: %{count: n}}) do
    directives =
      for i <- 1..n do
        %Jido.Agent.Directive.SpawnAgent{
          agent: WorkerAgent,
          tag: :"worker_#{i}",
          opts: %{initial_state: %{worker_id: i}},
          meta: %{origin: :orchestrator}
        }
      end

    {:ok, state, directives}
  end
end

```

This returns multiple `SpawnAgent` directives from a single `cmd/2` invocation. The runtime executes these via `DirectiveExec` and populates `state.children` with `ChildInfo` structs keyed by each tag.

## Managing Agent Lifecycles

### Handling Child Exits

When a child crashes or stops, the runtime emits a `jido.agent.child.exit` signal. The parent handles this in `cmd/2`:

```elixir
@impl true
def cmd(state, %Jido.Signal{type: "jido.agent.child.exit", payload: payload}) do
  IO.puts("Child exited: #{inspect(payload)}")
  {:ok, state}
end

```

The `DirectiveExec` implementation monitors child processes and converts exit messages into these signals automatically.

### Stopping Child Agents

Use the `StopChild` directive (defined in [`lib/jido/agent/directive.ex`](https://github.com/agentjido/jido/blob/main/lib/jido/agent/directive.ex), lines 94-112) to gracefully terminate a child by tag:

```elixir
@impl true
def cmd(state, %Jido.Signal{type: "orchestrator.stop", payload: %{tag: tag}}) do
  {:ok, state, [%Jido.Agent.Directive.StopChild{tag: tag}]}
end

```

The executor implementation in [`lib/jido/agent_server/directive_executors.ex`](https://github.com/agentjido/jido/blob/main/lib/jido/agent_server/directive_executors.ex) (lines 141-176) handles the graceful shutdown and cleanup of the `ChildInfo` entry in `state.children`.

## Bidirectional Parent-Child Communication

Child agents reference their parent via `state.parent`, injected during spawning by `State.from_options/3`. Workers notify parents using `emit_to_parent/3` from the `Jido.Agent.Directive` module:

```elixir
defmodule WorkerAgent do
  use Jido.Agent

  @impl true
  def cmd(%__MODULE__{} = state, %Jido.Signal{type: "work", payload: payload}) do
    result = do_work(payload)
    emit_to_parent(state, "worker.done", %{id: state.state.worker_id, result: result})
    {:ok, state}
  end
end

```

This sends a signal that the parent receives as a normal inbound signal, enabling reactive orchestration patterns where parent agents respond to child lifecycle events and results.

## Summary

- **SpawnAgent Directive**: The primary mechanism for multi-agent orchestration in Jido, creating child `AgentServer` processes tracked via `ChildInfo` structs in `state.children`.
- **Pure Agent Logic**: Agents remain stateless decision modules; the runtime handles all process management through `DirectiveExec` implementations in [`lib/jido/agent_server/directive_executors.ex`](https://github.com/agentjido/jido/blob/main/lib/jido/agent_server/directive_executors.ex).
- **Lifecycle Management**: Automatic monitoring converts child exits to `jido.agent.child.exit` signals, while `StopChild` directives enable graceful termination.
- **Hierarchical Communication**: Children use `emit_to_parent/3` to send signals upstream, and parents address children by tag or PID.

## Frequently Asked Questions

### How do I start a child agent from within a parent agent?

Return a `%Jido.Agent.Directive.SpawnAgent{}` struct from your agent's `cmd/2` function. The runtime automatically creates the child process, registers it in the parent's `state.children` map, and establishes a monitor reference. You can return multiple `SpawnAgent` directives in a single list to spawn entire fleets.

### What information is stored about each child agent?

The runtime stores a `%ChildInfo{}` struct (defined in [`lib/jido/agent_server/child_info.ex`](https://github.com/agentjido/jido/blob/main/lib/jido/agent_server/child_info.ex)) containing the child's PID, monitor reference, module type, ID, tag, and metadata. This struct lives in the parent's `state.children` map, keyed by the atom tag you specified in the `SpawnAgent` directive.

### How can a child agent send data back to its parent?

Use the `emit_to_parent/3` function from the `Jido.Agent.Directive` module. This helper looks up the parent reference injected during spawning and emits a signal that the parent receives as a normal inbound signal. The parent handles these signals in its `cmd/2` clauses just like any other event.

### What happens when a spawned agent crashes?

The `Jido.AgentServer` monitors all child processes. When a child exits (normally or via crash), the runtime emits a `jido.agent.child.exit` signal to the parent containing exit details. The parent can pattern match on this signal in `cmd/2` to implement restart logic, cleanup, or error handling.