Skip to content

Parallel agent

A parallel agent fans the same user message out to every sub-agent concurrently, waits for all to finish, and aggregates their responses. Pick this when you want N independent perspectives on the same input — ensemble answers, multi-perspective analysis, simultaneous lookups against unrelated tools.

Type identifier

YAML form:

agents:
  - id: ensemble
    type: parallel
    parallel_error_policy: continue   # or fail_fast / collect
    sub_agents:
      - { id: gpt-perspective,    type: react, model: { ... } }
      - { id: claude-perspective, type: react, model: { ... } }
      - { id: ollama-perspective, type: react, model: { ... } }

What it does

runParallel in pkg/agent/adk/run_orchestration.go:

  1. Creates a derived runCtx so ParallelFailFast can cancel in-flight siblings.
  2. Spawns one goroutine per sub-agent, bounded by a semaphore of min(len(sub_agents), 10) — so a fan-out of 50 sub-agents actually runs 10 at a time, not 50.
  3. Each goroutine emits a delegate debug event, runs agent.Run(runCtx, userMessage), and stores its outcome in a ParallelResult{ AgentID, Index, Response, Err }. Failures emit delegate_error regardless of policy — observability is non-optional.
  4. Apply the error policy (see below).
  5. Aggregate results into one assistant message. Default aggregation concatenates [<agent-id>]: <content>\n\n for every successful response, in SubAgents order (deterministic, not arrival order). A custom ParallelAggregator can replace this default.

Error policies

ParallelErrorPolicy (YAML: parallel_error_policy):

Value Behavior
"" / continue Default. Log + drop failed sub-agents, return the rest.
fail_fast First error cancels all in-flight siblings via runCtx.Done(), returns that error.
collect Wait for everyone to finish, return errors.Join(...) of every failure if any failed.

fail_fast correctly distinguishes the trigger error from sibling context.Canceled errors and only surfaces the real one.

Configuration

Field Type Default Description
id string — Parent ID.
type string — Must be parallel.
sub_agents list required Nested AgentDefinitions. Same user message goes to each.
parallel_error_policy string "" (continue) "" / fail_fast / collect.
model, tools, memory, guardrails, etc. — ignored Parent's own config is ignored — like sequential, the parent only orchestrates.

The default 10-way concurrency cap is fixed in code, not configurable from YAML. If you need a different cap, embed New(...) directly and supply a custom aggregator that throttles further.

Behavior notes

  • All sub-agents receive the SAME userMessage. There is no per-sub-agent input customisation in YAML — encode any differentiation in each sub-agent's system_prompt.
  • Aggregation is deterministic: results are emitted in SubAgents declaration order even though execution is concurrent.
  • A custom Go-level ParallelAggregator(results []ParallelResult) is available on AgentConfig. Useful for "first-success", "majority-vote", "JSON-merge" aggregators — not exposed in YAML, set it after constructing the agent in code.
  • delegate_error events fire for every failure regardless of policy, so tracers see all siblings' status, not just the one the policy surfaced.
  • Parallel is the LLM-driven counterpart to flow.ParallelFlow in pkg/agent/flow/. See flows.
  • Streaming is not supported — RunStream falls back to non-streaming and replays the aggregated text as word chunks.

Example

A multi-model ensemble that asks three different LLMs and presents all three answers:

agents:
  - id: ensemble
    type: parallel
    parallel_error_policy: collect
    sub_agents:
      - id: opinion-gpt
        type: react
        model: { provider: openai, model: gpt-4o }
        system_prompt: "Give your best one-paragraph answer."
      - id: opinion-claude
        type: react
        model: { provider: anthropic, model: claude-sonnet-4-7 }
        system_prompt: "Give your best one-paragraph answer."
      - id: opinion-ollama
        type: react
        model: { provider: ollama, model: llama3.3 }
        system_prompt: "Give your best one-paragraph answer."

Output is:

[opinion-gpt]: ...

[opinion-claude]: ...

[opinion-ollama]: ...

Source

  • pkg/agent/adk/run_orchestration.go — runParallel, error policy switch, default aggregator.
  • pkg/agent/adk/agent.go — Run dispatch on TypeParallel, ParallelResult, ParallelErrorPolicy, ParallelAggregator on AgentConfig.
  • pkg/workflow/definition.go — AgentDefinition.ParallelErrorPolicy.

See also

  • sequential — pipeline instead of fan-out.
  • supervisor — LLM picks which sub-agent to call.
  • flows — flow.ParallelFlow for processor-side composition.