Fast revision for choosing between model-decided and deterministic control flow, and the Bedrock services that back each one.
Options at a glance
| Approach | Control flow | Use when |
|---|---|---|
| Plain Converse call | You, in code | Single prompt in, single answer out; no tools, no loop |
| Converse loop with tool use | Model requests the tool, you run it | Model needs live data or actions; you keep the orchestration |
| Structured output | You constrain the shape | You want schema-validated JSON back, not prose |
| AgentCore harness | Harness orchestrates | Declared agent: a model, a system prompt, and a tool list, no loop to write |
| AgentCore runtime, your own loop | Your framework orchestrates | You need custom orchestration, stage-specific prompts, or real multi-agent routing |
| AgentCore gateway | n/a (tool surface) | Publishing existing APIs and Lambdas to any agent as MCP tools |
| Bedrock Flows | Deterministic, visual | Fixed low-code pipeline of prompts, conditions, loops, and steps |
| AWS Step Functions | Deterministic, durable | Long-running, retries, parallel branches, human-approval waits |
The split on the agent rows is who writes the loop. The harness takes a declaration and runs the cycle for you; the runtime takes an agent you wrote on any framework and runs the operational pieces around it. The harness sits on the runtime’s per-session microVMs, and both draw on the same memory, gateway, identity, and observability.
Decision rules
- If there is no loop and no external data, use a plain Converse call.
- If the model needs to fetch data or take an action, use tool use in the Converse loop.
- If you want validated JSON out, send a JSON schema in
outputConfig.textFormat, or mark the tool definitionstrict: true. - If the order of steps comes out of the model at runtime rather than out of your code, that is model-decided control flow, so reach for an agent: the harness when a declared model, prompt, and tool list covers it, your own loop on the runtime when it does not.
- If the sequence is fixed and you own it, that is deterministic control flow, so use Flows or Step Functions.
- If the pipeline is low-code, Bedrock-native, and built from prompts, conditions, and knowledge base lookups, use Bedrock Flows.
- If you need durable state, retries, timeouts, parallel branches, or a pause for human approval, use Step Functions.
- If the agent needs grounding from your own content, attach a knowledge base rather than stuffing documents into the prompt.
- If work splits into distinct specialisms, expose each specialist agent as a tool and let a coordinating agent call them.
- If a Lambda or REST API backs the tool, attach it to the gateway as a target; a remote MCP server attaches to the harness by URL with no gateway, and an inline function tool returns the call to your own code.
- If you are debugging why an agent did something, turn on CloudWatch Transaction Search for the account, enable tracing on the resource, and instrument your agent code with ADOT. Built-in metrics arrive without any of that.
- If you run a third-party framework agent in production, host it on the AgentCore runtime for memory, gateway, and identity.
- If a tool must never exceed a permission, put that limit in IAM or a gateway policy, not the prompt.
Traps
- An agent is not always the answer; a fixed workflow is cheaper, faster, and more predictable as Flows or Step Functions.
- Your code runs the tool in the Converse loop. The model emits a tool-use request with
stopReasonoftool_use, and you return a toolResult. Bedrock executes tools itself only in server-side tool use on the Responses API, which calls a Lambda or an AgentCore Gateway. - Every toolResult must echo the toolUseId from the request, or the turn will not stitch together.
- Structured output is its own feature, not a tool-schema workaround:
outputConfig.textFormaton Converse,strict: trueon a tool definition, or both together. An unsupported schema comes back as a 400 before any inference runs. - An inline function tool does not mean no Lambda ever; it means the harness pauses and returns the call to your application instead of the gateway invoking the target itself.
- A Lambda gateway target runs under the gateway’s own permissions, so it cannot act as the signed-in user. Three-legged OAuth on an MCP or OpenAPI target does that, or an inline function tool in your own code.
- Tool permissions live in IAM, and in the Cedar policies a gateway evaluates before each call. A prompt saying please do not delete is not a control.
- Agent memory is not the context window. Short-term is the session; long-term persists across sessions and needs a memory strategy attached.
- Flows has condition, loop, knowledge base, Lambda and inline code nodes, and no retry, wait, or approval node. Those are Step Functions.
- Step Functions calls AgentCore through an InvokeHarness task, request-response only: no
.sync, no task-token callback, and the task state stops at 15 minutes. - AgentCore is a framework-agnostic platform, not a model. You bring the agent, or declare one on the harness.
- Knowledge base grounding is retrieval, not fine-tuning. It changes what the agent can look up, not the model weights.
- Bedrock Agents is now Bedrock Agents Classic, closed since 30 July 2026 to accounts with no prior use, so its supervisor-and-collaborator routing is not a live option. The harness does agent-as-tool; richer routing means framework code on the runtime.
Say it in one line
- Model-decided control flow means an agent; deterministic control flow means Flows or Step Functions.
- Tool use: the model requests, your code executes, you send the toolResult back keyed by toolUseId.
- Structured output is a schema Bedrock enforces, through
outputConfig.textFormator a strict tool definition. - The harness orchestrates the loop from a declaration; the runtime runs a loop you wrote yourself. Same capabilities underneath, different owner of the cycle.
- A gateway target publishes an existing Lambda or REST API to the agent as an MCP tool; an inline function tool returns the call to your app instead.
- Memory strategies decide what long-term memory gets extracted; a memory resource with none attached keeps the session and stores nothing across sessions.
- Metrics arrive by default; spans need Transaction Search, tracing switched on, and ADOT in your agent code.
- Multi-agent on the harness is agent-as-tool: expose a specialist agent through the gateway and let another agent call it.
- Step Functions is durable orchestration: retries, parallel, timeouts, human-approval waits, broad integration, the model as one step.
- Least privilege lives on the tool’s IAM role and the gateway’s policies, never in the prompt.
- Pick the least powerful option that fits: plain call, then tool loop, then agent, and orchestrate the rest deterministically.