AI & assistant-friendly summary

This section provides structured content for AI assistants and search engines. You can cite or summarize it when referencing this page.

Summary

Amazon Bedrock Agents automate workflows by giving foundation models the ability to call tools (APIs, Lambda, databases). This guide covers building agents with tool definitions, testing in the console, handling errors, and scaling to production.

Key Facts

  • Amazon Bedrock Agents automate workflows by giving foundation models the ability to call tools (APIs, Lambda, databases)
  • Amazon Bedrock Agents automate workflows by giving foundation models the ability to call tools (APIs, Lambda, databases)

Entity Definitions

Amazon Bedrock
Amazon Bedrock is an AWS service discussed in this article.
Bedrock
Bedrock is an AWS service discussed in this article.
Lambda
Lambda is an AWS service discussed in this article.

How to Build an Amazon Bedrock Agent with Tool Use (2026)

Generative AI Palaniappan P 8 min read

Quick summary: Amazon Bedrock Agents automate workflows by giving foundation models the ability to call tools (APIs, Lambda, databases). This guide covers building agents with tool definitions, testing in the console, handling errors, and scaling to production.

Key Takeaways

  • Amazon Bedrock Agents automate workflows by giving foundation models the ability to call tools (APIs, Lambda, databases)
  • Amazon Bedrock Agents automate workflows by giving foundation models the ability to call tools (APIs, Lambda, databases)
Table of Contents

Amazon Bedrock Agents extend foundation models with the ability to call external tools — APIs, Lambda functions, databases, and more. Instead of returning a single response, agents reason over multiple steps, deciding which tools to call and how to use results to answer complex questions.

This guide covers building agents end-to-end: defining tools, creating the agent, testing in the console, and deploying at scale with error handling and monitoring.

Building Intelligent Agents on AWS? FactualMinds helps teams implement Bedrock agents with custom tool integrations, secure API access, and production monitoring. See our AWS Bedrock consulting services or talk to our team.

Step 1: Understand the Agent Architecture

Bedrock Agents operate in a continuous loop:

User Input

Agent (Claude or other model)
  ↓ (model decides to call a tool)
Tool (Lambda, API Gateway, Knowledge Base)
  ↓ (tool returns result)
Agent (model processes result, decides next step)
  ↓ (repeat until done)
Response to User

Key concepts:

  • Agent Executor: The runtime that manages the agentic loop. You invoke it once; it handles multiple tool calls internally.
  • Tool Definition: OpenAPI spec describing what the tool does, required inputs, outputs. Agent uses this to decide when to call the tool.
  • Tool Action: When the agent decides to call a tool, Bedrock invokes it and returns the result.
  • Tool Artifacts: Knowledge Bases or code interpreters that the agent can access directly.

Example flow:

User: “I need a report on my top 10 customers by revenue for Q1 2026.”

Agent reasoning:

  1. “I need to query the database for customer revenue data” → calls QueryCustomerRevenue tool
  2. Receives list of customers + revenue
  3. “I need to generate a formatted report” → calls GenerateReport tool
  4. Returns formatted report to user

Step 2: Define Your Tools

Tools are described using OpenAPI 3.0 specifications. Bedrock uses these specs to decide when to call tools and what parameters to pass.

Tool Types in Bedrock Agents

  1. AWS Lambda (most common) — synchronous functions for business logic
  2. AWS Step Functions (for long-running workflows) — async state machines
  3. API Gateway (for third-party APIs) — Stripe, SendGrid, external systems
  4. Knowledge Base (built-in) — semantic search over documents
  5. Code Interpreter (built-in) — run Python for calculations

Define a Lambda Tool

Create a Lambda function for customer lookup:

# lambda_handler.py
import json
import boto3

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Customers')

def lambda_handler(event, context):
    customer_id = event.get('customerId')
    response = table.get_item(Key={'id': customer_id})

    if 'Item' in response:
        return {
            'statusCode': 200,
            'body': json.dumps(response['Item'])
        }
    else:
        return {
            'statusCode': 404,
            'body': json.dumps({'error': 'Customer not found'})
        }

Define the tool in the agent using OpenAPI spec:

{
  "toolSpec": {
    "name": "GetCustomerInfo",
    "description": "Retrieve detailed information about a customer by ID",
    "inputSchema": {
      "json": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "string",
            "description": "The unique customer ID (e.g., CUST-12345)"
          }
        },
        "required": ["customerId"]
      }
    }
  },
  "toolInputType": "LAMBDA",
  "toolInputReference": "arn:aws:lambda:us-east-1:123456789012:function:GetCustomerInfo"
}

Key fields:

  • name: Tool identifier (used by agent in reasoning)
  • description: What the tool does (agent reads this to decide when to call it)
  • inputSchema: Parameters the tool accepts (JSON schema)
  • toolInputType: Type of tool (LAMBDA, API_GATEWAY, STEP_FUNCTIONS, KNOWLEDGE_BASE)
  • toolInputReference: ARN or URL of the actual tool

Define an API Gateway Tool

For third-party APIs:

{
  "toolSpec": {
    "name": "SendEmail",
    "description": "Send an email using SendGrid API",
    "inputSchema": {
      "json": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string",
            "description": "Recipient email address"
          },
          "subject": {
            "type": "string",
            "description": "Email subject"
          },
          "body": {
            "type": "string",
            "description": "Email body (HTML or plain text)"
          }
        },
        "required": ["to", "subject", "body"]
      }
    }
  },
  "toolInputType": "API_GATEWAY",
  "toolInputReference": "https://api.sendgrid.com/v3/mail/send",
  "toolAuthConfig": {
    "authorizationType": "BEARER_TOKEN",
    "apiKeyAuthConfig": {
      "apiKeyName": "Authorization",
      "secretsManagerArn": "arn:aws:secretsmanager:us-east-1:123456789012:secret:sendgrid-api-key"
    }
  }
}

Bedrock:

  1. Reads the SendGrid API spec
  2. When the agent decides to call SendEmail, Bedrock constructs the API request
  3. Retrieves the API key from Secrets Manager
  4. Calls SendGrid and returns the response

Step 3: Create an Agent in the AWS Console

Navigate to Amazon BedrockAgents:

  1. Click Create agent

  2. Agent name: customer-service-agent (lowercase, descriptive)

  3. Agent description: “Helps customers with account queries, orders, and support”

  4. Model: Select Claude 3.5 Sonnet (or preferred model)

  5. Agent role: Create or select an IAM role with permissions for:

    • lambda:InvokeFunction (for Lambda tools)
    • secretsmanager:GetSecretValue (for API authentication)
    • bedrock:InvokeModel (for Knowledge Base access)
  6. Instructions (system prompt for the agent):

You are a customer service representative for [Company]. Your job is:
1. Answer customer questions about their account, orders, and billing
2. Help resolve support issues by gathering information and escalating if needed
3. Always be polite and professional

Tools available:
- GetCustomerInfo: Retrieve customer account details
- GetOrderHistory: Retrieve past orders
- SendEmail: Send follow-up emails to customers

When a customer asks a question:
1. Use GetCustomerInfo to load their account
2. Use GetOrderHistory if they ask about orders
3. Answer their question based on the data
4. If the issue can't be resolved, offer to escalate

Never make assumptions. Always retrieve data before answering.
  1. Click Create

Step 4: Add Tools to the Agent

In the agent detail page, go to Tools:

  1. Click Add tool
  2. Choose tool type (Lambda, API Gateway, Knowledge Base, etc.)
  3. For Lambda: Select function from dropdown
  4. For API: Paste OpenAPI spec URL or raw JSON
  5. Click Add tool

Repeat for all tools (customer lookup, order history, email, etc.).

Step 5: Test the Agent in the Playground

Bedrock ConsoleAgents[Your Agent]Test:

  1. Enter a test prompt:
I need information about customer CUST-54321
  1. Watch the agent reasoning:
Thinking... I should call GetCustomerInfo with customerId=CUST-54321

Tool: GetCustomerInfo
Input: {"customerId": "CUST-54321"}
Result: {"id": "CUST-54321", "name": "Alice", "email": "alice@example.com", "plan": "Pro"}

I have the customer information. Let me provide a response...
  1. Agent responds:
I found the customer Alice (CUST-54321). They're on the Pro plan and can be reached at alice@example.com. Is there anything specific I can help with?
  1. Test error handling:
I need information about a non-existent customer

Verify the agent:

  • Calls the tool even when the customer doesn’t exist
  • Handles the error gracefully (instead of crashing)
  • Informs the user that the customer wasn’t found

Step 6: Integrate the Agent into Your Application

Use the Bedrock Agent Runtime API to invoke agents from code:

import boto3
import json

bedrock_agent_runtime = boto3.client('bedrock-agent-runtime', region_name='us-east-1')

agent_id = 'your-agent-id'
agent_alias_id = 'LFSSTCWOOY'  # Default alias

response = bedrock_agent_runtime.invoke_agent(
    agentId=agent_id,
    agentAliasId=agent_alias_id,
    sessionId='session-123',  # Unique per conversation
    inputText='I need information about customer CUST-54321'
)

# Stream results (agents return responses as events)
result_text = ''
for event in response.get('completion', []):
    if 'chunk' in event:
        chunk_data = event['chunk'].get('bytes', b'').decode('utf-8')
        result_text += chunk_data
        print(chunk_data, end='', flush=True)

print(f"\nFinal response: {result_text}")

Handling Agent Errors

Agents can fail if tools error out or the model gets stuck. Handle gracefully:

try:
    response = bedrock_agent_runtime.invoke_agent(
        agentId=agent_id,
        agentAliasId=agent_alias_id,
        sessionId=session_id,
        inputText=user_input
    )

    result = ''.join([
        event['chunk']['bytes'].decode('utf-8')
        for event in response.get('completion', [])
        if 'chunk' in event
    ])

    return {'response': result, 'status': 'success'}

except bedrock_agent_runtime.exceptions.AccessDeniedException as e:
    return {'error': 'Permission denied. Check agent permissions.', 'status': 'error'}

except bedrock_agent_runtime.exceptions.ValidationException as e:
    return {'error': 'Invalid agent configuration.', 'status': 'error'}

except Exception as e:
    return {'error': f'Agent error: {str(e)}', 'status': 'error'}

Step 7: Monitor and Optimize

CloudWatch Metrics

Enable Agent Execution Metrics:

bedrock:agent:InvocationCount
bedrock:agent:ToolUseCount
bedrock:agent:ToolErrorCount
bedrock:agent:ExecutionTimeMs

Set up alarms:

  • If ToolErrorCount spikes → review tool implementations
  • If ExecutionTimeMs > 10s → agent is looping; refine tool definitions or instructions

Optimize Tool Use

  1. Reduce tool calls: Refine agent instructions to avoid unnecessary calls

    • Instead of “call GetCustomerInfo and GetOrderHistory separately”, say “retrieve complete customer profile (info + orders)”
  2. Cache results: Store frequently-accessed data (customer profiles, inventory) in the agent’s session context to avoid repeated tool calls

  3. Prioritize tools: Order tools in the agent’s tool list by likelihood of use (most-used first)

Step 8: Production Patterns

Pattern 1: Multi-Tool Reasoning

For complex workflows, give agents multiple tools and let them chain operations:

Agent Tools:
- QueryDatabase (customer data)
- GenerateReport (formatting)
- SendEmail (delivery)

User: "Send my quarterly revenue report to alice@example.com"

Agent:
1. Calls QueryDatabase → retrieves Q1-Q3 revenue data
2. Calls GenerateReport → formats as PDF
3. Calls SendEmail → sends to alice@example.com

Pattern 2: Graceful Degradation

If a tool fails, the agent should fall back to a simpler response:

# Tool definition with fallback
{
  "toolSpec": {
    "name": "GetInventory",
    "description": "Check product inventory (may fail; agent should handle gracefully)"
  },
  # If tool fails 3x, agent responds: "I couldn't check inventory, but here's what I know..."
}

Pattern 3: Audit Logging

Log all agent invocations for compliance and debugging:

import logging

logger = logging.getLogger('agents')

def invoke_agent_with_logging(user_id, input_text):
    logger.info(
        'Agent invoked',
        extra={
            'user_id': user_id,
            'input': input_text,
            'timestamp': datetime.now().isoformat()
        }
    )

    response = bedrock_agent_runtime.invoke_agent(
        agentId=agent_id,
        sessionId=user_id,
        inputText=input_text
    )

    logger.info(
        'Agent completed',
        extra={
            'user_id': user_id,
            'tool_calls': count_tool_calls(response),
            'status': 'success'
        }
    )

    return response

Common Mistakes to Avoid

  1. Tool definitions too vague

    • ❌ Description: “Get data”
    • ✓ Description: “Retrieve customer billing history for a given customer ID, including invoices and payment status”
  2. Not handling tool errors

    • Agent gets stuck if a tool returns an error
    • Design tools to return empty results instead of errors
  3. Too many tools

    • Agents get confused with >10 tools
    • Start with 3-5 core tools, add more only if needed
  4. Insufficient context in instructions

    • Don’t just say “use tools to help the customer”
    • Specify which tools for what scenarios
  5. Not testing error paths

    • Test what happens when a tool fails, returns empty, or returns unexpected data
    • Agent should degrade gracefully

Next Steps

  1. Define your first 3 tools (start simple)
  2. Create an agent in the console and test with sample inputs
  3. Integrate into a test application with error handling
  4. Monitor tool usage and refine agent instructions
  5. Deploy to production with audit logging
  6. Talk to FactualMinds if you need help designing agent workflows for complex business processes
PP
Palaniappan P

AWS Cloud Architect & AI Expert

AWS-certified cloud architect and AI expert with deep expertise in cloud migrations, cost optimization, and generative AI on AWS.

AWS ArchitectureCloud MigrationGenAI on AWSCost OptimizationDevOps

Ready to discuss your AWS strategy?

Our certified architects can help you implement these solutions.

Recommended Reading

Explore All Articles »

How to Build a RAG Pipeline with Amazon Bedrock Knowledge Bases

Amazon Bedrock Knowledge Bases automate the RAG (Retrieval-Augmented Generation) pipeline — semantic search, chunking, embedding, and context injection into Claude or other foundation models. This guide covers setup, data ingestion, cost optimization, and production patterns.

How to Set Up Amazon Bedrock Guardrails for Production

Amazon Bedrock Guardrails protect foundation models from harmful outputs — filtering on prompt injection, jailbreaks, toxicity, and PII. This guide covers setup, testing, cost optimization, and production safety patterns for GenAI applications.

How to Run SageMaker Training Jobs Cost-Efficiently

Amazon SageMaker automates ML training, but instance costs add up fast. This guide covers spot instances, instance selection, distributed training, and production patterns to reduce SageMaker costs by 50-70%.