Skip to content

Is there a recommended way to run multiple sub‑agents in parallel from a Handoff? (best practices) #2056

@Shivam-Bahuguna-Seatrium

Description

Summary

I want to trigger several specialist agents concurrently when a handoff occurs (e.g., run P1, P2, P3 in parallel) and then aggregate their outputs under a single agent. The current Handoff factory (src/agents/handoffs.py) requires on_invoke_handoff to return a single Agent. Is there a recommended pattern or built‑in support for parallel sub‑agent execution and aggregation?

File / context

  • File inspected: src/agents/handoffs.py
  • Observed: handoff(...) produces an on_invoke_handoff that must return one Agent. No first‑class API to return multiple agents.

Minimal example (orchestrator pattern)

# Concept: handoff runs sub-agents in parallel, stores aggregated results in context,
# then returns a single "orchestrator" agent that reads the precomputed results.

import asyncio
from agents import Agent, Runner, handoff, function_tool, RunContextWrapper

# assume these exist
# tqf_p78_agent, tqf_p80_agent, tqf_p82_agent = Agent(...)

@function_tool
def get_aggregated_results(context: RunContextWrapper) -> str:
    return getattr(context.context, "aggregated_results", "No results available")

orchestrator_agent = Agent(
    name="TQF-Orchestrator",
    instructions="Call get_aggregated_results to obtain precomputed results and summarize them.",
    tools=[get_aggregated_results],
)

async def on_handoff_run_subagents(ctx: RunContextWrapper, input_json: str | None = None) -> Agent:
    task1 = Runner.run(tqf_p78_agent, input="forwarded user input / context")
    task2 = Runner.run(tqf_p80_agent, input="forwarded user input / context")
    task3 = Runner.run(tqf_p82_agent, input="forwarded user input / context")
    res1, res2, res3 = await asyncio.gather(task1, task2, task3)

    aggregated = f"P78:\n{res1.output}\n\nP80:\n{res2.output}\n\nP82:\n{res3.output}"
    ctx.context.aggregated_results = aggregated
    return orchestrator_agent

parallel_handoff = handoff(
    agent=orchestrator_agent,
    on_handoff=on_handoff_run_subagents,
    tool_description_override="Run P78, P80, P82 agents in parallel and aggregate results."
)

Questions

  1. Is calling Runner.run from on_invoke_handoff (including concurrently via asyncio.gather) supported and safe? Any reentrancy, lifecycle, or tracing caveats?
  2. Are there built‑in helpers, patterns, or examples in the SDK for running/aggregating multiple sub‑agents in a handoff?
  3. Streaming: given the handoff streaming caveats, what’s the recommended approach to surface sub‑agent outputs incrementally to the original caller, or is precompute+aggregate the intended pattern?
  4. Timeouts & partial results: recommended patterns for enforcing timeouts and returning partial results when some sub‑agents are slow or fail?

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions