Research Squad - AG2

05 · Research Squad

Two complementary multi-Agent patterns in one example. First, a coordinator opts in to the auto-injected run_subtasks tool (via tasks=TaskConfig()) to fan out three independent factual lookups concurrently in a single tool call. Then a second coordinator delegates arithmetic to a math_expert Agent exposed via Agent.as_tool(). Together they show "fan out then collect" alongside "named delegate".

What it covers

Primitives covered

Source

<br> 1<br> 2<br> 3<br> 4<br> 5<br> 6<br> 7<br> 8<br> 9<br> 10<br> 11<br> 12<br> 13<br> 14<br> 15<br> 16<br> 17<br> 18<br> 19<br> 20<br> 21<br> 22<br> 23<br> 24<br> 25<br> 26<br> 27<br> 28<br> 29<br> 30<br> 31<br> 32<br> 33<br> 34<br> 35<br> 36<br> 37<br> 38<br> 39<br> 40<br> 41<br> 42<br> 43<br> 44<br> 45<br> 46<br> 47<br> 48<br> 49<br> 50<br> 51<br> 52<br> 53<br> 54<br> 55<br> 56<br> 57<br> 58<br> 59<br> 60<br> 61<br> 62<br> 63<br> 64<br> 65<br> 66<br> 67<br> 68<br> 69<br> 70<br> 71<br> 72<br> 73<br> 74<br> 75<br> 76<br> 77<br> 78<br> 79<br> 80<br> 81<br> 82<br> 83<br> 84<br> 85<br> 86<br> 87<br> 88<br> 89<br> 90<br> 91<br> 92<br> 93<br> 94<br> 95<br> 96<br> 97<br> 98<br> 99<br>100<br>101<br> <br>"""05 · Research squad — parallel subtasks and sibling delegation<br>Two patterns for multi-Agent orchestration:<br>1. **Opt-in subtask tools.** Pass ``tasks=TaskConfig(...)`` and the Agent<br> gains ``run_subtask`` / ``run_subtasks``. The coordinator uses<br> ``run_subtasks`` with ``parallel=True`` to fan out three short<br> investigations concurrently. Spawned subtasks have **no** ``run_subtask``<br> tools (they default to ``tasks=False``), so recursion is structurally<br> impossible — no depth limiter needed.<br>2. **``Agent.as_tool()``.** A second Agent (``math_expert``) is exposed to<br> the coordinator as a callable tool. The wrapped Agent has no<br> ``run_subtask`` tools either (default), so recursion is bounded by the<br> call structure.<br>Run::<br> .venv/bin/python 05_research_squad.py<br>"""<br>import asyncio<br>import time<br>from ag2 import Agent<br>from ag2.agent import TaskConfig<br>from ag2.config import GeminiConfig<br>from ag2.events import TaskCompleted, TaskStarted<br>from ag2.stream import MemoryStream<br>def section(title: str) -> None:<br> print(f"\n── {title} ───")<br>async def main() -> None:<br> config = GeminiConfig(model="gemini-3-flash-preview", temperature=0)<br> section("Parallel subtasks — fan out three lookups in one tool call")<br> coordinator = Agent(<br> "coordinator",<br> prompt=(<br> "You answer multi-part questions by dispatching run_subtasks "<br> "with parallel=True. Use one tool call with every sub-question "<br> "packed into the 'tasks' list. Be concise."<br> ),<br> config=config,<br> tasks=TaskConfig(), # Opt in to run_subtask / run_subtasks.<br> )<br> # Collect subtask lifecycle events so we can show the fan-out to the user<br> starts: list[TaskStarted] = []<br> completions: list[TaskCompleted] = []<br> stream = MemoryStream()<br> stream.where(TaskStarted).subscribe(lambda e: starts.append(e))<br> stream.where(TaskCompleted).subscribe(lambda e: completions.append(e))<br> start = time.monotonic()<br> reply = await coordinator.ask(<br> "Use run_subtasks(parallel=True) to answer, in one tool call: "<br> "(a) what is the tallest waterfall in the world, "<br> "(b) what year was the Eiffel Tower completed, "<br> "(c) what is the boiling point of nitrogen in Celsius. "<br> "Then list all three answers.",<br> stream=stream,<br> )<br> elapsed = time.monotonic() - start<br> print(reply.body)<br> print()<br> print(f"Subtasks dispatched: {len(starts)}")<br> print(f"Subtasks finished: {len(completions)}")<br> print(f"Wall time: {elapsed:.2f}s (3 concurrent LLM calls)")<br> section("Sibling delegation — math_expert is a tool on coordinator2")<br> math_expert = Agent(<br> "math-expert",<br> prompt="You are an arithmetic specialist. Reply with only the number.",<br> config=config,<br> )<br> coordinator2 = Agent(<br> "coordinator2",<br> prompt=(<br> "When arithmetic comes up, delegate to the task_math-expert tool "<br> "rather than computing yourself. Then present the answer in a "<br> "complete sentence."<br> ),<br> config=config,<br> tools=[<br> math_expert.as_tool(<br> description="Delegate arithmetic problems to the math expert.",<br> )<br> ],<br> )<br> reply2 = await coordinator2.ask("What is 237 times 19?")<br> print(reply2.body)<br>if __name__ == "__main__":<br> asyncio.run(main())<br>