How to Build Amazon Bedrock AI Agents: 12 Steps [2026]

Amazon Bedrock crossed a quiet but important threshold this year: the service now routes access to more than 100 foundation models from upwards of 18 providers, all through a single API, according to AWS documentation updated in August 2026. But the bigger shift isn’t the model count. It’s that Bedrock Agents — the layer that lets a foundation model call Lambda functions, query your data, and complete multi-step tasks on its own — has moved from “interesting demo” to something teams are actually shipping, a trajectory AWS underscored in April 2026 by launching Managed Agents in Amazon Bedrock as a limited preview, pushed further in September 2026 when AWS opened a preview of Bedrock Managed Agents powered by OpenAI models — with no separate agent fee during the preview — and reinforced again that same month when AWS published general-availability pricing for the new AWS Agent Registry, a discovery service for cataloging and searching agents across an organization. AWS’s own tutorial for building a Bedrock agent was last updated August 18, 2026, and the getting-started guide two days later, which tells you how fast this corner of AWS is moving right now.

This tutorial walks through building a working Amazon Bedrock agent from a blank AWS account: IAM setup, model access requests, a Lambda-backed action group, an OpenAPI schema, a knowledge base for retrieval-augmented generation, and a deployed alias you can call from Python. By the end you’ll have an agent that answers questions using your own data and takes real actions through Lambda, plus the troubleshooting steps for when something inevitably throws a permissions error at 2 a.m.

Google · Preferred Sources

Don't miss new tech stories on Google

Add Tech Insider once in the Google app and our stories appear in your news suggestions.

Add Now

What Amazon Bedrock Agents Actually Do

Amazon Bedrock Agents is a fully managed service that enables you to build and configure autonomous agents in your applications, according to AWS Prescriptive Guidance. In plain terms: instead of a chatbot that only generates text, an agent breaks a user request into steps, decides which tools it needs, calls those tools (usually AWS Lambda functions or third-party APIs), reads the results, and keeps going until the task is done.

AWS puts it directly on the product page: “Amazon Bedrock Agents uses the reasoning of foundation models (FMs), APIs, and data to break down user requests, gathers relevant information, and efficiently completes tasks—freeing teams to focus on high-value work,” according to AWS’s Bedrock Agents product page. That’s the pitch. The practical version is closer to: you write a Lambda function, you describe it to the agent with a JSON or OpenAPI schema, and the model decides when to invoke it based on the conversation.

Three building blocks make up almost every real Bedrock agent project:

  • Action groups — Lambda functions the agent can call, described via an OpenAPI schema or function-detail JSON
  • Knowledge bases — vectorized document stores (usually backed by Amazon OpenSearch Serverless or Amazon S3 Vectors) the agent queries for retrieval-augmented generation
  • Guardrails — content filters and denied-topic rules applied before a response reaches the user

This guide builds all three, plus a production alias and the IAM scaffolding AWS requires before any of it runs.

Prerequisites: What You Need Before You Start

Get these in place before Step 1. Skipping the IAM step is the single most common reason first-time Bedrock agent builds fail partway through.

RequirementMinimum Version / DetailWhy You Need It
AWS accountActive, billing enabledBedrock and Lambda both bill on usage; no free-tier bypass for model inference
IAM role or userNon-root, with Bedrock + Lambda permissionsAWS documentation explicitly instructs against using the root user for Bedrock work
Python3.12+Current AWS beginner tutorials specify 3.12+ as the baseline for boto3 and the Bedrock SDK
boto3Latest via pipPython SDK used for every Bedrock API call in this guide
AWS CLIv2Configuring credentials and testing Lambda deploys from the terminal
Foundation model accessRequested and approved in consoleBedrock requires an explicit access request per model family before invocation works
AWS Regionus-east-1, us-west-2, or another Bedrock Agents regionBedrock Agents is supported in 16 regions as of the July 2026 AWS documentation update, not all commercial regions
Text editor / IDEVS Code or similarEditing Lambda code and OpenAPI schema files

Estimated total time: 100 minutes, assuming model access approval comes through quickly (it’s usually near-instant for Amazon’s own Nova models and can take longer for some third-party models that require a use-case form).

Step 1: Sign In and Create an IAM Role for Bedrock

Sign in to the AWS Management Console with an IAM user or role that has administrator access, or at minimum the ability to create IAM policies. Do not do any of this as the account root user — AWS’s current getting-started documentation is explicit that Bedrock work should run under a scoped IAM identity, not the root account.

Create a new IAM role named something like BedrockAgentExecutionRole. Attach a trust policy that lets Bedrock assume it, plus permissions for Lambda invocation, S3 access (for knowledge base documents), and CloudWatch Logs.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Service": "bedrock.amazonaws.com" },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": { "aws:SourceAccount": "YOUR_ACCOUNT_ID" }
      }
    }
  ]
}

Save this as trust-policy.json and create the role via the AWS CLI:

aws iam create-role \
  --role-name BedrockAgentExecutionRole \
  --assume-role-policy-document file://trust-policy.json

aws iam attach-role-policy \
  --role-name BedrockAgentExecutionRole \
  --policy-arn arn:aws:iam::aws:policy/AmazonBedrockFullAccess

AmazonBedrockFullAccess is fine for this tutorial. For production, scope it down to the specific actions your agent needs — see the pitfalls section below for why broad policies cause problems later. For background on IAM role design, AWS’s own IAM roles guide is the canonical reference.

Step 2: Request Access to Foundation Models

Bedrock doesn’t grant model access by default, even on a fresh account. Open the Bedrock console, go to Model access in the left navigation, and request access to the models you plan to use. For this tutorial, request access to an Amazon Nova model (Nova Pro or Nova Lite) and, if you have it enabled, an Anthropic Claude model — the agent examples below work with either.

Amazon’s own models (Nova family) typically approve within a minute or two. Third-party models sometimes require a short use-case description before access is granted. This step blocks everything downstream, so don’t skip checking the approval status before moving on — a pending request looks identical to a working one until you try to invoke the model and get an AccessDeniedException.

Step 3: Install and Configure boto3

Set up a Python virtual environment and install the AWS SDK:

python3 -m venv bedrock-agent-env
source bedrock-agent-env/bin/activate
pip install boto3 botocore

aws configure
# AWS Access Key ID: [your key]
# AWS Secret Access Key: [your secret]
# Default region name: us-east-1
# Default output format: json

Verify the connection with a quick model list call:

import boto3

bedrock = boto3.client("bedrock", region_name="us-east-1")
response = bedrock.list_foundation_models()

for model in response["modelSummaries"][:10]:
    print(model["modelId"], "-", model["modelLifecycle"]["status"])

If this prints a list of model IDs without errors, your credentials and region are correctly configured. If it throws UnrecognizedClientException, your access key or region is wrong — double-check the output of aws configure list.

Step 4: Send Your First Inference Request

Before building an agent, confirm plain model inference works. This isolates SDK and permissions problems from agent-specific issues later.

import boto3
import json

runtime = boto3.client("bedrock-runtime", region_name="us-east-1")

response = runtime.converse(
    modelId="amazon.nova-pro-v1:0",
    messages=[
        {
            "role": "user",
            "content": [{"text": "In one sentence, what is Amazon Bedrock?"}]
        }
    ],
    inferenceConfig={"maxTokens": 200, "temperature": 0.3}
)

print(response["output"]["message"]["content"][0]["text"])

The converse API is the current recommended entry point for Bedrock inference because it works identically across model providers — you don’t need a different request format for Nova versus Claude versus Llama. That consistency matters once you’re routing agent tool calls through multiple models.

Step 5: Build the Lambda Function for Your Agent’s Tool

AWS’s own agent tutorial builds a Lambda function that returns the current date and time when invoked by the agent, as a minimal starting example — as the documentation puts it: “Create a Lambda function — Build a Python function that returns the current date and time when invoked by your agent,” according to the AWS Bedrock agent tutorial. This tutorial extends that pattern into something closer to a real use case: an order-lookup tool for a customer support agent.

import json

def lambda_handler(event, context):
    action_group = event.get("actionGroup")
    api_path = event.get("apiPath")
    parameters = {p["name"]: p["value"] for p in event.get("parameters", [])}

    if api_path == "/orderStatus":
        order_id = parameters.get("orderId", "unknown")
        # Replace with a real DynamoDB or database lookup
        mock_orders = {
            "ORD-1001": {"status": "shipped", "eta": "2026-08-25"},
            "ORD-1002": {"status": "processing", "eta": "2026-08-29"}
        }
        result = mock_orders.get(order_id, {"status": "not found", "eta": None})
        body = json.dumps(result)
    else:
        body = json.dumps({"error": "unknown apiPath"})

    return {
        "messageVersion": "1.0",
        "response": {
            "actionGroup": action_group,
            "apiPath": api_path,
            "httpMethod": event.get("httpMethod"),
            "httpStatusCode": 200,
            "responseBody": {"application/json": {"body": body}}
        }
    }

Package and deploy it:

zip function.zip lambda_function.py

aws lambda create-function \
  --function-name bedrock-order-status \
  --runtime python3.12 \
  --role arn:aws:iam::YOUR_ACCOUNT_ID:role/BedrockAgentExecutionRole \
  --handler lambda_function.lambda_handler \
  --zip-file fileb://function.zip \
  --timeout 15

You also need to grant Bedrock permission to invoke this specific Lambda function — this is a separate resource-based policy, not the IAM role from Step 1:

aws lambda add-permission \
  --function-name bedrock-order-status \
  --statement-id bedrock-invoke \
  --action lambda:InvokeFunction \
  --principal bedrock.amazonaws.com \
  --source-arn arn:aws:bedrock:us-east-1:YOUR_ACCOUNT_ID:agent/*

Forgetting this second permission grant is the number-one cause of agents that “reason correctly” but return empty tool responses — the model picks the right function, calls it, and Lambda silently rejects the invocation because Bedrock was never authorized to call it.

Step 6: Write the OpenAPI Schema for Your Action Group

The agent needs a structured description of what your Lambda function does, what parameters it takes, and when to call it. Bedrock accepts this as an OpenAPI 3.0 schema, uploaded as JSON or YAML to S3.

{
  "openapi": "3.0.0",
  "info": {
    "title": "Order Status API",
    "version": "1.0.0",
    "description": "Look up the shipping status of a customer order"
  },
  "paths": {
    "/orderStatus": {
      "get": {
        "summary": "Get order status by order ID",
        "operationId": "getOrderStatus",
        "parameters": [
          {
            "name": "orderId",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "description": "The order ID, e.g. ORD-1001"
          }
        ],
        "responses": {
          "200": {
            "description": "Order status returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "string" },
                    "eta": { "type": "string" }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Upload it to an S3 bucket the Bedrock role can read:

aws s3 mb s3://your-bedrock-agent-schemas
aws s3 cp order-status-schema.json s3://your-bedrock-agent-schemas/

The operationId and description fields matter more than they look. The agent’s reasoning model reads this schema as natural language to decide when to invoke the tool, so vague descriptions (“does stuff with orders”) produce agents that either never call the tool or call it for the wrong queries.

Step 7: Create the Bedrock Agent

Now assemble the agent itself. This can be done in the console under Bedrock → Agents → Create Agent, or programmatically with boto3, which is easier to reproduce and version-control:

import boto3

agent_client = boto3.client("bedrock-agent", region_name="us-east-1")

response = agent_client.create_agent(
    agentName="customer-support-agent",
    foundationModel="amazon.nova-pro-v1:0",
    instruction=(
        "You are a customer support assistant. Use the order status tool "
        "to look up shipping information when a customer provides an order ID. "
        "Be concise and always confirm the order ID back to the customer."
    ),
    agentResourceRoleArn="arn:aws:iam::YOUR_ACCOUNT_ID:role/BedrockAgentExecutionRole",
    idleSessionTTLInSeconds=600
)

agent_id = response["agent"]["agentId"]
print("Agent created:", agent_id)

The instruction field is effectively your system prompt — it’s what steers the agent’s reasoning across every turn, so treat it with the same care you’d give a production prompt template, not a placeholder.

Step 8: Attach the Action Group to the Agent

Connect the Lambda function and OpenAPI schema from Steps 5 and 6 to the agent you just created:

agent_client.create_agent_action_group(
    agentId=agent_id,
    agentVersion="DRAFT",
    actionGroupName="order-status-tool",
    actionGroupExecutor={
        "lambda": "arn:aws:lambda:us-east-1:YOUR_ACCOUNT_ID:function:bedrock-order-status"
    },
    apiSchema={
        "s3": {
            "s3BucketName": "your-bedrock-agent-schemas",
            "s3ObjectKey": "order-status-schema.json"
        }
    },
    actionGroupState="ENABLED"
)

agent_client.prepare_agent(agentId=agent_id)

The prepare_agent call compiles your instruction, action groups, and any attached knowledge bases into a testable DRAFT version. You must re-run prepare_agent after every change to the agent’s configuration — the console will visibly nag you about this with a “not prepared” banner if you forget.

Step 9: Add a Knowledge Base for RAG

To automate tasks in an application using AI agents, AWS documentation notes that the first optional step is to “create a knowledge base to store your private data,” according to the Amazon Bedrock user guide. A knowledge base lets your agent answer questions grounded in your own documents instead of relying purely on the foundation model’s training data.

In the console, go to Bedrock → Knowledge bases → Create. Point it at an S3 bucket containing your source documents (PDFs, text files, or HTML), choose an embeddings model (Amazon Titan Text Embeddings or Cohere Embed both work), and let Bedrock create the underlying vector store — typically Amazon OpenSearch Serverless unless you’ve configured a different vector database.

knowledge_base = agent_client.create_knowledge_base(
    name="support-docs-kb",
    roleArn="arn:aws:iam::YOUR_ACCOUNT_ID:role/BedrockAgentExecutionRole",
    knowledgeBaseConfiguration={
        "type": "VECTOR",
        "vectorKnowledgeBaseConfiguration": {
            "embeddingModelArn": "arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v2:0"
        }
    },
    storageConfiguration={
        "type": "OPENSEARCH_SERVERLESS",
        "opensearchServerlessConfiguration": {
            "collectionArn": "arn:aws:aoss:us-east-1:YOUR_ACCOUNT_ID:collection/YOUR_COLLECTION_ID",
            "vectorIndexName": "support-docs-index",
            "fieldMapping": {
                "vectorField": "embedding",
                "textField": "text",
                "metadataField": "metadata"
            }
        }
    }
)

kb_id = knowledge_base["knowledgeBase"]["knowledgeBaseId"]

agent_client.associate_agent_knowledge_base(
    agentId=agent_id,
    agentVersion="DRAFT",
    knowledgeBaseId=kb_id,
    description="Product documentation and return policy reference",
    knowledgeBaseState="ENABLED"
)

After associating the knowledge base, trigger an ingestion job so Bedrock chunks, embeds, and indexes your source documents before the agent can query them. This can take anywhere from a couple of minutes to well over an hour depending on document volume — don’t test the agent’s RAG behavior until the ingestion job status shows COMPLETE.

Step 10: Test the Agent in the Console

AWS’s tutorial lists testing as the fourth core step: “Test your agent in the Amazon Bedrock console or through API calls to the TSTALIASID,” per the official agent tutorial documentation. Every newly prepared DRAFT agent gets an automatic test alias called TSTALIASID, which you can use immediately without creating a formal alias.

Open the agent in the console, click Test, and try a conversation:

You: “What’s the status of order ORD-1001?”
Agent: “Order ORD-1001 has shipped and is expected to arrive by August 25, 2026. Would you like tracking details?”

The console’s trace panel shows exactly what happened behind that response: the model’s reasoning step, the action group it called, the raw Lambda output, and the final response synthesis. Use this trace constantly during development — it’s the fastest way to see whether a wrong answer came from bad reasoning, a schema mismatch, or a Lambda bug.

Step 11: Invoke the Agent Programmatically

Once console testing looks right, call the agent from application code using the bedrock-agent-runtime client:

import boto3
import uuid

runtime_agent = boto3.client("bedrock-agent-runtime", region_name="us-east-1")

session_id = str(uuid.uuid4())

response = runtime_agent.invoke_agent(
    agentId=agent_id,
    agentAliasId="TSTALIASID",
    sessionId=session_id,
    inputText="What's the status of order ORD-1002?"
)

for event in response["completion"]:
    if "chunk" in event:
        print(event["chunk"]["bytes"].decode("utf-8"), end="")

Note the streaming response format — invoke_agent returns an event stream, not a single JSON blob, so you iterate over chunks as they arrive. This matters for latency-sensitive applications: you can start rendering partial output to a user before the agent finishes its full reasoning trace.

Step 12: Deploy a Production Alias

TSTALIASID always points to the current DRAFT version, which changes every time you call prepare_agent. That’s fine for development but dangerous in production, where you want a stable, versioned target. Create a formal alias that pins to a specific agent version:

version_response = agent_client.create_agent_version(agentId=agent_id)
agent_version = version_response["agentVersion"]["version"]

alias_response = agent_client.create_agent_alias(
    agentId=agent_id,
    agentAliasName="production",
    routingConfiguration=[{"agentVersion": agent_version}]
)

production_alias_id = alias_response["agentAlias"]["agentAliasId"]
print("Production alias:", production_alias_id)

Point your application at production_alias_id instead of TSTALIASID. When you’re ready to ship a new version, create a new agent version and update the alias’s routing configuration — this gives you a clean rollback path if the new version misbehaves, since the old version stays intact and callable.

Amazon Bedrock Agent Pricing: What This Actually Costs

Bedrock agents don’t have a separate line-item price — you pay standard Bedrock token pricing for every model call the agent makes, including its internal reasoning steps, plus Lambda invocation costs (typically negligible) and any knowledge base storage or query costs. Because an agent often makes multiple model calls per user turn (initial reasoning, tool selection, response synthesis), real-world cost per conversation runs higher than a single chat completion — though AWS said in August 2026 that swapping in Bedrock’s distilled models can cut that overhead sharply, running up to 500% faster and costing up to 75% less than their full-size counterparts for reasoning and tool-selection steps that don’t need the largest model available.

ModelInput (per 1M tokens)Output (per 1M tokens)Typical Use in Agents
Amazon Nova Lite$0.06$0.24High-volume, low-complexity tool routing
Amazon Nova Pro$0.80$3.20General-purpose agent reasoning
Claude 3.5 Haiku$0.80$4.00Fast tool-calling with stronger instruction following
Claude 3.7 Sonnet$3.00$15.00Complex multi-step reasoning, higher-stakes tasks

On-demand list pricing for the us-east-1 region, current as of August 2026, according to AWS’s official Bedrock pricing page. Batch inference (asynchronous, non-real-time) typically runs at roughly half these rates for models that support it, which is worth considering for agents that process backlogs rather than live conversations.

Amazon Bedrock AgentCore: Governance for Production Agents

Once an agent moves past a proof of concept, AWS’s answer for governance is Amazon Bedrock AgentCore — a separate, consumption-based service layered on top of standard Bedrock Agents. An AWS Machine Learning blog post published August 19, 2026 lays out a four-stage maturity model for hardening agent tool access: Connect, Control, Catalog, and Harden, walking teams from basic tool wiring toward fully governed, policy-enforced tool gateways. The “Control” stage now has a concrete price tag: AWS’s AgentCore Policy component, published in August 2026, charges $0.000025 per authorization request — with the first 100 temporal policies exempt from extra authorization charges — plus $0.13 per 1,000 input tokens processed for policy evaluation, putting a real per-request cost on the fine-grained access checks the maturity model recommends.

AgentCore is billed entirely separately from foundation model tokens — it’s a distinct set of meters covering runtime compute, gateway invocations, and memory storage: Runtime microVMs and Browser Tool compute list at $0.0895 per vCPU-hour, while the newly GA’d AWS Agent Registry — AWS’s name for the AgentCore Registry once it left preview — charges $0.400 per 1,000 records after the first 5,000 free each month, $0.020 per 1,000 search invocations after the first 1,000,000 free, and $0.004 per 1,000 combined get/list invocations after the first 2,000,000 free per month, under the general-availability pricing AWS announced in September 2026. AgentCore itself reached general availability across nine AWS regions in August 2026, according to AWS Docs, later expanded to include Bangkok, Malaysia, Milan, and Spain.

AgentCore MeterPrice
Runtime microVM — CPU$0.0895 per vCPU-hour
Runtime microVM — Memory$0.00945 per GB-hour
Gateway — API invocations$0.005 per 1,000 calls
Gateway — search invocations$0.025 per 1,000 calls
Memory — short-term events$0.25 per 1,000 events
Memory — long-term storage (built-in)$0.75 per 1,000 records/month
Identity — token/API key requests$0.010 per 1,000 requests

For a single internal tool with light usage, standard Bedrock Agents without AgentCore is usually sufficient. AgentCore earns its cost once you’re running many agents against many tools and need centralized catalogs, access control, and audit trails — the governance problem it’s built to solve.

Amazon Bedrock Agents vs Other AI Agent Frameworks

Bedrock Agents isn’t the only way to build a tool-calling AI agent, and the comparison got more interesting in April 2026, when AWS announced three new Bedrock offerings in one go — native access to OpenAI’s models, OpenAI’s Codex, and Managed Agents — narrowing the gap with frameworks that previously required leaving AWS entirely to use OpenAI’s own tooling. The short version still holds, though: Bedrock Agents wins on AWS-native integration and managed infrastructure, and gives up some flexibility compared to open-source orchestration frameworks that run anywhere.

PlatformHosting ModelBest ForTradeoff
Amazon Bedrock AgentsFully managed (AWS)Teams already on AWS wanting IAM-integrated, Lambda-backed agentsTied to AWS infrastructure and Bedrock’s supported model list
OpenAI Assistants / Responses APIFully managed (OpenAI)Fastest path to a working agent with OpenAI’s own modelsLocked to OpenAI models; less control over the underlying orchestration loop
LangChain / LangGraphSelf-hosted, model-agnosticComplex multi-agent graphs, maximum control over orchestration logicYou own the infrastructure, retries, and state management yourself
Claude Agent SDKSelf-hosted, Anthropic modelsTeams standardizing on Claude who want a lighter-weight SDK than raw API callsNarrower tool ecosystem than Bedrock’s native AWS service integrations

The practical decision usually comes down to where your data and existing infrastructure already live. If your order database, document store, and authentication already run on AWS, Bedrock Agents removes a lot of plumbing — IAM handles authorization, Lambda handles compute, S3 and OpenSearch Serverless handle the knowledge base, and you’re not standing up a separate orchestration server. If you’re multi-cloud or need fine-grained control over the agent’s reasoning loop (custom retry logic, non-standard tool formats, streaming behavior Bedrock doesn’t expose), a self-hosted framework like LangGraph gives you that control at the cost of managing it yourself. Teams already using Anthropic’s Claude Agent SDK for other projects may also find it faster to extend that pattern than to stand up a parallel Bedrock agent, unless AWS-native tool integration is the deciding factor.

Monitoring Bedrock Agents with CloudWatch

An agent that works in your Step 10 console test can still fail silently in production if a Lambda function starts timing out under real load or a knowledge base ingestion job breaks after a document format change. Bedrock Agents integrates with Amazon CloudWatch for both metrics and full invocation logging — enable this before you route real traffic through the production alias, not after something breaks.

Enable invocation logging so every agent trace — model reasoning steps, tool calls, and final responses — lands in a CloudWatch Logs group you can query:

import boto3

bedrock = boto3.client("bedrock", region_name="us-east-1")

bedrock.put_model_invocation_logging_configuration(
    loggingConfig={
        "cloudWatchConfig": {
            "logGroupName": "/aws/bedrock/agent-invocations",
            "roleArn": "arn:aws:iam::YOUR_ACCOUNT_ID:role/BedrockAgentExecutionRole"
        },
        "textDataDeliveryEnabled": True,
        "embeddingDataDeliveryEnabled": False
    }
)

Once logging is on, four CloudWatch metrics are worth alarming on for any production agent: Invocations (traffic volume), InvocationLatency (end-to-end response time, which includes every tool call the agent makes), InvocationClientErrors (bad requests from your application, usually a malformed session or missing parameter), and InvocationServerErrors (Bedrock-side failures, including Lambda invocation failures bubbling up through the action group). A sudden spike in InvocationServerErrors immediately after a Lambda code deploy is the fastest signal that your tool function broke something the agent depends on.

For cost visibility specifically, CloudWatch doesn’t break down spend by agent — you’ll need AWS Cost Explorer filtered by the Bedrock service and, if you’re tagging resources, by agent name, to see which of your agents is actually driving the token bill. This becomes important quickly once you have more than two or three agents running, since a runaway reasoning loop on one agent can otherwise hide inside an aggregate Bedrock cost line.

Common Pitfalls When Building Bedrock Agents

These are the mistakes that show up most often in first-time Bedrock agent builds, based on the failure modes AWS’s own documentation and tutorials repeatedly call out.

  • Forgetting the Lambda resource-based policy. The IAM role from Step 1 controls what the agent can do; it does not grant Bedrock permission to invoke a specific Lambda function. That’s a separate lambda:AddPermission call, and skipping it produces agents that reason correctly but never get real tool output.
  • Vague OpenAPI descriptions. The model reads your schema’s description fields as natural language to decide when to call a tool. “Handles order stuff” produces unreliable tool selection; “Look up order status by order ID” does not.
  • Using the root account. Beyond being a general security anti-pattern, several Bedrock console features assume an IAM identity and behave inconsistently under root.
  • Testing against TSTALIASID in production. This alias always tracks the latest DRAFT, so a teammate’s in-progress edit can silently change your production agent’s behavior. Always deploy a versioned alias before going live.
  • Skipping the ingestion job status check. Associating a knowledge base doesn’t mean it’s queryable yet. Documents must finish an ingestion job (chunking, embedding, indexing) before RAG answers will reflect them.
  • Overly broad IAM policies. AmazonBedrockFullAccess is fine for a tutorial; in production it’s an unnecessary blast radius. Scope permissions to the specific model IDs and actions your agent actually uses.
  • Not accounting for multi-call token costs. A single user turn can trigger several model invocations (reasoning, tool selection, response generation). Cost estimates based on “one prompt, one response” pricing will undercount real spend.
  • Region mismatches. Bedrock Agents is available in a specific subset of AWS regions — 16 as of the current AWS documentation — not every commercial region. Deploying resources across mismatched regions produces confusing “resource not found” errors.

Troubleshooting Amazon Bedrock Agent Errors

Here are the errors you’re most likely to hit, and what actually fixes them.

  • AccessDeniedException on model invocation. Model access hasn’t been approved yet, or was requested in a different region than you’re calling from. Check Model Access status in the exact region your code targets.
  • Agent returns generic answers, ignoring the Lambda tool. Usually a schema description problem — the model doesn’t recognize when the tool is relevant. Rewrite the OpenAPI description and operationId to be explicit about the exact use case.
  • “Agent not prepared” banner in the console. You changed instructions, action groups, or a knowledge base association without re-running prepare_agent. Every configuration change requires a new prepare call before testing.
  • Lambda invocation times out. Default Lambda timeout is 3 seconds; increase it (this tutorial uses 15) if your function does a real database lookup rather than returning mock data instantly.
  • Knowledge base returns empty or irrelevant results. Check the ingestion job status first — a job stuck in IN_PROGRESS or that failed silently means zero documents are actually indexed yet.
  • ValidationException on create_agent_action_group. Almost always an OpenAPI schema syntax error. Validate the JSON independently before uploading to S3 — Bedrock’s error messages for malformed schemas are not always specific about the line at fault.
  • Agent alias invocation returns a stale response. You updated the DRAFT and prepared it, but your alias still routes to an older agent version. Confirm the alias’s routingConfiguration points at the version you expect.
  • Streaming response cuts off mid-sentence. Client-side timeout is shorter than the agent’s full reasoning-and-response cycle, especially for multi-step tool calls. Increase the client read timeout for the bedrock-agent-runtime client.
  • Cross-region S3 access denied for the OpenAPI schema. The S3 bucket holding your schema must be in the same region as the agent, or you need an explicit cross-region bucket policy — Bedrock doesn’t assume cross-region access by default.

Advanced Tips: Multi-Agent Collaboration and Guardrails

Once a single agent is working reliably, two extensions are worth exploring. First, Bedrock supports multi-agent collaboration, where a supervisor agent delegates subtasks to specialized sub-agents — useful when one agent handles order lookups, another handles returns policy questions, and a supervisor routes between them rather than cramming every capability into one instruction set and action group list.

Second, attach a Guardrails configuration before shipping anything customer-facing. Guardrails let you define denied topics, content filters, and PII redaction rules that apply to both input and output, independent of what the underlying foundation model would otherwise generate. This is the layer AWS recommends for compliance-sensitive use cases — it’s a policy enforcement point that sits outside the model’s own judgment, which matters when you can’t fully trust prompt-based instructions alone to prevent an off-topic or unsafe response.

For teams building beyond a single tutorial-scale agent, the strands-agents and strands-agents-tools Python packages — referenced in AWS’s current beginner-to-agent tutorial content — provide a higher-level orchestration layer on top of raw boto3 calls, worth evaluating once you’re managing several agents with overlapping tool sets.

Complete Working Project: End-to-End Support Agent

Putting every step together, here’s the full setup script that provisions the Lambda function, agent, action group, and production alias in one pass. Run this after completing Steps 1–2 (IAM role and model access already in place).

import boto3
import time

REGION = "us-east-1"
ACCOUNT_ID = "YOUR_ACCOUNT_ID"
ROLE_ARN = f"arn:aws:iam::{ACCOUNT_ID}:role/BedrockAgentExecutionRole"
LAMBDA_ARN = f"arn:aws:lambda:{REGION}:{ACCOUNT_ID}:function:bedrock-order-status"
SCHEMA_BUCKET = "your-bedrock-agent-schemas"
SCHEMA_KEY = "order-status-schema.json"

agent_client = boto3.client("bedrock-agent", region_name=REGION)
runtime_agent = boto3.client("bedrock-agent-runtime", region_name=REGION)

# 1. Create the agent
agent = agent_client.create_agent(
    agentName="customer-support-agent",
    foundationModel="amazon.nova-pro-v1:0",
    instruction=(
        "You are a customer support assistant for an e-commerce store. "
        "Use the order status tool to answer shipping questions. "
        "Always confirm the order ID and keep responses under three sentences."
    ),
    agentResourceRoleArn=ROLE_ARN,
    idleSessionTTLInSeconds=600
)
agent_id = agent["agent"]["agentId"]
print(f"Created agent {agent_id}")

# 2. Wait for agent to reach NOT_PREPARED (ready for config)
while agent_client.get_agent(agentId=agent_id)["agent"]["agentStatus"] != "NOT_PREPARED":
    time.sleep(2)

# 3. Attach the action group
agent_client.create_agent_action_group(
    agentId=agent_id,
    agentVersion="DRAFT",
    actionGroupName="order-status-tool",
    actionGroupExecutor={"lambda": LAMBDA_ARN},
    apiSchema={"s3": {"s3BucketName": SCHEMA_BUCKET, "s3ObjectKey": SCHEMA_KEY}},
    actionGroupState="ENABLED"
)
print("Action group attached")

# 4. Prepare the agent
agent_client.prepare_agent(agentId=agent_id)
while agent_client.get_agent(agentId=agent_id)["agent"]["agentStatus"] != "PREPARED":
    time.sleep(2)
print("Agent prepared")

# 5. Create a versioned production alias
version = agent_client.create_agent_version(agentId=agent_id)["agentVersion"]["version"]
alias = agent_client.create_agent_alias(
    agentId=agent_id,
    agentAliasName="production",
    routingConfiguration=[{"agentVersion": version}]
)
alias_id = alias["agentAlias"]["agentAliasId"]
print(f"Production alias {alias_id} live on version {version}")

# 6. Smoke test
response = runtime_agent.invoke_agent(
    agentId=agent_id,
    agentAliasId=alias_id,
    sessionId="smoke-test-001",
    inputText="What's the status of order ORD-1001?"
)
output = ""
for event in response["completion"]:
    if "chunk" in event:
        output += event["chunk"]["bytes"].decode("utf-8")
print("Agent response:", output)

Expected output from the smoke test, given the mock data in the Step 5 Lambda function:

Created agent AGENT7XK2P9
Action group attached
Agent prepared
Production alias ALIAS4NM8Q live on version 1
Agent response: Order ORD-1001 has shipped and is expected to arrive by August 25, 2026.

From here, swap the mock mock_orders dictionary in the Lambda function for a real DynamoDB or RDS lookup, add the knowledge base from Step 9 for policy and FAQ questions, and attach a Guardrails configuration before pointing any real customer traffic at the production alias.

Frequently Asked Questions

What’s the difference between Amazon Bedrock and Amazon Bedrock Agents?

Bedrock is the base platform providing API access to more than 100 foundation models from roughly 18 providers — a catalog AWS said was serving more than 225,000 active customers, including over 80% of the Fortune 100, as of September 2026, the same month it added million-token context windows for the GPT-5.6 Sol, Terra, and Luna models available on the platform. Bedrock Agents is a specific capability within Bedrock that adds reasoning, tool-calling (via Lambda action groups), and knowledge-base retrieval on top of a chosen foundation model, turning a single-turn chat model into a multi-step task executor.

Do I need Amazon Bedrock AgentCore to build an agent?

No, but the runway is shortening: AWS renamed the standard Bedrock Agents service covered in this tutorial to Amazon Bedrock Agents Classic in its June 2026 availability updates, and has said Agents Classic stopped accepting new customers after July 30, 2026 — the same date its model catalog was frozen, with any new foundation models arriving in AgentCore instead. Existing users can keep building on Agents Classic after that cutoff, and as of October 2026 it still carries no separate orchestration charge: customers pay only for model inference and whatever connected resources their agent touches. AgentCore, by contrast, is an additional, separately billed governance and orchestration layer aimed at teams running many agents against many tools who need centralized access control and auditing, and its billable surface has kept expanding — AWS rolled out general-availability pricing for the AWS Agent Registry in September 2026 and for AgentCore Policy’s per-request authorization checks in August 2026 — reinforcing that this is the path AWS is steering new projects toward as Agents Classic winds down.

Which foundation model should I use for agent reasoning?

Amazon Nova Lite is the cheapest option and works for simple, well-defined tool routing. Nova Pro and Claude 3.5 Haiku sit in the middle for general-purpose agents. Claude 3.7 Sonnet costs more per token but handles more complex, multi-step reasoning chains more reliably — worth it for agents making higher-stakes decisions.

Can I use Bedrock Agents outside AWS Lambda for tool execution?

Yes. Action groups can also call external REST APIs directly via a return-of-control pattern, where the agent returns the parameters it wants to send and your application handles the actual API call rather than routing through Lambda. This is useful when integrating with systems outside AWS.

How many AWS regions support Bedrock Agents?

As of AWS’s documentation update in late July 2026, Bedrock Agents is supported in 16 regions, including us-east-1, us-east-2, us-west-2, eu-west-1, eu-central-1, ap-southeast-1, ap-northeast-1, and others. Not every AWS commercial region has Bedrock Agents available, so check the current supported-regions list before architecting a multi-region deployment.

Why does my agent call the wrong tool or no tool at all?

This is almost always an OpenAPI schema clarity problem. The foundation model decides which action group to invoke based on the description and operationId fields in your schema. Vague or overlapping descriptions across multiple tools confuse the routing decision — be as specific as possible about what each tool does and when it should be used.

Is Amazon Bedrock Agents free to try?

There’s no separate charge for the Agents feature itself — you pay standard on-demand token pricing for the foundation model calls your agent makes, plus Lambda and any knowledge base storage costs. For light testing with a model like Nova Lite at $0.06 per million input tokens, development-stage costs are typically a few dollars at most.

How do I version-control my agent configuration?

Treat the boto3 provisioning script from the complete working project section as your source of truth, stored in your own version control alongside the Lambda function code and OpenAPI schema. Bedrock’s create_agent_version gives you immutable snapshots on the AWS side, but your application-level infrastructure-as-code should be the canonical definition you deploy from.

Marcus Chen

Marcus Chen

Gaming & Consumer Tech Editor

Marcus Chen is a senior editor at Tech Insider, where he leads coverage of the US online gaming market, including sweepstakes and social casinos, alongside consumer technology. He evaluates operators on their published terms, licensing and RNG certifications, stated redemption policies, and corroborating independent reporting, and writes plainly about what the evidence supports. Tech Insider does not run first-party money tests and does not gamble with reader funds. Marcus has reported on the technology and online-gaming industries for more than a decade.

View all articles