Name: Towards AI Legal Name: Towards AI, Inc. Description: Towards AI is the world's leading artificial intelligence (AI) and technology publication. Read by thought-leaders and decision-makers around the world. Phone Number: +1-650-246-9381 Email: pub@towardsai.net
228 Park Avenue South New York, NY 10003 United States
Website: Publisher: https://towardsai.net/#publisher Diversity Policy: https://towardsai.net/about Ethics Policy: https://towardsai.net/about Masthead: https://towardsai.net/about
Name: Towards AI Legal Name: Towards AI, Inc. Description: Towards AI is the world's leading artificial intelligence (AI) and technology publication. Founders: Roberto Iriondo, , Job Title: Co-founder and Advisor Works for: Towards AI, Inc. Follow Roberto: X, LinkedIn, GitHub, Google Scholar, Towards AI Profile, Medium, ML@CMU, FreeCodeCamp, Crunchbase, Bloomberg, Roberto Iriondo, Generative AI Lab, Generative AI Lab VeloxTrend Ultrarix Capital Partners Denis Piffaretti, Job Title: Co-founder Works for: Towards AI, Inc. Louie Peters, Job Title: Co-founder Works for: Towards AI, Inc. Louis-François Bouchard, Job Title: Co-founder Works for: Towards AI, Inc. Cover:
Towards AI Cover
Logo:
Towards AI Logo
Areas Served: Worldwide Alternate Name: Towards AI, Inc. Alternate Name: Towards AI Co. Alternate Name: towards ai Alternate Name: towardsai Alternate Name: towards.ai Alternate Name: tai Alternate Name: toward ai Alternate Name: toward.ai Alternate Name: Towards AI, Inc. Alternate Name: towardsai.net Alternate Name: pub.towardsai.net
5 stars – based on 497 reviews

Frequently Used, Contextual References

TODO: Remember to copy unique IDs whenever it needs used. i.e., URL: 304b2e42315e

Resources

Free: 6-day Agentic AI Engineering Email Guide.
Learnings from Towards AI's hands-on work with real clients.
Road to Bedrock AgentCore, From a Single API Call to a Production Agent
Latest   Machine Learning

Road to Bedrock AgentCore, From a Single API Call to a Production Agent

Last Updated on July 30, 2026 by Editorial Team

Author(s): Jahid

Originally published on Towards AI.

Road to Bedrock AgentCore, From a Single API Call to a Production Agent

Spend a week in AWS’s agent tooling and the same four names start to blur together. The Bedrock Converse API. Bedrock Agents. The Strands Agents SDK. Bedrock AgentCore. They turn up in the same blog posts and the same conference talks, usually side by side, as if they were four contestants for a single job. A newcomer is left with a fair question. Which one is the right one. The honest answer is that the question itself is wrong. These are not four rivals. They are four layers, each one solving a problem the layer below it left behind, and the fastest way to feel that is to stop reading about them and watch them do the same job.

So that is the whole plan. We build one tiny agent four times. Every version answers a single question, what is the weather in Melbourne right now, by calling a live weather service. The tool never changes. A single get_weather(city) function does the real work in all four builds. Only the wrapper around it changes. Holding the tool still is the trick that makes the comparison honest, because every difference you see is then a difference in the layer, never a difference in the example.

Road to Bedrock AgentCore, From a Single API Call to a Production Agent
Four layers, one job. The same agent grows from a raw API call on the left to a deployed production agent on the right.

TL;DR. Four AWS tools, one weather agent, built four times. The only thing that changes is who runs the loop, and where.

The chain, and why each step leads to the next.

  1. Converse API. You call the model directly and run the tool-use loop by hand. Total control, and total tedium. Writing it once is worth it, and then you never want to write it again.
  2. Bedrock Agents. So AWS runs the loop for you, as a managed service, with your tool as a Lambda. Less code, but the loop becomes a box you cannot step through, and a governed account adds an IAM trap.
  3. Strands SDK. So you take the loop back into your own code, run by the SDK rather than by hand. Control returns without the bookkeeping, plus model portability and multi-agent patterns.
  4. AgentCore. Your Strands agent is ready but has nowhere to run, so you deploy it, unchanged, onto AgentCore’s managed runtime, and pick up Gateway, Memory, Identity, and Observability around it.

The punchline. The agent’s logic never changes across all four. Only the wrapper does. So these are not four rivals to choose between. They are four answers to one question, who runs the loop and where, and you pick the trade that fits the project.

The one question that separates them

There is a single lens that snaps all four into focus, and it is worth holding from the first line. An agent, underneath the marketing, is a loop. The model reads the request, decides it needs a tool, the tool runs, the result comes back, and the model reads again and decides what to do next, around and around until it has an answer. Almost everything these four layers disagree about comes down to two questions. Who runs that loop, and where does it run.

The two things that actually change between the four stages. Everything else is detail.

Stage one, the Converse API, is you running the loop, in your own code. Stage two, Bedrock Agents, is AWS running it, inside a managed service you configure. Stage three, the Strands SDK, is a library running it, still inside your own process. And stage four, AgentCore, is that same library running it, now on infrastructure AWS operates for you. Once who runs the loop, and where is the frame, the whole comparison stops being about which layer is best and becomes about which trade you are willing to make.

One honest word before the detail. These stages are not a staircase you are meant to climb on every project. A small, well-understood agent may be genuinely better off in the managed console of stage two than in code you write and deploy yourself. We walk all four because seeing them solve one problem side by side makes the trade-offs concrete, not because stage four is the summit and the rest are base camps you abandon on the way up.

First, the ground floor, what Amazon Bedrock is

Before any of the four layers make sense, one term underneath all of them needs to be clear, because everything here sits on top of it. Amazon Bedrock is AWS’s managed service for calling large language models. A large language model is the kind of model that powers a chat assistant, and normally running one means wrangling GPUs, weights, and a serving stack. Bedrock takes all of that off your plate. You make one kind of API call, you name the model you want, OpenAI, Claude or Llama or Titan or others, and Bedrock hosts it and answers. You never touch the machinery.

You write to one API. Bedrock hosts the models and routes your call to whichever one you name

The specific way you talk to Bedrock in this post is the Converse API, its single unified way to hold a conversation with any hosted model. Converse matters for us because it understands tools. You can tell it which tools exist, and it can decide, mid-conversation, that it wants one. Hold that thought, because it is the seed the entire agent grows from. With Bedrock as the floor, we can start building.

Stage one, the raw Converse API

At the very bottom there is no agent abstraction at all. You call Converse directly, list your tools, and wait. When the model decides it wants a tool, it does not run anything. It stops and asks you to. You run the tool, hand the result back, and call again. Nothing is hidden from you here, which is exactly the same as saying nothing is done for you.

Stripped to the idea, the loop is this short.

messages = [{"role": "user", "content": [{"text": "What's the weather in Melbourne?"}]}]while True:
response = client.converse(modelId=MODEL_ID, messages=messages, toolConfig=tool_config)
output = response["output"]["message"]
messages.append(output)
if response["stopReason"] != "tool_use":
break # the model is done, print the answer
# the model asked for a tool, so we run it and hand the result back ourselves
for block in output["content"]:
if "toolUse" in block:
result = get_weather(block["toolUse"]["input"]["city"])
messages.append(tool_result_message(block["toolUse"]["toolUseId"], result))
The model asks for a tool, your code runs it and hands the result back, and your code decides when to loop again. Every arrow is something you write.

Look at everything that is now your job. Checking the stop reason to see whether the model is finished or wants a tool. Matching each tool call to its result. Appending messages in exactly the right shape. Deciding when to break. None of this is wrong to write by hand. It is genuinely worth doing once, because it is the reason the next three layers stop feeling like magic. This is the floor. It is also, very quickly, tedious, and that tedium is the whole reason stage two exists. The first thing most people want after writing this loop is to never write it again.

Stage two, Bedrock Agents hand the loop to AWS

Bedrock Agents is AWS’s managed answer to that exact wish. Instead of a Python while loop, you describe the tool and let AWS drive. You define an action group, which is two things. An OpenAPI schema, a standard way of describing what an operation takes and returns, so the model can work out when to call it. And a Lambda function, an AWS serverless function that runs your code without you managing a server, which actually does the work. From there, AWS owns the orchestration entirely, deciding when to call your tool, shaping the request, and stitching the final answer together.

Your entire contribution shrinks to the tool itself.

# the whole "agent", from AWS's point of view, is just this tool
def lambda_handler(event, context):
city = get_param(event, "city")
return wrap_for_bedrock(get_weather(city)) # same get_weather as every stage
The loop itself has left your code. AWS owns the orchestration, and the only code you write is the Lambda tool.

That is genuinely less code than stage one. The trade is that the orchestration is now a box you configure rather than a loop you can step through in a debugger. And in a governed AWS account, a second problem shows up that has nothing to do with agents at all. Permissions. It catches almost everyone once, so it is worth a proper look.

The permissions trap that is not about agents

Every Bedrock Agent needs an execution role, which is the identity the service assumes in order to act for you. If your account enforces a permissions boundary, as many company-managed accounts do, creating that role correctly matters more than anything about the agent itself. Two permissions get confused constantly, and the gap between them is the whole trap. iam:CreateRole lets you create the role. iam:PassRole lets you hand that role to a service at deploy time. Here is the cruel part. A role can be created without a hitch and still be completely useless, because CreateRole succeeding tells you nothing about whether PassRole will be allowed for it later. In a boundary-governed account, the two are often granted under separate, non-overlapping conditions.

A role a service will assume must be created under the service-role path, where both permissions apply. A role named for direct human use often lacks PassRole, which makes it a dead end for an execution role.

The practical rule is short. If any AWS service will assume the role, and essentially every execution role is assumed by a service, create it under the /service-role/ path, where both permissions travel together. Roles named for direct human use frequently live under a separate grant that is missing PassRole entirely, which is fine for their purpose and a dead end here. The one habit worth building is to confirm PassRole actually works before you deploy anything on top of the role, with a quick aws iam simulate-principal-policy check. The exact command is in the repo. It costs a few seconds and it saves you from finding out about a denial at the very end of a long deployment.

Write on Medium

Stage two bought us convenience and charged us visibility. We handed away the loop and, with it, the ability to step through it. The natural next wish is to get the loop back without going all the way back to the hand-written bookkeeping of stage one. That is precisely the gap Strands fills.

Meet Strands, the SDK that runs the loop for you

Strands is AWS’s open-source SDK for building agents, in Python and TypeScript. Think of it as the middle path between stages one and two. Stage one gave you total control and total tedium. Stage two gave you convenience and a black box. Strands gives you a loop that runs itself, inside your own process, where you can still see and shape it.

You define the tools. Strands drives the reason, act, observe loop, and the model behind it is swappable.

Two things about Strands matter for the rest of this post. It is model-agnostic, so Bedrock, Anthropic, OpenAI, and Gemini all sit behind the same Agent class, and swapping between them is a one-line change. And it supports multi-agent patterns, graphs and swarms and agent-to-agent hand-offs, that neither earlier stage gives you for free. It is the first layer that treats building an agent as ordinary application code rather than a managed configuration.

Stage three, Strands gives you the loop back

With the SDK understood, the code is almost anticlimactic.

from strands import Agent, tool
from strands.models import BedrockModel

@tool
def get_weather(city: str) -> dict:
"""Get the current weather for a named city."""
return _get_weather(city) # the same function, again

def build_agent() -> Agent:
return Agent(model=BedrockModel(), tools=[get_weather])

agent = build_agent()
print(agent("What's the weather in Melbourne right now?"))
The loop is back inside your process, but the Strands SDK runs it for you, sitting between your code and Bedrock.

That is the whole thing. Notice one deliberate choice. build_agent() is the single place the agent is constructed, and that is not a stylistic tic. It is a setup for the punchline of the entire post, because stage four is about to import that exact function and change nothing inside it. The agent that runs on your laptop right now is, quite literally, the agent that will run in production. All that is missing is somewhere production to run it. That somewhere is AgentCore.

Meet AgentCore, the production platform

Here is the mental shift that makes stage four click. AgentCore is not another way to write an agent. It is the place a finished agent goes to survive real traffic. Your Strands agent stays exactly as it is. AgentCore wraps the hard production concerns around it, the ones you would otherwise build and operate yourself, scaling, isolation between users, memory, tool access, identity, and monitoring.

Same agent code. AgentCore adds the production concerns around it, so you operate none of that infrastructure yourself.

It reached general availability in October 2025, and the important thing about its design is that it is a set of services, not a single monolith. You can adopt the runtime alone, or bring in memory when you need it, or add a gateway for tools later. We will meet the five that carry our weather example, then name the rest.

The services can be used together or one at a time. We take the five that matter for the weather agent in turn, then name the other four.

Stage four, deploying with AgentCore

Deployment is almost boringly small, which is the point.

from bedrock_agentcore.runtime import BedrockAgentCoreApp
from agent import build_agent # the exact function from stage three

app = BedrockAgentCoreApp()
agent = build_agent()

@app.entrypoint
def invoke(payload: dict) -> dict:
return
{"result": str(agent(payload.get("prompt", "")))}

if __name__ == "__main__":
app.run()
agentcore configure --entrypoint agent.py --name weather-agent
agentcore launch # builds a container in AWS CodeBuild and deploys it to the Runtime
agentcore invoke '{"prompt": "What is the weather in Melbourne right now?"}'

The logic of the agent was not touched. Only a thin deployment wrapper is new. That single fact is the whole argument for building on Strands before you ever need AgentCore. Now let us open up the five services doing the real work underneath that wrapper.

Runtime, where the agent actually runs

The Runtime is the serverless home for your agent. Serverless means you never provision or patch a server. You hand over the container and AWS runs it, scaling it up and down with traffic. Its defining feature is session isolation. Each user’s conversation runs in its own sealed environment, so one user’s data and state can never leak into another’s, and a long-running task for one person cannot trample another’s. The Runtime also handles genuinely long jobs, with execution windows measured in hours rather than the seconds a plain function allows, which matters the moment an agent has to think for a while.

Gateway, how a plain function becomes a shared tool

Gateway is the one genuinely new idea at stage four, and the least intuitive, so it earns the most care. On your laptop, a Strands tool is just a Python function the agent imports. Once the agent is deployed, that will not do. The tool has to live somewhere the runtime can reach and be callable over a standard protocol. Gateway is what makes that happen. It takes a plain Lambda or an OpenAPI service and exposes it as an MCP tool, where MCP, the Model Context Protocol, is the emerging standard for how agents discover and call tools. The agent stops importing a function and starts asking Gateway for a tool by name.

A bare Lambda is unreachable to a deployed agent. Gateway wraps that same Lambda and exposes it as an MCP tool the agent can call by name.

That indirection sounds like overhead until you see what it buys. The same tool can now be shared across many agents, secured in one central place, and swapped without redeploying the agents that use it. The tool stops being a private detail of one agent and becomes a governed, reusable capability.

Memory, so the agent stops forgetting

By default an agent forgets everything the instant a request ends. AgentCore Memory fixes that, and it comes in two flavours worth keeping straight. Short-term memory holds the current conversation, so a follow-up question knows what was just discussed, and it clears when the session ends. Long-term memory outlives the session entirely, a durable store that lets a brand-new conversation recall what was established days ago. The first makes an exchange feel coherent. The second makes an assistant feel like it knows you.

Short-term memory holds this conversation and clears with the session. Long-term memory is a durable store that carries context across sessions.

Identity, who is allowed to act

Once an agent can take actions in the world, a sharp question follows. On whose authority. AgentCore Identity answers it. It lets an agent act securely, either as itself or on behalf of a specific user, with tightly scoped access rather than a blanket set of keys. It integrates with OAuth-based services and stores credentials in a secure vault, so an agent that books a meeting or reads a record does so with exactly the permissions of the person it is acting for, and no more. In an enterprise, this is often the difference between a demo and something legal will let you ship.

Observability, so you can see inside the box

An agent you cannot watch is an agent you cannot trust in production, because when it does something strange, and eventually it will, you need to see why. AgentCore Observability gives you that window. It surfaces every step of an agent’s reasoning, every tool call, and every failure, as traces and metrics flowing into Amazon CloudWatch. It is built on OpenTelemetry, an open standard for this kind of tracing, so the data is not locked to one dashboard. This is what turns debugging from guesswork into reading a trail.

Those are the five that carry the weather agent. AgentCore ships four more for reach beyond it. Code Interpreter runs model-written code in a sandbox. Browser gives an agent a secure, cloud-hosted browser to use the web. Policy provides a governed, paved path for teams to build on approved tools. And Evaluations continuously scores agent quality against real traffic. You reach for those when the job calls for them, on the same platform.

What a request actually does at stage four

It is easy to lose count of the hops a single question takes once Gateway is in the picture, so here is that Melbourne question traced end to end after deployment.

The full round trip. The client asks, the agent decides it needs the tool, Gateway makes the Lambda callable, the Lambda calls the live service, and the answer travels back.

Read it once and the shape is reassuringly familiar. It is the same Lambda round trip from stage two, plus the Gateway hop that turns the Lambda into a callable tool, plus the Runtime layer now hosting the agent instead of your laptop. Nothing exotic. Just the same idea, wearing production clothes.

One tool, four wrappers

Step back and the whole journey collapses to a single image. Because all four stages call the identical get_weather(city) function, the only thing that ever changed was the shell around it.

The core function is identical at every stage. Stage one wraps it in a while loop, stage two in a Lambda, stage three in a decorator, and stage four does not wrap it again at all. It just deploys stage three.

That is the argument in one picture. The work of moving from a script to a production service was not rewriting the agent. It was changing what surrounds it. Which is exactly why the order these tools are usually presented in, as competitors, does everyone a disservice.

So which stage do you actually start with

There is no ranking, since best depends entirely on what you are trying to do this week. But the choice is not hard once you name the intent behind it.

Match the intent to the stage. Learning favours stage one, shipping fast favours stage two, control favours stage three, and real traffic favours stage four.

To learn how tool calling works at all, start at stage one and write the loop once. To ship a bounded, well-understood agent today, stage two’s managed orchestration is a real time saver. When you need multi-agent coordination, model portability, or simply want the loop back under your control, reach for stage three. And when you already have a working agent and need it to survive real traffic, stage four is the answer, where the move is to deploy the agent you have rather than rewrite it.

Closing thought

The four names at the top of this post were never four competing products. They are four answers to one question. Who runs the loop, and where. Stage one is you, in your own process. Stage two is AWS, in a managed console. Stage three is an SDK, still in your process. Stage four is that same SDK, running somewhere AWS operates for you. Once that is the frame, the anxiety of picking the right one dissolves. There is no right one. There is only the trade that fits the project in front of you, and now you can see exactly what each trade costs and buys.

Join thousands of data leaders on the AI newsletter. Join over 80,000 subscribers and keep up to date with the latest developments in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming a sponsor.

Published via Towards AI


Towards AI Academy

We Build Enterprise-Grade AI. We'll Teach You to Master It Too.

15 engineers. 100,000+ students. Towards AI Academy teaches what actually survives production.

Start free — no commitment:

6-Day Agentic AI Engineering Email Guide — one practical lesson per day

Agents Architecture Cheatsheet — 3 years of architecture decisions in 6 pages

Our courses:

AI Engineering Certification — 90+ lessons from project selection to deployed product. The most comprehensive practical LLM course out there.

Agent Engineering Course — Hands on with production agent architectures, memory, routing, and eval frameworks — built from real enterprise engagements.

AI for Work — Understand, evaluate, and apply AI for complex work tasks.

Note: Article content contains the views of the contributing authors and not Towards AI.