How to Build an Amazon Bedrock Agent with Tool Use (2026)
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 UserKey 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:
- “I need to query the database for customer revenue data” → calls
QueryCustomerRevenuetool - Receives list of customers + revenue
- “I need to generate a formatted report” → calls
GenerateReporttool - 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
- AWS Lambda (most common) — synchronous functions for business logic
- AWS Step Functions (for long-running workflows) — async state machines
- API Gateway (for third-party APIs) — Stripe, SendGrid, external systems
- Knowledge Base (built-in) — semantic search over documents
- 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:
- Reads the SendGrid API spec
- When the agent decides to call SendEmail, Bedrock constructs the API request
- Retrieves the API key from Secrets Manager
- Calls SendGrid and returns the response
Step 3: Create an Agent in the AWS Console
Navigate to Amazon Bedrock → Agents:
Click Create agent
Agent name:
customer-service-agent(lowercase, descriptive)Agent description: “Helps customers with account queries, orders, and support”
Model: Select Claude 3.5 Sonnet (or preferred model)
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)
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.- Click Create
Step 4: Add Tools to the Agent
In the agent detail page, go to Tools:
- Click Add tool
- Choose tool type (Lambda, API Gateway, Knowledge Base, etc.)
- For Lambda: Select function from dropdown
- For API: Paste OpenAPI spec URL or raw JSON
- Click Add tool
Repeat for all tools (customer lookup, order history, email, etc.).
Step 5: Test the Agent in the Playground
Bedrock Console → Agents → [Your Agent] → Test:
- Enter a test prompt:
I need information about customer CUST-54321- 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...- 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?- Test error handling:
I need information about a non-existent customerVerify 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:ExecutionTimeMsSet up alarms:
- If
ToolErrorCountspikes → review tool implementations - If
ExecutionTimeMs> 10s → agent is looping; refine tool definitions or instructions
Optimize Tool Use
Reduce tool calls: Refine agent instructions to avoid unnecessary calls
- Instead of “call GetCustomerInfo and GetOrderHistory separately”, say “retrieve complete customer profile (info + orders)”
Cache results: Store frequently-accessed data (customer profiles, inventory) in the agent’s session context to avoid repeated tool calls
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.comPattern 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 responseCommon Mistakes to Avoid
Tool definitions too vague
- ❌ Description: “Get data”
- ✓ Description: “Retrieve customer billing history for a given customer ID, including invoices and payment status”
Not handling tool errors
- Agent gets stuck if a tool returns an error
- Design tools to return empty results instead of errors
Too many tools
- Agents get confused with >10 tools
- Start with 3-5 core tools, add more only if needed
Insufficient context in instructions
- Don’t just say “use tools to help the customer”
- Specify which tools for what scenarios
Not testing error paths
- Test what happens when a tool fails, returns empty, or returns unexpected data
- Agent should degrade gracefully
Next Steps
- Define your first 3 tools (start simple)
- Create an agent in the console and test with sample inputs
- Integrate into a test application with error handling
- Monitor tool usage and refine agent instructions
- Deploy to production with audit logging
- Talk to FactualMinds if you need help designing agent workflows for complex business processes
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.
