The situation
A support team wants an assistant that answers policy questions from subscribers. The shape is fixed and everyone already knows it: take the question, pull the relevant passages from a knowledge base built on the policy documents, check whether the retrieval actually found something on topic, and then either draft an answer grounded in those passages or hand the question to a fallback that files a ticket for a human. Every request walks the same path. The only variation is the branch on whether the knowledge base returned anything useful.
The first instinct is to build a Bedrock agent, because the model is doing the interesting part. That instinct is worth questioning. The sequence here is not something the model needs to discover; a person can draw it on a whiteboard in a minute, and it will look the same for every question. What the team wants is a predictable pipeline they can trace, version, and ship, with as little glue code as possible, and with the whole thing staying inside Bedrock next to the knowledge base and prompts it already uses.
The choice sits between three ways of assembling the steps: a model-driven Bedrock agent, a visually-defined Bedrock Flow, and an AWS Step Functions state machine. Each puts the decision about what happens next in a different place, and for a known sequence that placement is the whole question.
What actually matters
The first thing to name is where the control flow is decided. In a Bedrock agent the foundation model decides the sequence at run time: it reads the request, picks a tool or a knowledge base, observes the result, and chooses the next step, looping until it is done. That earns its cost when the path genuinely cannot be known in advance. It is exactly what you do not want when the path is known, because model-chosen control flow is nondeterministic, harder to test, and spends a model call every time the model stops to decide what to do next. A Bedrock Flow inverts this: a designer places the nodes and draws the links, and the runtime walks the graph in the order you wired it. The model still runs inside a prompt node or an agent node, but it never chooses the order.
The second is how much of the work is Bedrock-native. This job is prompts, a knowledge base, and a condition; those are all first-class Bedrock building blocks. A Flow is built precisely for stitching those blocks together with the least assembly, and it keeps the whole pipeline in one place with the knowledge base and the prompts it calls. If instead the job were mostly reads and writes to other AWS services, fan-out across thousands of records, and long durable runs, the centre of gravity would move outside Bedrock, and a Flow would be the wrong shape.
The third is how much durability, error handling, and cross-service reach the run needs. A Flow executes a graph for a single invocation; it is not a durable, hours-long, resumable workflow engine with per-step retry policies and human-approval pauses. The support pipeline does not need those: it answers one question in one pass. When a job does need durable execution, exactly-once semantics, fan-out, or a human pause measured in days, that is Step Functions territory, and a Flow is not trying to compete there.
The fourth is deployment discipline. The team wants to change a prompt without breaking what is live. Bedrock Flows are versioned, and you point traffic at an alias rather than at the mutable draft, so you can publish a new version and move the alias when you are ready, or roll it back by moving the alias. That is the difference between a graph you can iterate on and a graph you are afraid to touch.
Underneath all of it: reach for the model-driven agent only when the value it adds, discovering a path you could not draw, outweighs what it costs in determinism and control. For a pipeline whose steps you already know and whose blocks are Bedrock-native, the drawn graph is the cheaper, more predictable answer.
What we’ll filter on
- Is the sequence known ahead of time, or does the model need to discover it at run time?
- Are the building blocks Bedrock-native (prompts, knowledge bases, agents), or does the work spread across the wider AWS surface?
- How much durability, per-step retry, fan-out, and human-approval waiting does a single run need?
- How much assembly and glue code are you willing to own versus have the runtime provide?
- Does the workflow need clean versioning and a safe way to promote or roll back what is live?
The flow landscape
-
A Bedrock agent. One agent, an instruction prompt, one or more 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. (each backed by a Lambda function or an API schema), and optional knowledge bases. The foundation model runs the reason-act-observe loop and chooses each step. Good when the path varies request to request and cannot be drawn in advance, and when the whole job is essentially reasoning with tools. Its ceiling for a known pipeline is that the control flow is nondeterministic, every decision point is another model call, and there is no drawn graph to trace or version as a fixed sequence.
-
A Bedrock Flow. A low-code visual builder and runtime, native to Bedrock, for a defined and mostly-deterministic workflow. You place nodes and connect them with data links: an input node and an output node at the edges; prompt nodes that run a prompt (inline or from Prompt Management); knowledge-base nodes that query a knowledge base; agent nodes that hand one step to a Bedrock agent; Lambda nodes for custom code; condition nodes that branch on the data flowing through; iterator and collector nodes to loop over a set; and a Lex node to bring in an Amazon Lex bot. Because you draw the links, the control flow is yours, designed ahead of time, not decided by a model at run time. Flows are versioned and deployed behind aliases. Good when the sequence is known, the blocks are Bedrock-native, and you want predictability and traceability with less code than wiring it by hand. Its limits are that it is Bedrock-centric rather than a general workflow engine, and it is not built for hours-long durable runs, large fan-out, or human-approval waits.
-
An AWS Step Functions state machine. A general-purpose, durable workflow orchestrator. You define states: task states that call a service, a Lambda, or Bedrock; choice states that branch; parallel states; a Map state that fans out across a collection; wait states; and success or failure states. Standard workflows run durably for up to a year with exactly-once execution and a full history; Express workflows run up to five minutes for high-volume, short-lived work. Each state can carry its own retry and catch policy, and the callback pattern lets a run pause on a task token until a human or external system responds. It integrates directly with a broad range of AWS services and invokes Bedrock as one step among many. The right home when durability, retries, fan-out, cross-service reach, or human pauses dominate, and the model is a participant rather than the whole job. The sibling piece, when to orchestrate with Step Functions instead of an agent, walks that case in depth.
You can also layer them rather than choosing once. A Step Functions state machine can invoke a Bedrock model, an agent, or a Flow as a single task state, and a Flow can drop in an agent node for one open-ended step. The engines are layers, not rivals; the question is which one owns the sequence for the job in front of you.
Side by side
| Property | Bedrock agent | Bedrock Flow | Step Functions |
|---|---|---|---|
| Control flow decided by | Model, at run time | Designer, ahead of time | Designer, ahead of time |
| Deterministic / testable | ✗ | ✓ | ✓ |
| Low-code, visual build | Configured, not drawn | ✓ (drag-and-wire graph) | ✓ (Workflow Studio) |
| Bedrock-native building blocks | ✓ | ✓ (prompts, KBs, agents, Lex) | Via task integrations |
| Durable long-running execution | ✗ | ✗ | ✓ (up to 1 year, Standard) |
| Built-in per-step retry and catch | ✗ | ✗ | ✓ |
| Fan-out and parallelism | ✗ | Iterator over a set | ✓ (Map, Parallel) |
| Human-approval pause | Build it yourself | ✗ | ✓ (callback task token) |
| Reach across AWS services | Via action-group Lambdas | Bedrock-centric plus Lambda | ✓ (broad direct integrations) |
| Versioned deployment | Aliases | ✓ (versions and aliases) | ✓ (versions and aliases) |
| Best when | Path must be discovered at run time | Known Bedrock-native pipeline | Durable cross-service process |
Reading it for the support pipeline: the sequence is known, so the model-driven agent is the wrong axis; the run is a single pass over Bedrock-native blocks with one branch, so the durability and cross-service reach of a state machine is more engine than the job needs; the Flow is the fit.
The picks in depth
A Bedrock Flow. The right shape when the sequence is known, the building blocks are Bedrock-native, and you want a predictable graph with little assembly. You build it visually and the runtime executes the nodes in the order you wired them, so every run walks the same path and traces node by node. The pieces slot together: an input node hands the question in; a knowledge-base node retrieves the relevant passages; a condition node checks whether the retrieval cleared a relevance threshold; on the yes branch a prompt node drafts a grounded answer and hands it to the output node; on the no branch a Lambda node files a ticket. Nothing here needs the model to decide the order, so nothing spends a model call deciding it. When one step genuinely does need open-ended reasoning, an agent node drops a model-driven step into the otherwise deterministic graph without giving the whole pipeline over to the model. Deployment is disciplined: publish a version, point an alias at it, and move or roll back the alias to control what is live. Where a Flow runs out of road is scale and durability. It executes a graph for a single invocation; hours-long runs, large fan-out with independent per-branch retries, and human-approval waits measured in days are not what the Flow runtime is built to carry.
A Bedrock agent. The right shape when the sequence cannot be drawn ahead of time and the whole job is reasoning with tools. The model handles branching for free: it looks something up, decides it needs another fact, fetches it, and answers, without you specifying that path. That flexibility is the point, and it is worth its nondeterminism when the path truly varies. For the support pipeline it is the expensive answer to a question nobody asked, because the path does not vary; a fixed graph does the same work with fewer model calls and a trace you can prove. Reach for the agent when you cannot draw the sequence, not for a pipeline you already understand. A Flow can still borrow the agent for one node when a single step needs that judgement.
AWS Step Functions. The right shape when the workflow is durable, cross-service, and mostly not model calls: long runs that must survive throttling and slow dependencies, fan-out across thousands of records with per-item retry, parallel branches, and human pauses on a callback token. The model becomes one task among many, and retries, parallelism, and the human wait are first-class primitives rather than code you write and operate. The cost is that you design and maintain the state machine, which is more scaffolding than a single-pass, Bedrock-native pipeline needs. For the support question the run is one pass over Bedrock blocks, so the state machine is more engine than the job asks for; when the job grows a durable, cross-service spine, that is when it earns its place.
A worked example: the policy-answer pipeline as a Flow
The job: answer a subscriber policy question from a knowledge base, or escalate to a human when retrieval comes up short. Drawn as a Flow, it is six nodes wired in a fixed order.
The input node receives the question text. Its output link feeds a knowledge-base node, which queries the policy knowledge base and passes back the retrieved passages along with their relevance scores. A condition node reads that output and branches: if the best score clears the threshold, control flows to a prompt node; if not, it flows to a Lambda node. The prompt node runs a grounded-answer prompt from Prompt Management, taking both the original question and the retrieved passages as inputs, and writes a drafted answer to the output node. The Lambda node, on the other branch, files a ticket with the question attached and writes a holding message to the output node instead. Every request walks one of those two branches, and which one is decided by the data, not by a model choosing what to do next.
Once it behaves, you publish a version and point the production alias at it. A later change, a tighter grounding prompt or a different relevance threshold, becomes a new version; you move the alias when it is ready, or move it back if it regresses. The graph is small, deterministic, entirely inside Bedrock, and traceable node by node. That is the shape a Flow is for, and it is the shape the support team already had in their heads.
What’s worth remembering
- A Bedrock Flow is a graph of nodes connected by data links, so the control flow is designed by you ahead of time, not decided by a model at run time. That is the whole difference from an agent.
- The node types cover the common pipeline shapes: input and output at the edges, prompt nodes, knowledge-base nodes, agent nodes, Lambda nodes, condition nodes, iterator and collector nodes, and an Amazon Lex node.
- Reach for a Flow when the sequence is known, the blocks are Bedrock-native, and you want predictability and traceability with less code than wiring it by hand.
- Reach for a single agent instead when the path must be discovered at run time; the model choosing the sequence is the point, and its nondeterminism is the price you accept for that.
- A Flow can still drop in an agent node for one open-ended step, so a mostly-deterministic graph can borrow model-driven judgement in exactly one place.
- Flows are Bedrock-native and low-code, and they are versioned with aliases, so you publish a version, point an alias at it, and promote or roll back by moving the alias.
- A Flow executes a graph for a single invocation; it is not a durable, hours-long, resumable workflow engine, and it has no built-in per-step retry policy or human-approval pause.
- When you need durability, exactly-once execution, per-state retry and catch, fan-out with Map, parallel branches, broad AWS-service integration, or a callback human pause, that is AWS Step Functions, not a Flow.
- The engines layer rather than compete: Step Functions can invoke a model, an agent, or a Flow as one task, and a Flow can invoke an agent as one node.
- Match the assembler to the job: a path the model must discover, an agent; a known Bedrock-native pipeline you draw and version, a Flow; a durable cross-service process with the model as one step, a state machine.