The situation
The assistant behind the subscriber help desk started life as a single Bedrock Agent: one foundation model, one knowledge base of help articles, one Action groupThe bundle of API operations a Bedrock agent is allowed to call, described by a schema so the model knows what each one does. 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 action groups 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
The first thing worth naming is where control flow lives. In a single Bedrock Agent, the foundation model decides the sequence: it reads the request, picks an action group 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 Bedrock Flow inverts this: you draw the graph, prompts, knowledge bases, agents, Lambda functions, conditions, and iterators wired together, and the runtime walks the graph you designed. The model still does the work inside each node, but it does not choose the order.
The second is whether the task really decomposes into distinct specialisms. Multi-agent collaboration puts a supervisor agent in front of one or more collaborator agents, each a Bedrock Agent in its own right with its own instructions, tools, and knowledge. The supervisor reads the request, decides which collaborators to invoke, passes them sub-tasks, and stitches the results together. This earns its keep 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 does not earn its keep 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 collaborators is not three calls; it is the supervisor’s own reasoning plus each collaborator’s full reasoning loop, and the results flowing back up. That multiplies both latency and token cost. A deterministic Flow with two prompt nodes and a knowledge-base lookup is a handful of calls you can count in advance; a supervisor over collaborators 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 Flow gives you a diagram you can point at and a run you can trace node by node. The more the outcome has to be defensible, the more the fixed graph 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, an application-side loop over the Converse API, 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
- Who decides the control flow, the model at run time, or the designer ahead of time?
- Does the task genuinely split into distinct specialisms with different tools, prompts, or guardrails?
- What is the latency and cost budget for extra model hops?
- How much does the path need to be predictable, auditable, and the same every time?
- How much orchestration and failure surface is the team willing to own?
The orchestration landscape
-
A single Bedrock Agent. One agent, an instruction prompt, up to several action groups (each backed by a Lambda function or a defined API schema), and one or more associated knowledge bases. The foundation model runs the ReAct-style loop: reason, act, observe, repeat. Good for a bounded task where the path varies but the skills do not, “answer support questions about this account, using these tools.” Already covered in depth earlier in the series; the recap is that its strength is flexible model-driven control flow inside one context, and its ceiling is that everything shares one instruction prompt and one set of guardrails.
-
Multi-agent collaboration (supervisor plus collaborators). A supervisor agent is configured with collaborator agents, each a separate Bedrock Agent with an alias. The supervisor’s model decides which collaborators to call and with what sub-task, receives their outputs, and composes the final answer. Two routing modes exist: the default where the supervisor reasons about every delegation, and a routing mode that can hand a request straight to a single collaborator when intent is clear, saving the supervisor’s own reasoning pass. 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 collaborator 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 thetoolResult. 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.
Side by side
| Option | Control flow decided by | Handles distinct specialisms | Extra model hops | Predictable / auditable | Ops and failure surface |
|---|---|---|---|---|---|
| Single Bedrock Agent | Model, at run time | ✗ (one prompt, one guardrail) | Low to moderate | ✗ (path varies) | Low |
| Multi-agent (supervisor) | 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 collaborators 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
The picks in depth
A single Bedrock Agent. The right shape when the task varies but the skills do not, and when one instruction prompt and one guardrail configuration can cover the whole job. The model’s reasoning loop handles branching for free: it will look up the account, decide it needs the delivery schedule, fetch it, and answer, without you drawing that path. Keep it here as long as the action groups are close cousins. The moment two parts of the job want contradictory instructions, “never invent a figure” for billing versus “write warmly and loosely” for the reply, you are fighting one prompt to serve two masters, and that is the signal to split. Cost and latency are the lowest of the managed options because there is one agent doing the reasoning.
Multi-agent collaboration. The right shape when the work genuinely decomposes into specialists. Give the billing collaborator a tight prompt, a calculation tool, and a strict guardrail; give the drafting collaborator a looser prompt and no numeric authority; let the supervisor route. The payoff is that each specialist is simpler and safer than one generalist trying to be all of them, and the supervisor can, in principle, run independent collaborators to make progress on separate sub-tasks. The bill is real: the supervisor reasons, then each invoked collaborator runs its own full loop, so a single user request can fan out into many foundation-model calls, and p99 latency climbs with the depth of delegation. The failure surface grows too, every collaborator is a thing that can time out or return something unusable, and the supervisor’s prompt has to handle that. Reach for it when specialisation buys you more than the orchestration costs, not before. Where clear-intent requests dominate, the supervisor’s routing mode can send a request straight to one collaborator and skip the extra reasoning pass, which claws back some of the latency.
Bedrock Flows. The right shape when the path is known and needs to be defensible. Draw the graph: take the request, retrieve from the knowledge base, run a condition on whether the policy resolves automatically, branch to a Lambda that opens a ticket or to a prompt node that drafts the reply, emit the result. The order is fixed, so you can trace any run node by node and prove the required step always happens, which matters for anything with a compliance or money angle. A Flow is not all-or-nothing about flexibility: an agent node lets you drop one model-driven step into an otherwise fixed pipeline, so “mostly deterministic, one open-ended step” is a first-class shape. What you give up is novelty, if a request needs a path you did not draw, the Flow cannot invent it, and you maintain the graph as the process changes.
Application-code chaining over Converse. The right shape when the sequence is simple, fixed, and you would rather own the loop than adopt a managed orchestrator. The Converse API gives a uniform request across models and a clean tool-use contract: the model returns a toolUse block, your code runs the tool and returns a toolResult, and you call again. For two or three known steps this is less machinery than a Flow and cheaper to reason about, at the price of building the retries, branching, and observability yourself. When the branching gets genuinely complex, that home-grown control flow becomes the thing you wish you had drawn as a Flow.
A worked example: one subscriber request, three ways
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 action group to fetch the subscription and its pause history, calls the billing action group 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 collaborators. The supervisor reads the message and delegates: the billing collaborator (tight prompt, calculation tool, guardrail against inventing figures) confirms the charge should be reversed and returns the amount; the delivery collaborator checks the schedule and confirms the skip was correct; the drafting collaborator (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 collaborator 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
- 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).
- A single Bedrock Agent is the floor. Reach past it only when one prompt and one guardrail can no longer serve the whole job.
- Multi-agent collaboration buys specialisation: distinct prompts, tools, and guardrails per collaborator, with a supervisor routing between them.
- Multi-agent’s cost is real. Each collaborator runs its own reasoning loop, so latency and token spend climb with the depth of delegation, and every collaborator is a new thing that can fail.
- Bedrock Flows trade flexibility for predictability. A fixed graph you can trace node by node, which is what compliance and money paths need.
- A Flow is not all-or-nothing. An agent node drops one model-driven step into an otherwise deterministic pipeline.
- Not everything needs an agent. A fixed sequence you already own is cheapest and most predictable as a Converse API loop in your own code.
- Step Functions is the orchestrator when the GenAI work is one part of a larger, durable business process rather than the whole of it.
- Match the shape to the decision: known path, draw it; path the model must decide, give it an agent; distinct skills, split them; simple and fixed, chain it yourself.
The support desk lands on a Flow for the common, defensible path with an agent node for the one open-ended step, and keeps multi-agent in reserve for when billing and drafting genuinely need to be pulled apart. The answer is not universal, a task whose path the model must discover tips toward a single agent, a task of truly distinct specialisms tips toward collaborators, but the axis to defend it on is always the same: where the control flow should live.