Exam Room · Advanced GenAI

Orchestrating Multiple Bedrock Agents

July 26, 2026 · 31 min read

Generative AI Development · part of The Exam Room

The situation

The assistant behind the subscriber help desk started life as a single agent: one foundation model, one knowledge base of help articles, one tool that could look up an account. It answered “when is my next delivery” and “how do I pause” without fuss.

The job has grown. A single request now often needs several distinct things done: pull the subscriber record, check the delivery schedule for their postcode, work out whether a prorated charge is correct against the billing rules, and, if it cannot be resolved automatically, open a ticket and draft a reply in the right tone. Some of that is retrieval, some is arithmetic against a documented policy, some is a call into an internal API, and some is generation. The steps are not always the same from one request to the next, and a few of them want genuinely different expertise.

The team can keep piling tools and knowledge bases onto the one agent, split the work across specialist agents with an orchestrator on top, or pin the common path down as a fixed pipeline. Each choice moves the control flow, the decision about what happens next, to a different place.

What actually matters

Control flow is the first thing to place. In a single agent, the model decides the sequence: it reads the request, picks a tool or a knowledge base, looks at the result, and decides the next step, looping until it has an answer. That is powerful when the path cannot be known in advance, and it is exactly what you give up when you want the same steps every time. A fixed workflow inverts this: you draw the graph, wiring prompts, retrieval, tool calls, and conditions together, and the runtime walks the graph you designed. The model still does the work inside each step, but it does not choose the order.

The second is whether the task really decomposes into distinct specialisms. A supervisor topology puts one agent in front of several workers, each with its own instructions, tools, and knowledge. The supervisor reads the request, decides which workers to invoke, passes them sub-tasks, and stitches the results together. This is worth it when the sub-tasks want different system prompts, different tools, or different guardrails, a billing specialist that must never hallucinate a number, a tone-of-voice drafter that should be a little freer. It is not worth it when you are really just chaining steps that one agent could hold in its head.

The third is the budget for extra model hops. Every agent turn is at least one foundation-model call, often several as it reasons and calls tools. A supervisor delegating to three workers is not three calls; it is the supervisor’s own reasoning plus each worker’s full reasoning loop, and the results flowing back up. That multiplies both latency and token cost. A fixed graph with two prompt steps and a retrieval lookup is a handful of calls you can count in advance; a supervisor over workers is a tree you can only bound loosely.

The fourth is auditability and predictability. When a step must happen the same way every time, in a compliance path, a refund calculation, a data-handling sequence, model-chosen control flow is a liability: it is hard to prove that the model always takes the required step. A drawn graph gives you a diagram you can point at and a run you can trace step by step. The more the outcome has to be defensible, the more that is worth.

Underneath all of it: the simplest workable shape wins. Not every multi-step task needs an agent at all. If the sequence is fixed and you already own the code, a loop in your own application, call the model, run a tool, call the model again, is the most predictable and the cheapest thing on the table.

What we’ll filter on

  1. Who decides the control flow, the model at run time, or the designer ahead of time?
  2. Does the task genuinely split into distinct specialisms with different tools, prompts, or guardrails?
  3. What is the latency and cost budget for extra model hops?
  4. How much does the path need to be predictable, auditable, and the same every time?
  5. How much orchestration and failure surface is the team willing to own?

The landscape

A single agent on Bedrock AgentCore

One reasoning loop that you write, hosted on a managed serverless runtime with per-session isolation, reaching its tools through the gateway, which exposes existing APIs and Lambda functions through one uniform interface rather than as bespoke agent actions. The model runs the familiar reason-act-observe cycle; the difference from the fully-managed predecessor is that the loop is code you own rather than a service that runs it for you. Good for a bounded task where the path varies but the skills do not: “answer support questions about this account, using these tools.” Its strength is flexible model-driven control flow inside one context; its ceiling is that everything shares one instruction prompt and one set of guardrails.

A supervisor over specialist workers

The topology is expressed in whichever agent framework the team already uses, and AgentCore runs it: each agent gets its own isolated session on the runtime, they share the gateway for tools and the identity capability for scoped credentials, and one observability trace covers the whole fan-out. The supervisor’s model decides which workers to call and with what sub-task, receives their outputs, and composes the final answer.

Because the routing is code, a clear-intent request can skip the supervisor’s reasoning pass and go straight to one worker, which is a decision you make rather than a mode you switch on.

Fits when the problem breaks into distinct domains, billing, delivery, tone, that each want their own prompt and tools. The cost is more model calls, higher and less predictable latency, and a larger failure surface: any worker can fail, time out, or return something the supervisor must handle.

Bedrock Flows

A visual builder and runtime for a deterministic workflow. You place nodes, prompt nodes, knowledge-base nodes, agent nodes, Lambda nodes, condition nodes, iterators, input and output, and wire the data between them. The graph is fixed; the model runs inside nodes but never chooses the order.

Fits when the steps are known ahead of time and you want predictability, traceability, and less nondeterminism than an agent gives. It can still invoke an agent as one node, so “mostly fixed with one flexible step” is expressible.

The cost is that you design and maintain the graph, and genuinely novel paths that you did not draw cannot happen.

Application-code chaining over the Converse API

No managed orchestration at all: your own code calls the model with the Converse API, inspects the response, runs a tool if the model asked for one via toolUse, and calls again with the toolResult. You own the loop, the retries, the branching. Fits simple deterministic sequences and cases where you want full control and minimal managed surface.

The cost is that you build and operate everything the managed options would have handled, and complex branching becomes your code to maintain.

Step Functions around the pieces

For workflows that reach well beyond the model, long-running human approvals, fan-out across many records, integration with dozens of AWS services, a Step Functions state machine can orchestrate Bedrock calls, agents, and Flows as steps. It is the general-purpose orchestrator when the GenAI work is one part of a larger business process rather than the whole of it. Heavier to build; the right home when durability, retries, and broad service integration dominate.

Evaluation

Side by side

Option Control flow decided by Handles distinct specialisms Extra model hops Predictable / auditable Ops and failure surface
Single agent on AgentCore Model, at run time ✗ (one prompt, one guardrail) Low to moderate ✗ (path varies) Low
Supervisor over workers Model, at run time High, hard to bound High (many agents)
Bedrock Flows Designer, ahead of time ✓ (agent node per step) Countable Moderate
Converse API chain Your code Partial (you route) Low, you control You own it all
Step Functions Designer, ahead of time ✓ (across services) Countable Moderate to high

Reading it for this situation, a support flow where some steps are fixed policy and one or two want real specialism, the field narrows to three: a single agent if the skills are close enough to share a prompt, a supervisor over workers if billing and drafting genuinely want to be separate, and a Flow if the path is stable enough to draw and needs to be defensible.

The three shapes side by side

Bedrock Flow designer fixes the order Single agent model picks each step Supervisor + workers model delegates by skill Input Knowledge base Condition Lambda Output predictable, traceable, fixed Agent reason + act loop Tool A Tool B Knowledge base flexible, one prompt shared Supervisor delegates Billing agent Delivery agent Drafting agent specialised, more hops and failure
Same request, three places to put the control flow: the designer draws it, one model reasons through it, or a supervisor model splits it by skill.

The solution

Split it into a supervisor over specialist workers. Both halves of what changed point here. The steps are not the same from one request to the next, which rules out drawing the sequence ahead of time, and a few of them want genuinely different expertise, which is the condition a supervisor topology exists for.

Give each worker the prompt, tools, and guardrails its job actually needs. The billing worker gets a tight prompt, a calculation tool, and a guardrail against inventing figures. The delivery worker gets the schedule tools and the knowledge base. The drafting worker gets a looser prompt, room to write warmly, and no numeric authority at all. The supervisor reads the request, decides which of them the request needs, passes each a sub-task, and composes what comes back. Each specialist is simpler and safer than one generalist trying to be all three, and a drafting worker with no numeric authority also has no credential that could charge a card.

Determinism where money moves comes from the tool, not from the topology. A refund calculation that must happen the same way every time belongs behind a calculation tool with its own validation and its own scoped role, invoked by the billing worker. The model proposes the call; the tool and its guard decide whether it runs and what it returns. That gives the compliance property without freezing the path everything else takes, which is the trade a drawn graph would have forced.

The bill is real and worth planning for. The supervisor reasons, then each invoked worker runs its own full loop, so one user request fans out into many model calls and p99 latency climbs with the depth of delegation. Every worker is also a thing that can time out or return something unusable, and the supervisor has to handle each case. One observability trace covering the whole fan-out is what keeps that debuggable rather than guesswork. Where clear-intent requests dominate, route them straight to one worker and skip the supervisor’s reasoning pass, which claws back much of the latency.

Each worker gets its own isolated session on the runtime, shares the gateway rather than carrying its own copy of every integration, and draws scoped credentials from the identity capability, so specialisation in the prompt is matched by specialisation in what each worker can actually reach.

Why not a single agent. It is what they have, and it is the cheapest model-driven option while the skills stay close enough to share a prompt. They no longer are. “Never invent a figure” for billing and “write warmly and loosely” for the reply are instructions that pull against each other, and one prompt serving both is the strain the team is already feeling.

Why not a Flow. A drawn graph gives a diagram you can point at and a run you can trace node by node, which is genuinely what a compliance path wants. It needs a stable path to draw, and this assistant does not have one: the steps vary per request, and a Flow cannot invent a path nobody drew. Keep it in mind for the sub-flows that do stabilise, and reach for an agent node inside one when a single step needs judgement.

Why not application-code chaining. For two or three known steps, owning the loop over Converse is less machinery than anything managed. This branches wider than that, and hand-rolled control flow at this size becomes the thing you wish you had expressed as a topology, with the retries, routing, and observability all yours to build.

Worked example

A subscriber writes: “I paused last month but I have still been charged, and my box did not arrive this week either.”

As a single agent. The one agent reads the message, calls the account tool to fetch the subscription and its pause history, calls the billing tool to check the charge against the pause date, queries the delivery knowledge base for the postcode’s schedule, decides the charge was an error and the delivery was correctly skipped, and drafts a reply. One prompt carried all of it; the model chose the order. It works because billing and drafting were close enough to share instructions. If the reply had needed a warmer register than the strict billing instructions allowed, the single prompt would have started to strain.

As a supervisor with workers. The supervisor reads the message and delegates: the billing worker (tight prompt, calculation tool, guardrail against inventing figures) confirms the charge should be reversed and returns the amount; the delivery worker checks the schedule and confirms the skip was correct; the drafting worker (looser prompt, no numeric authority) takes both findings and writes the reply. The supervisor composes the outcome. Each specialist was simpler and safer than one generalist, and the numeric guardrail lived exactly where numbers were handled. The request cost the supervisor’s reasoning plus three worker loops, and the reply came back a few seconds slower than the single agent managed.

As a Flow. Input node takes the message. A prompt node classifies it as a billing-and-delivery query. A knowledge-base node pulls the pause and delivery policy. A Lambda node computes whether the charge was valid against the pause date. A condition node branches: valid charge to a “explain the charge” prompt node, invalid charge to a Lambda that files a refund ticket and then a prompt node that drafts the apology. Output node returns the draft. Every run takes the same shape, and the refund step is provably always reached when the charge is invalid, which is exactly what you want when money moves.

All three resolve the subscriber’s problem. The difference is who decided the order, how many model calls it took, and whether you can point at a diagram afterwards and show it always does the right thing.

What’s worth remembering

  1. The real question is who decides control flow: the model at run time (agents) or the designer ahead of time (Flows, Step Functions, your own code).
  2. A single agent is the floor. Reach past it only when one prompt and one set of guardrails can no longer serve the whole job.
  3. Multi-agent’s cost is real. Each worker runs its own reasoning loop, so latency and token spend climb with the depth of delegation, and every worker is a new thing that can fail.
  4. Bedrock Flows trade flexibility for predictability: a fixed graph you can trace node by node, which needs a path stable enough to draw in the first place.
  5. A compliance requirement does not automatically mean a drawn graph. Determinism where money moves can come from a guarded tool the model calls rather than from freezing the path everything else takes.
  6. A Flow is not all-or-nothing. An agent node drops one model-driven step into an otherwise deterministic pipeline.

The answer is not universal. A task whose path the model must discover tips toward a single agent, and a task of truly distinct specialisms tips toward a supervisor and workers. The axis to defend it on is always the same: where the control flow should live.

These posts are LLM-aided. Backbone, original writing, and structure by Craig. Research and editing by Craig + LLM. Proof-reading by Craig.