Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Multi-agent (Agents as tools, Swarm, Graph, and...

Multi-agent (Agents as tools, Swarm, Graph, and A2A) | Learn Strands Agents with Kiro 07

This Level 300 deck shows five ways to combine agents in Strands Agents (1.64), following the chapters of the official docs, with the code of a help desk agent and real output from Amazon Bedrock in the Tokyo Region. It covers passing an agent as a tool (as_tool, delegate), Swarm and Graph (handoffs, conditional edges, the OR default, loop limits), Workflow, A2AAgent and A2AServer, and human approval with an interrupt in BeforeNodeCallEvent, as deck 07 (Go deeper) of the series Learn Strands Agents with Kiro.

Avatar for Riku INADA

Riku INADA PRO

November 11, 2026

More Decks by Riku INADA

Other Decks in Technology

Transcript

  1. Learn Strands Agents with Kiro 07 Go deeper Multi-agent Agents

    as tools, Swarm, Graph, and A2A 07 Level 300 / November 2026 November 2026 Riku Inada Amazon Web Services Japan © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Kiro + Strands Agents 1
  2. Introduction About me Riku Inada Amazon Web Services Japan G.K.

    Solutions Architect Works mainly with manufacturing customers Recent work Promoting the AI-Driven Development Life Cycle (AI-DLC) Writing and speaking about Kiro and AWS Amplify © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. X @inada_riku Speaker Deck speakerdeck.com/inariku Zenn zenn.dev/inariku GitHub github.com/inariku 2
  3. Introduction Where this deck fits You are here: 07 Multi-agent.

    Next: 08 Deploy and secure for production Get started 01–02 Go deeper 03–07 Verify 09 Ship and extend 08–10 Read next Get started with Hooks and 01 Strands Agents 03 lifecycle controls 02 Tools and MCP 04 and plugins Interventions Observability 09 and evals 08 Deploy and secure for production 10 Strands harness 05 Sessions and memory Read first 06 Structured output and streaming 07 Multi-agent © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 3
  4. Introduction This deck builds the help desk in four parts

    The help desk answers customers of a made-up online electronics shop. This deck adds order_agent for orders and refund_agent for refunds. The circled numbers are the parts © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 4
  5. 07 Multi-agent tools of desk Part 1 order_agent Pass an

    agent as a tool refund_agent © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. get_order_history 5
  6. 1 Pass an agent as a tool Strands has five

    ways to combine agents Pattern How it works Part Agents as tools One agent calls another agent as a tool 1 Swarm Agents hand off the task to the next agent by themselves 2 Graph A flowchart of nodes and edges. An LLM decision at each node picks the path, with branches and loops 2 Workflow Runs a fixed task graph (DAG) as one tool, with independent tasks in parallel 2 A2A Connects to an agent in another service over the Agent-to-Agent protocol 3 The smallest pattern is agents as tools. Graph and Swarm are orchestrators built into the SDK. Workflow is a pattern you write in code by chaining agents © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 6
  7. 1 Pass an agent as a tool Graph, Swarm, and

    Workflow differ in routing Graph Swarm Workflow What picks the path The edges, and an LLM decision at each node The agents (each picks who is next) The dependencies (fixed) Cycles Yes Yes No What is shared A state object all agents read and change The request, the handoff history, and what earlier agents added Task outputs become inputs of the tasks that depend on them On failure An error edge can route to a handling node Hand off to a handling agent. Timeouts and handoff limits stop loops One failed task halts all the tasks downstream What to weigh first: how the path of execution is decided © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 7
  8. 1 Pass an agent as a tool Put an agent

    in the tools of another agent smallest.py lines 5–17 order_agent = Agent( name="order_agent", description="Look up orders and answer", system_prompt="You handle orders. " + SHORT, model=model, tools=[get_order_history], callback_handler=None, ) desk = Agent( system_prompt="Ask order_agent. " + SHORT, model=model, tools=[order_agent], callback_handler=None, ) result = desk("When will the C-1001 hub arrive?") © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Output Your USB-C hub ships now. It arrives November 11, 2026. order_agent: call_count=1 order_agent becomes a tool of the desk The desk reads its description, and calls it like any other tool order_agent in the output is the tool it called 8
  9. 1 Pass an agent as a tool The desk can

    call several agents, then answer 1 Help desk Agent (desk) input="..." tool result (text) order_agent has get_order_history tools=[order_agent, Customer refund_agent] 2 refund_agent has process_refund Output of two_tools.py Called in order: ['order_agent', 'refund_agent'] Order C-1002 was delayed. Refund of ¥15,800 was accepted. Funds arrive in three to five days. © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Each reply comes back as a tool result The numbers are the order of the calls in this run 9
  10. 1 Pass an agent as a tool An agent becomes

    a tool with one input string tool_spec.py lines 5–17 order_agent = Agent( name="order_agent", model=model, description="Look up orders and answer", tools=[get_order_history], callback_handler=None) # prints nothing itself desk = Agent(model=model, tools=[order_agent]) spec = desk.tool_registry.get_all_tools_config() schema = spec["order_agent"]["inputSchema"]["json"] print(spec["order_agent"]["description"]) for name, p in schema["properties"].items(): print(name, p["type"]) print(schema["required"]) © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Output Look up orders and answer input string ['input'] The tool takes one input string, and the reply text of the agent is the result Set callback_handler=None on the specialist. Without it, the specialist prints its own reply next to the output of the desk 10
  11. 1 Pass an agent as a tool as_tool() sets name,

    description, and context as_tool.py lines 10–19 tool = order_agent.as_tool( name="order_desk", description="Find orders", preserve_context=preserve) desk = Agent(model=model, tools=[tool], callback_handler=None) counts = [] for cid in ("C-1001", "C-1002"): desk(f"Look up {cid} with order_desk") counts.append(len(order_agent.messages)) print(preserve, desk.tool_names, counts) Output False ['order_desk'] [4, 4] True ['order_desk'] [4, 8] name and description set the tool name and description the desk sees By default, the conversation of the specialist resets on every call ([4, 4] in the output) With preserve_context=True, it is kept ([4, 8]) © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 11
  12. 1 Pass an agent as a tool Passing an answer

    through the parent can hurt Checked answer When the parent processes generated code or a reviewed text Parent rewrites again, it costs more tokens, and the text can change as_tool(delegate=True) returns it delegate=True without the parent In the run on the next slide, the event loop cycles of the desk went from 2 to 1 © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 12
  13. 1 Pass an agent as a tool With delegate=True, the

    answer comes back as is delegate.py lines 15–28, in run(delegate) (RefundAnswer: 9–11) refund_agent = Agent( name="refund_agent", model=model, description="Find the refund amount", system_prompt="Late items get a full refund.", tools=[get_order_history], structured_output_model=RefundAnswer, callback_handler=None) tool = refund_agent.as_tool(delegate=delegate) desk = Agent(model=model, tools=[tool], callback_handler=None) r = desk("How much is the C-1002 refund?") calls = r.metrics.cycle_count print(delegate, r.stop_reason, calls) return r © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Output (lines 32–33 print line 2) True end_turn 1 15800 Late keyboard refund False end_turn 2 With True, r holds the RefundAnswer JSON of refund_agent, unchanged Lines 31, 34: run(True), run(False). Value 3 is cycle_count The desk must call this tool alone in its turn 13
  14. 07 Multi-agent Part 2 Build flows with Swarm and Graph

    © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Swarm Graph 14
  15. 2 Build flows with Swarm and Graph In a Swarm,

    each agent picks who works next 4 final answer triage reads the inquiry Swarm adds the handoff 1 refund accepts refunds 2 3 tool to each agent any other, with a message and, if needed, context The agent that answers without a handoff gives the order checks orders handoff_to_agent(agent_name, message, context) © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Any agent can hand off to final answer The numbers are the steps of the run on the next slide 15
  16. 2 Build flows with Swarm and Graph List agents in

    a Swarm, run it with swarm(task) swarm_run.py lines 2, 20–26 from strands.multiagent import Swarm swarm = Swarm( [order, refund, triage], entry_point=triage, max_handoffs=6, max_iterations=6, execution_timeout=300.0, node_timeout=120.0, ) result = swarm("This is C-1002. Refund my late keyboard.") Output lines 1–3 Status.COMPLETED ['triage', 'refund', 'order', 'refund'] Refund processed for your keyboard order. © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Without entry_point, it starts with the first agent order, refund, and triage are made with member() (appendix A3) Lines 27–30 print result.status, the node_id of each entry in result.node_history (the order the agents ran in), and result.results[last].result of the last agent 16
  17. 2 Build flows with Swarm and Graph With no handoff

    limit, a run may never end Still passing it on If agents keep passing the task back and forth, the run does not end Stop it with handoff limits, total and per-agent timeouts, and repetitive handoff detection The defaults: max_handoffs and max_iterations both 20, execution_timeout 900 seconds, node_timeout 300 seconds. Repetitive handoff detection is off by default © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 17
  18. 2 Build flows with Swarm and Graph In a Graph,

    nodes run along edges by dependency Batch 1 Batch 2 (in parallel) Batch 3 order The entry point gets the original task checks order intake reply summarizes writes reply Other nodes get the task and the output of the dependencies that finished policy The Python SDK runs applies rule Entry gets the task Gets the task and 2 outputs nodes in batches, and waits for a whole batch to finish © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 18
  19. 2 Build flows with Swarm and Graph GraphBuilder: add nodes

    and edges, then build() graph_run.py lines 2, 17–28 from strands.multiagent import GraphBuilder b = GraphBuilder() b.add_node(intake, "intake") b.add_node(order, "order") b.add_node(policy, "policy") b.add_node(reply, "reply") b.add_edge("intake", "order") b.add_edge("intake", "policy") b.add_edge("order", "reply") b.add_edge("policy", "reply") b.set_entry_point("intake") b.set_execution_timeout(600) graph = b.build() © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Output Status.COMPLETED intake → policy → order → reply Add nodes with add_node(agent, "name") and edges with add_edge("from", "to") Without set_entry_point, the nodes with no incoming edge are the entry points result.execution_order is the order the nodes ran in 19
  20. 2 Build flows with Swarm and Graph Conditional edges choose

    the path graph_cond.py lines 12–16, 23–24, 28–31 def says(word): def condition(state): r = state.results.get("intake") return r is not None and word in str(r.result) return condition b.add_edge("intake", "refund", condition=says("refund")) b.add_edge("intake", "order", condition=says("delivery")) for task in ("This is C-1002. Refund my keyboard.", "When will the C-1001 hub arrive?"): result = graph(task) print([n.node_id for n in result.execution_order]) Output ['intake', 'refund'] ['intake', 'order'] A condition function takes state and returns a bool It reads the result of an earlier node in state.results and decides whether to take the edge Output line 1 is the refund inquiry, line 2 the delivery inquiry © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 20
  21. 2 Build flows with Swarm and Graph In Python, nodes

    do not wait for all inputs graph_and.py lines 3, 9–12, 23–25 (NEED is ["order", "amount"]) from strands.multiagent.base import Status def all_done(state): return all(k in state.results and state.results[k].status == Status.COMPLETED for k in NEED) cond = all_done if wait_all else None b.add_edge("order", "reply", condition=cond) b.add_edge("amount", "reply", condition=cond) To wait for all, put this condition on each edge No condition: reply ran in the same batch as amount, then again after it. On slide 18, both sources of reply ended in one batch Output (edges: intake to order and policy, policy to amount, order and amount to reply) no condition ['intake', 'order', 'policy', 'amount', 'reply', 'reply'] wait for all ['intake', 'policy', 'order', 'amount', 'reply'] © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 21
  22. 2 Build flows with Swarm and Graph Use a limit

    to stop a Graph with a loop graph_loop.py lines 28–34 b.add_edge("draft", "review") b.add_edge("review", "draft", condition=again) b.add_edge("review", "send", condition=says("OK")) b.set_entry_point("draft") # set the entry point b.set_max_node_executions(limit) b.set_execution_timeout(300) b.reset_on_revisit(True) The loop adds an edge into draft too, so set the entry point with set_entry_point reset_on_revisit(True) resets the state of a node that runs again Output (line 43: again is says("FIX") of lines 16–20 for limit 10, always() for limit 3) limit 10: Status.COMPLETED ['draft', 'review', 'draft', 'review', 'send'] limit 3: Status.FAILED ['draft', 'review', 'draft'] always() (lines 38–39) returns True, so the limit of 3 ends it in Status.FAILED before any OK © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 22
  23. 2 Build flows with Swarm and Graph A fixed-order Workflow

    can be plain functions workflow.py lines 11–13, 16–19 (agent(), lines 6–8, is node() of appendix A3) order = agent("You look up orders.", [get_order_history]) policy = agent("Rule: refund late items in full, even before arrival.") writer = agent("You write replies to customers.") def handle(question): found = order(f"Look up the order: {question}") rule = policy(f"Apply the rule to this order: {found}") return writer(f"Write a reply from this decision: {rule}") Output of line 22 Your keyboard was delayed. Full refund approved now. Please contact support to claim it. © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Line 22 asks "Can I get a refund for the C-1002 keyboard?" Each prompt holds the result of the agent before it You decide the order and what is passed on 23
  24. 07 Multi-agent agent card Part 3 Call agents across processes

    with A2A © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. A2AServer A2AAgent 24
  25. 3 Call agents across processes with A2A A2AAgent calls A2AServer

    over HTTP Calling process Another process (server) GET /.well-known/agent-card.json A2AAgent endpoint=... A2AServer agent_factory agent card (name, description, skills) POST / (JSON-RPC) An Agent per context_id reply (becomes an AgentResult) The server serves the agent card, and takes JSON-RPC requests at the root path A2A also connects agents built on other platforms and frameworks © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 25
  26. 3 Call agents across processes with A2A Install with [a2a]

    to use A2A Install as in the docs pip install 'strands-agents[a2a]' This deck: pyproject.toml line 7 (uv sync) "strands-agents[a2a]==1.64.0", a2a_deps.py lines 4–12 # What strands-agents[a2a] requires, with the versions seen = [] for req in requires("strands-agents"): if not req.endswith("extra == 'a2a'"): continue name = re.match(r"[A-Za-z0-9_.-]+", req).group() if name not in seen: seen.append(name) print(f"{name:<10} {version(name)}") © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Output (packages, versions) a2a-sdk 0.3.26 fastapi 0.162.3 httpx 0.28.1 starlette 1.10.0 uvicorn 0.54.0 The core SDK, plus the A2A protocol dependencies 26
  27. 3 Call agents across processes with A2A Call A2AAgent like

    a local Agent a2a_call.py lines 4–5, 14–17 (lines 14–17 are inside async def main()) from a2a.client import ClientConfig from strands.agent.a2a_agent import A2AAgent remote = A2AAgent( endpoint="http://127.0.0.1:9000", client_config=ClientConfig(httpx_client=http)) result = await remote.invoke_async("When will the C-1001 hub arrive?") Output of lines 18–20 AgentResult end_turn assistant USB-C hub ships, due Nov 11. Earbuds already delivered Nov 2. It returns an AgentResult, as a local Agent does A running server needs only endpoint="http://localhost:9000" client_config passes http, an httpx client sending in-process (A5) © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 27
  28. 3 Call agents across processes with A2A A2AAgent works in

    two patterns so far Pattern A2AAgent Tool of the desk Works. Call it inside a @tool function (code on the left) Graph node Works (Python only). Add it with add_node() like a local Agent (code on the right) Swarm Not supported. Handoffs need features the A2A protocol does not have yet a2a_tool.py lines 21–25 @tool def ask_order_desk(q: str) -> str: """Ask the order desk of another service.""" r = remote()(q) return r.message["content"][0]["text"] © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. a2a_tool.py lines 35–36 b = GraphBuilder() b.add_node(remote(), "remote") remote() returns an A2AAgent. The output of the run is in appendix A6 28
  29. 3 Call agents across processes with A2A A2AServer makes an

    Agent per conversation a2a_server.py lines 2, 7–15, 18, 20–21 from strands.multiagent.a2a import A2AServer def create_agent(context_id: str) -> Agent: # A new Agent for each conversation (context_id) return Agent( name="order_desk", description="Looks up orders", system_prompt=SHORT, model=model, tools=[get_order_history], callback_handler=None, ) server = A2AServer(agent_factory=create_agent) if __name__ == "__main__": server.serve() # the default is 127.0.0.1:9000 © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Output of a2a_card.py (agent card) name: order_desk description: Looks up orders url: http://127.0.0.1:9000/ streaming: True skills: ['get_order_history'] create_agent takes a context_id and returns an Agent serve() starts it. In 1.64.0 the default is 127.0.0.1:9000 (change it with host= and port=) 29
  30. 3 Call agents across processes with A2A Knowing the context_id

    is enough to join The server keeps one conversation per context_id. The caller sends that value, so a Same context_id caller who knows the context_id of someone A2AServer else can join that conversation If several tenants share one server, check identity at the transport or gateway layer The server keeps at most max_contexts conversations (default 1000). Past that, it drops the one used least recently © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 30
  31. 07 Multi-agent triage Part 4 Stop for human approval ©

    2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Status.INTERRUPTED refund answer y 31
  32. 4 Stop for human approval A hook stops the run,

    and the answer resumes it 1 swarm(task) 2 Hook on BeforeNodeCallEvent 3 Status.INTERRUPTED event.interrupt(name, reason) result.interrupts stops and returns 6 interrupt() returns "y" if not y, cancel_node 5 swarm(responses) 4 Made from the answer the same hook runs again interruptResponse Output of swarm_approve.py Status.INTERRUPTED ['desk-approval'] Status.COMPLETED Refund processed successfully. Funds arrive in 3-5 days. © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Resuming with the answers runs the same hook again Line 1 stopped, line 2 resumed 32
  33. 4 Stop for human approval Write the approval hook as

    a HookProvider approval.py lines 14–20 def approve(self, event: BeforeNodeCallEvent) -> None: if event.node_id != "refund": return answer = event.interrupt(f"{self.app_name}-approval", reason={"node": "refund"}) if answer.lower() != "y": event.cancel_node = "not approved" register_hooks adds approve for BeforeNodeCallEvent. Appendix A4 If the answer is not y, it sets a reason in cancel_node swarm_approve.py lines 2, 17 from strands.multiagent import Status, Swarm swarm = Swarm([triage, refund], hooks=[ApprovalHook("desk")]) A Swarm takes it with hooks=. A Graph adds it with set_hook_providers (next slide) © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 33
  34. 4 Stop for human approval A cancelled Graph node raises

    an error in Python graph_approve.py lines 2, 17–29 from strands.multiagent import GraphBuilder b.set_hook_providers([ApprovalHook("desk")]) b.set_execution_timeout(600) graph = b.build() result = graph("This is C-1002. Refund my keyboard.") print(result.status) responses = [{"interruptResponse": { "interruptId": i.id, "response": "n"}} for i in result.interrupts] try: result = graph(responses) except RuntimeError as e: print("RuntimeError:", e) © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. Output Status.INTERRUPTED RuntimeError: not approved set_hook_providers adds the hook, and graph(responses) resumes the run Answering n cancels the node (FAILED) and raises RuntimeError 34
  35. Summary Summary 1 An agent in the tools of another

    agent becomes a tool that takes an input string. as_tool() sets the tool name, whether context is kept, and delegate 2 In a Swarm, the agents hand off by themselves. In a Graph, edges and conditions set the flow. Give both limits on counts and time 3 Call an agent of another service with A2AAgent, and serve one with A2AServer. Stop for human approval with an interrupt in BeforeNodeCallEvent, then resume © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 35
  36. Summary Read next 08 Deploy and secure for production Put

    the agents you built into production, and secure them 03 Hooks and lifecycle controls How to register hooks, as with BeforeNodeCallEvent in this deck © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 36
  37. Appendix A1 The code this deck ran File Slides File

    Slides File Slides smallest.py 8 graph_cond.py 20 a2a_server.py 29 two_tools.py 9 graph_and.py 21 a2a_card.py 29, 41 tool_spec.py 10 graph_loop.py 22 swarm_approve.py 32, 33 as_tool.py 11 workflow.py 23 approval.py 33, 40 delegate.py 13 a2a_deps.py 26 graph_approve.py 34 swarm_run.py 16, 39 a2a_call.py 27, 41 graph_run.py 19, 39 a2a_tool.py 28, 42 All in d07/ of the help desk, not published. Run on 2026-11-11 with strands-agents 1.64.0 and Amazon Bedrock in Tokyo (global.anthropic.claude-sonnet-5, global cross-Region inference, which can run outside Tokyo) © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 37
  38. Appendix A2 The SHORT prompt and the model the slides

    use base.py lines 2–5 from agent import model # noqa: F401 SHORT = """Answer in at most two sentences, with no markdown symbols. Keep each sentence to 6 words or fewer, one sentence per line.""" agent.py lines 19–22 model = BedrockModel( model_id="global.anthropic.claude-sonnet-5", region_name="ap-northeast-1", # Tokyo ) get_order_history reads a ledger of made-up orders, and process_refund returns an acceptance message (@tool functions in tools.py). From the project root, above d07/, run uv run -m d07.smallest © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 38
  39. Appendix A3 The functions that make agents and nodes swarm_run.py

    lines 7–11 (the agents of the Swarm) def member(name, description, tools=()): return Agent(name=name, description=description, system_prompt=description + ". " + SHORT, model=model, tools=list(tools), callback_handler=None) graph_run.py lines 7–9 (the nodes of the Graph) def node(prompt, tools=()): return Agent(system_prompt=prompt + " " + SHORT, model=model, tools=list(tools), callback_handler=None) member() in swarm_approve.py, and node() in graph_cond.py and graph_approve.py, have the same shape. agent() in workflow.py (lines 6–8, slide 23) is this node() under another name © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 39
  40. Appendix A4 approval.py lines 1–12 (line 14 on: slide 33)

    approval.py lines 1–12 from strands.hooks import (BeforeNodeCallEvent, HookProvider, HookRegistry) class ApprovalHook(HookProvider): """Stop before the refund node and wait for a person to approve.""" def __init__(self, app_name: str) -> None: self.app_name = app_name def register_hooks(self, registry: HookRegistry) -> None: registry.add_callback(BeforeNodeCallEvent, self.approve) © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 40
  41. Appendix A5 How we tried A2A with no port opened

    a2a_call.py lines 9–13 async def main(): # Send to the server in this process, with no port opened app = server.to_starlette_app() http = httpx.AsyncClient( transport=httpx.ASGITransport(app=app), timeout=120) a2a_card.py lines 4–6 # Call the server in this process, with no port opened app = server.to_starlette_app() card = TestClient(app).get("/.well-known/agent-card.json").json() We called the ASGI app of the server inside the process, with the ASGITransport of httpx and the TestClient of Starlette. No port was opened © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 41
  42. Appendix A6 A2AAgent as a tool and a Graph node

    (slide 28) a2a_tool.py lines 28–30, 35–40 desk = Agent(model=model, system_prompt=SHORT, tools=[ask_order_desk], callback_handler=None) answer = desk("When will the C-1001 hub arrive?") b = GraphBuilder() b.add_node(remote(), "remote") b.add_node(reply, "reply") b.add_edge("remote", "reply") b.set_execution_timeout(600) r = b.build()("When will the C-1001 hub arrive?") Output Tool: Hub arrives November 11. It's already shipped and moving. Graph: Status.COMPLETED ['remote', 'reply'] © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 42
  43. Appendix Sources Strands Agents documentation, “Coordinate multiple agents”, November 2026

    (slides 4, 6–8, 23, 35) https://strandsagents.com/docs/user-guide/sdk/multi-agent/multi-agent-patterns/ Strands Agents documentation, “Agents as tools”, November 2026 (slides 4, 8–13, 28, 35) https://strandsagents.com/docs/user-guide/sdk/multi-agent/agents-as-tools/ Strands Agents documentation, “Swarm Multi-Agent Pattern”, November 2026 (slides 4, 15–17, 35) https://strandsagents.com/docs/user-guide/sdk/multi-agent/swarm/ Strands Agents documentation, “Graph Multi-Agent Pattern”, November 2026 (slides 4, 18–22, 28, 34, 35) https://strandsagents.com/docs/user-guide/sdk/multi-agent/graph/ © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 43
  44. Appendix Sources (continued) Strands Agents documentation, “Agent Workflows: Building Multi-Agent

    Systems with Strands Agents SDK”, November 2026 (slides 4, 23, 35) https://strandsagents.com/docs/user-guide/sdk/multi-agent/workflow/ Strands Agents documentation, “Agent-to-Agent (A2A) Protocol”, November 2026 (slides 4, 25–30, 35) https://strandsagents.com/docs/user-guide/sdk/multi-agent/agent-to-agent/ Strands Agents documentation, “Interrupts in Multi-Agent Systems”, November 2026 (slides 4, 32–35) https://strandsagents.com/docs/user-guide/sdk/interrupts-multi-agent/ The code we ran and its output, from the help-desk agent (English copy, made for this series and not published), strands-agents 1.64.0, Amazon Bedrock in Tokyo, 2026-11-11 (slides 8–13, 15, 16, 18–23, 25–29, 32–34, 37–42) © 2026, Amazon Web Services, Inc. or its affiliates. All rights reserved. 44