From ec6088c61ccd0dbaeafb90129fca5ed9d892b55c Mon Sep 17 00:00:00 2001 From: Murat Kaan Meral Date: Tue, 14 Oct 2025 23:48:26 +0200 Subject: [PATCH 1/2] docs: Add multi-agent streaming docs --- docs/user-guide/concepts/multi-agent/graph.md | 45 +++++ docs/user-guide/concepts/multi-agent/swarm.md | 39 +++++ .../streaming/multi-agent-streaming.md | 162 ++++++++++++++++++ .../user-guide/concepts/streaming/overview.md | 1 + mkdocs.yml | 1 + 5 files changed, 248 insertions(+) create mode 100644 docs/user-guide/concepts/streaming/multi-agent-streaming.md diff --git a/docs/user-guide/concepts/multi-agent/graph.md b/docs/user-guide/concepts/multi-agent/graph.md index db043b0e..5c34e918 100644 --- a/docs/user-guide/concepts/multi-agent/graph.md +++ b/docs/user-guide/concepts/multi-agent/graph.md @@ -269,6 +269,51 @@ async def run_graph(): result = asyncio.run(run_graph()) ``` +## Streaming Events + +Graphs support real-time streaming of events during execution using [`stream_async`](../../../api-reference/multiagent.md#strands.multiagent.graph.Graph.stream_async). This provides visibility into node execution, parallel processing, and nested multi-agent systems. + +```python +from strands import Agent +from strands.multiagent import GraphBuilder + +# Create specialized agents +researcher = Agent(name="researcher", system_prompt="You are a research specialist...") +analyst = Agent(name="analyst", system_prompt="You are an analysis specialist...") + +# Build the graph +builder = GraphBuilder() +builder.add_node(researcher, "research") +builder.add_node(analyst, "analysis") +builder.add_edge("research", "analysis") +builder.set_entry_point("research") +graph = builder.build() + +# Stream events during execution +async for event in graph.stream_async("Research and analyze market trends"): + # Track node execution + if event.get("multi_agent_node_start"): + print(f"šŸ”„ Node {event['node_id']} starting") + + # Monitor agent events within nodes + elif event.get("multi_agent_node_stream"): + inner_event = event["event"] + if "data" in inner_event: + print(inner_event["data"], end="") + + # Track node completion + elif event.get("multi_agent_node_stop"): + node_result = event["node_result"] + print(f"\nāœ… Node {event['node_id']} completed in {node_result.execution_time}ms") + + # Get final result + elif event.get("multi_agent_result"): + result = event["result"] + print(f"Graph completed: {result.status}") +``` + +For more details on multi-agent streaming including event types, parallel execution, and nested graphs, see [Multi-Agent Streaming](../streaming/multi-agent-streaming.md). + ## Graph Results When a Graph completes execution, it returns a [`GraphResult`](../../../api-reference/multiagent.md#strands.multiagent.graph.GraphResult) object with detailed information: diff --git a/docs/user-guide/concepts/multi-agent/swarm.md b/docs/user-guide/concepts/multi-agent/swarm.md index b62c261b..588190a6 100644 --- a/docs/user-guide/concepts/multi-agent/swarm.md +++ b/docs/user-guide/concepts/multi-agent/swarm.md @@ -186,6 +186,45 @@ async def run_swarm(): result = asyncio.run(run_swarm()) ``` +## Streaming Events + +Swarms support real-time streaming of events during execution using [`stream_async`](../../../api-reference/multiagent.md#strands.multiagent.swarm.Swarm.stream_async). This provides visibility into agent collaboration, handoffs, and autonomous coordination. + +```python +from strands import Agent +from strands.multiagent import Swarm + +# Create specialized agents +coordinator = Agent(name="coordinator", system_prompt="You coordinate tasks...") +specialist = Agent(name="specialist", system_prompt="You handle specialized work...") + +# Create swarm +swarm = Swarm([coordinator, specialist]) + +# Stream events during execution +async for event in swarm.stream_async("Design and implement a REST API"): + # Track node execution + if event.get("multi_agent_node_start"): + print(f"šŸ”„ Agent {event['node_id']} taking control") + + # Monitor agent events + elif event.get("multi_agent_node_stream"): + inner_event = event["event"] + if "data" in inner_event: + print(inner_event["data"], end="") + + # Track handoffs + elif event.get("multi_agent_handoff"): + print(f"\nšŸ”€ Handoff: {event['from_node']} → {event['to_node']}") + + # Get final result + elif event.get("multi_agent_result"): + result = event["result"] + print(f"\nSwarm completed: {result.status}") +``` + +For more details on multi-agent streaming including event types, handoff tracking, and nested swarms, see [Multi-Agent Streaming](../streaming/multi-agent-streaming.md). + ## Swarm Results When a Swarm completes execution, it returns a [`SwarmResult`](../../../api-reference/multiagent.md#strands.multiagent.swarm.SwarmResult) object with detailed information: diff --git a/docs/user-guide/concepts/streaming/multi-agent-streaming.md b/docs/user-guide/concepts/streaming/multi-agent-streaming.md new file mode 100644 index 00000000..1f84ca28 --- /dev/null +++ b/docs/user-guide/concepts/streaming/multi-agent-streaming.md @@ -0,0 +1,162 @@ +# Multi-Agent Streaming + +Multi-agent systems (Graph and Swarm) support real-time streaming of events during execution, providing visibility into the orchestration process, node execution, and agent handoffs. This enables responsive UIs, real-time monitoring, and debugging of complex multi-agent workflows. + +Both Graph and Swarm use the same `stream_async` method pattern as single agents, yielding events as execution progresses. + +## Multi-Agent Event Types + +In addition to the standard [streaming events](./overview.md#event-types), multi-agent systems emit coordination events: + +### Multi-Agent Coordination Events +- `multi_agent_node_start`: When a node begins execution + - `node_id`: Unique identifier for the node + - `node_type`: Type of node ("agent", "swarm", "graph") +- `multi_agent_node_stream`: Forwarded events from agents/multi-agents with node context + - `node_id`: Identifier of the node generating the event + - `event`: The original agent event +- `multi_agent_node_stop`: When a node completes execution + - `node_id`: Unique identifier for the node + - `node_result`: Complete NodeResult with execution details, metrics, and status +- `multi_agent_handoff`: When control is handed off between agents (Swarm only) + - `from_node`: Node ID handing off control + - `to_node`: Node ID receiving control + - `message`: Handoff message explaining the transfer +- `multi_agent_result`: Final multi-agent result + - `result`: The final GraphResult or SwarmResult + +## Graph Streaming + +Graphs stream events as nodes execute according to the graph structure. Events are emitted in real-time, including from parallel node execution. + +```python +from strands import Agent +from strands.multiagent import GraphBuilder + +# Create specialized agents +researcher = Agent(name="researcher", system_prompt="You are a research specialist...") +analyst = Agent(name="analyst", system_prompt="You are an analysis specialist...") + +# Build the graph +builder = GraphBuilder() +builder.add_node(researcher, "research") +builder.add_node(analyst, "analysis") +builder.add_edge("research", "analysis") +builder.set_entry_point("research") +graph = builder.build() + +# Stream events during execution +async for event in graph.stream_async("Research and analyze market trends"): + # Track node execution + if event.get("multi_agent_node_start"): + print(f"šŸ”„ Node {event['node_id']} starting ({event['node_type']})") + + # Monitor agent events within nodes + elif event.get("multi_agent_node_stream"): + inner_event = event["event"] + + # Access nested agent events + if "data" in inner_event: + print(inner_event["data"], end="") + + # Track node completion + elif event.get("multi_agent_node_stop"): + node_result = event["node_result"] + print(f"\nāœ… Node {event['node_id']} completed in {node_result.execution_time}ms") + + # Get final result + elif event.get("multi_agent_result"): + result = event["result"] + print(f"Graph completed: {result.status}") +``` + +## Swarm Streaming + +Swarms stream events as agents collaborate and hand off tasks. Handoff events provide visibility into the autonomous coordination process. + +```python +from strands import Agent +from strands.multiagent import Swarm + +# Create specialized agents +coordinator = Agent(name="coordinator", system_prompt="You coordinate tasks...") +specialist = Agent(name="specialist", system_prompt="You handle specialized work...") + +# Create swarm +swarm = Swarm([coordinator, specialist]) + +# Stream events during execution +async for event in swarm.stream_async("Design and implement a REST API"): + # Track node execution + if event.get("multi_agent_node_start"): + print(f"šŸ”„ Agent {event['node_id']} taking control") + + # Monitor agent events + elif event.get("multi_agent_node_stream"): + inner_event = event["event"] + + if "data" in inner_event: + print(inner_event["data"], end="") + + # Track handoffs + elif event.get("multi_agent_handoff"): + print(f"\nšŸ”€ Handoff: {event['from_node']} → {event['to_node']}") + + # Track node completion + elif event.get("multi_agent_node_stop"): + node_result = event["node_result"] + print(f"āœ… Agent {event['node_id']} completed in {node_result.execution_time}ms") + + # Get final result + elif event.get("multi_agent_result"): + result = event["result"] + print(f"Swarm completed: {result.status}") +``` + + + +## Accessing Node Results + +Node stop events include the complete NodeResult with execution details: + +```python +from strands import Agent +from strands.multiagent import GraphBuilder + +# Create graph +agent_a = Agent(name="agent_a", system_prompt="You are agent A...") +agent_b = Agent(name="agent_b", system_prompt="You are agent B...") + +builder = GraphBuilder() +builder.add_node(agent_a, "a") +builder.add_node(agent_b, "b") +builder.add_edge("a", "b") +graph = builder.build() + +# Collect node results +node_results = {} + +async for event in graph.stream_async("Process task"): + if event.get("multi_agent_node_stop"): + node_id = event["node_id"] + node_result = event["node_result"] + + # Store result for analysis + node_results[node_id] = { + "status": node_result.status, + "execution_time": node_result.execution_time, + "tokens": node_result.accumulated_usage["totalTokens"], + "result": node_result.result + } + +# Analyze results +for node_id, result in node_results.items(): + print(f"{node_id}: {result['execution_time']}ms, {result['tokens']} tokens") +``` + +## Next Steps + +- Learn about [Graph patterns](../multi-agent/graph.md) for structured workflows +- Explore [Swarm patterns](../multi-agent/swarm.md) for autonomous collaboration +- See [Async Iterators](./async-iterators.md) for async streaming patterns +- Review [Callback Handlers](./callback-handlers.md) for synchronous event processing diff --git a/docs/user-guide/concepts/streaming/overview.md b/docs/user-guide/concepts/streaming/overview.md index f0093b8f..88ae3a85 100644 --- a/docs/user-guide/concepts/streaming/overview.md +++ b/docs/user-guide/concepts/streaming/overview.md @@ -194,4 +194,5 @@ orchestrator("What is 3+3?") - Learn about [Async Iterators](async-iterators.md) for asynchronous streaming - Explore [Callback Handlers](callback-handlers.md) for synchronous event processing +- See [Multi-Agent Streaming](multi-agent-streaming.md) for Graph and Swarm streaming - See the [Agent API Reference](../../../api-reference/agent.md) for complete method documentation \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index d365518e..917b90a3 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -108,6 +108,7 @@ nav: - Overview: user-guide/concepts/streaming/overview.md - Async Iterators: user-guide/concepts/streaming/async-iterators.md - Callback Handlers: user-guide/concepts/streaming/callback-handlers.md + - Multi-Agent Streaming: user-guide/concepts/streaming/multi-agent-streaming.md - Multi-agent: - Agent2Agent (A2A): user-guide/concepts/multi-agent/agent-to-agent.md - Agents as Tools: user-guide/concepts/multi-agent/agents-as-tools.md From 997c056c19b7433a65e4495627aafdba4aea2859 Mon Sep 17 00:00:00 2001 From: Murat Kaan Meral Date: Tue, 14 Oct 2025 23:59:21 +0200 Subject: [PATCH 2/2] fix: Fix list item indentation --- .../streaming/multi-agent-streaming.md | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/docs/user-guide/concepts/streaming/multi-agent-streaming.md b/docs/user-guide/concepts/streaming/multi-agent-streaming.md index 1f84ca28..738238a9 100644 --- a/docs/user-guide/concepts/streaming/multi-agent-streaming.md +++ b/docs/user-guide/concepts/streaming/multi-agent-streaming.md @@ -8,22 +8,21 @@ Both Graph and Swarm use the same `stream_async` method pattern as single agents In addition to the standard [streaming events](./overview.md#event-types), multi-agent systems emit coordination events: -### Multi-Agent Coordination Events - `multi_agent_node_start`: When a node begins execution - - `node_id`: Unique identifier for the node - - `node_type`: Type of node ("agent", "swarm", "graph") + - `node_id`: Unique identifier for the node + - `node_type`: Type of node ("agent", "swarm", "graph") - `multi_agent_node_stream`: Forwarded events from agents/multi-agents with node context - - `node_id`: Identifier of the node generating the event - - `event`: The original agent event + - `node_id`: Identifier of the node generating the event + - `event`: The original agent event, see [agent streaming events](./overview.md#event-types) - `multi_agent_node_stop`: When a node completes execution - - `node_id`: Unique identifier for the node - - `node_result`: Complete NodeResult with execution details, metrics, and status + - `node_id`: Unique identifier for the node + - `node_result`: Complete NodeResult with execution details, metrics, and status - `multi_agent_handoff`: When control is handed off between agents (Swarm only) - - `from_node`: Node ID handing off control - - `to_node`: Node ID receiving control - - `message`: Handoff message explaining the transfer + - `from_node`: Node ID handing off control + - `to_node`: Node ID receiving control + - `message`: Handoff message explaining the transfer - `multi_agent_result`: Final multi-agent result - - `result`: The final GraphResult or SwarmResult + - `result`: The final GraphResult or SwarmResult ## Graph Streaming