Amazon Bedrock
Amazon Bedrock gives an agent access to foundation models from several providers through one AWS API. Strands connects to Bedrock through the BedrockModel class, which is the default model provider when you create an Agent without specifying one.
This page covers running an agent on Bedrock: configuring AWS credentials, selecting a model, and setting the options BedrockModel exposes. BedrockModel supports:
- Text generation
- Multimodal input (images, documents, and more)
- Tool calling
- Guardrails
- Prompt caching for system prompts, tools, and messages
Getting Started
Section titled “Getting Started”Prerequisites
Section titled “Prerequisites”- AWS Account: You need an AWS account with access to Amazon Bedrock
- AWS Credentials: Configure AWS credentials with appropriate permissions
Required IAM Permissions
Section titled “Required IAM Permissions”To use Amazon Bedrock with Strands, your IAM user or role needs the following permissions:
bedrock:InvokeModelWithResponseStream(for streaming mode)bedrock:InvokeModel(for non-streaming mode)
Here’s a sample IAM policy that grants the necessary permissions:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "bedrock:InvokeModelWithResponseStream", "bedrock:InvokeModel" ], "Resource": "*" } ]}For production, scope the Resource down to specific model ARNs.
Setting Up AWS Credentials
Section titled “Setting Up AWS Credentials”Strands uses boto3 (the AWS SDK for Python) to make calls to Amazon Bedrock. Boto3 has its own credential resolution system that determines which credentials to use when making requests to AWS.
For development environments, configure credentials using one of these methods:
Option 1: AWS CLI
aws configureOption 2: Environment Variables
export AWS_ACCESS_KEY_ID=your_access_keyexport AWS_SECRET_ACCESS_KEY=your_secret_keyexport AWS_SESSION_TOKEN=your_session_token # If using temporary credentialsexport AWS_REGION="us-west-2" # Used if a custom Boto3 Session is not providedOption 3: Custom Boto3 Session
You can configure a custom boto3 Session and pass it to the BedrockModel:
import boto3from strands.models import BedrockModel
# Create a custom boto3 sessionsession = boto3.Session( aws_access_key_id='your_access_key', aws_secret_access_key='your_secret_key', aws_session_token='your_session_token', # If using temporary credentials region_name='us-west-2', profile_name='your-profile' # Optional: Use a specific profile)
# Create a Bedrock model with the custom sessionbedrock_model = BedrockModel( model_id="global.anthropic.claude-sonnet-5", boto_session=session)For complete details on credential configuration and resolution, see the boto3 credentials documentation.
Option 4: aws login
aws login provides browser-based authentication for temporary credentials. Requires AWS CLI version 2.32.0 or later.
aws loginTo use aws login with enhanced performance, install botocore with CRT support:
pip install botocore[crt]See the Login for AWS local development using console credentials documentation for more details.
The TypeScript SDK uses the AWS SDK for JavaScript v3 to make calls to Amazon Bedrock. The SDK has its own credential resolution system that determines which credentials to use when making requests to AWS.
For development environments, configure credentials using one of these methods:
Option 1: AWS CLI
aws configureOption 2: Environment Variables
export AWS_ACCESS_KEY_ID=your_access_keyexport AWS_SECRET_ACCESS_KEY=your_secret_keyexport AWS_SESSION_TOKEN=your_session_token # If using temporary credentialsexport AWS_REGION="us-west-2"Option 3: Custom Credentials
import { BedrockModel } from '@strands-agents/sdk/models/bedrock'
// AWS credentials are configured through the clientConfig parameter// See AWS SDK for JavaScript documentation for all credential options:// https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html
const bedrockModel = new BedrockModel({ modelId: 'global.anthropic.claude-sonnet-5', region: 'us-west-2', clientConfig: { credentials: { accessKeyId: 'your_access_key', secretAccessKey: 'your_secret_key', sessionToken: 'your_session_token', // If using temporary credentials }, },})For complete details on credential configuration, see the AWS SDK for JavaScript documentation.
Basic Usage
Section titled “Basic Usage”A basic Agent uses the BedrockModel provider with Claude Sonnet 4.6 by default:
from strands import Agent
agent = Agent()
response = agent("Tell me about Amazon Bedrock.")You can specify which Bedrock model to use by passing in the model ID string directly to the Agent constructor:
from strands import Agent
# Create an agent with a specific model by passing the model ID stringagent = Agent(model="global.anthropic.claude-sonnet-5")
response = agent("Tell me about Amazon Bedrock.")A basic Agent uses the BedrockModel provider with Claude Sonnet 4.6 by default:
import { Agent } from '@strands-agents/sdk'
const agent = new Agent()
const response = await agent.invoke('Tell me about Amazon Bedrock.')You can specify which Bedrock model to use by passing in the model ID string directly to the Agent constructor:
import { Agent } from '@strands-agents/sdk'
// Create an agent using the modelconst agent = new Agent({ model: 'global.anthropic.claude-sonnet-5' })
const response = await agent.invoke('Tell me about Amazon Bedrock.')Note: See Bedrock troubleshooting if you encounter any issues.
Custom Configuration
Section titled “Custom Configuration”For more control over model configuration, you can create an instance of the BedrockModel class:
from strands import Agentfrom strands.models import BedrockModel
# Create a Bedrock model instancebedrock_model = BedrockModel( model_id="us.amazon.nova-premier-v1:0", temperature=0.3, top_p=0.8,)
# Create an agent using the BedrockModel instanceagent = Agent(model=bedrock_model)
# Use the agentresponse = agent("Tell me about Amazon Bedrock.")For more control over model configuration, you can create an instance of the BedrockModel class:
// Create a Bedrock model instanceconst bedrockModel = new BedrockModel({ modelId: 'us.amazon.nova-premier-v1:0', temperature: 0.3, topP: 0.8,})
// Create an agent using the BedrockModel instanceconst agent = new Agent({ model: bedrockModel })
// Use the agentconst response = await agent.invoke('Tell me about Amazon Bedrock.')Configuration Options
Section titled “Configuration Options”The BedrockModel supports various configuration parameters. For a complete list of available options, see the BedrockModel API reference.
Common configuration parameters include:
model_id- The Bedrock model identifiertemperature- Controls randomness (higher = more random)max_tokens- Maximum number of tokens to generatestreaming- Enable/disable streaming modeguardrail_id- ID of the guardrail to applycache_prompt- Cache point type for the system prompt (deprecated, usecache_config)cache_config- Configuration for prompt caching (e.g.,CacheConfig(strategy="auto"))cache_tools- Enable tool caching (deprecated, usecache_configwithCacheConfig(tools_ttl=...))strict_tools- Enforce structured output on tool definitions. Bedrock’s strict mode restricts which JSON Schema features tool input schemas may use (for example,oneOfis unsupported), so a schema that uses an unsupported feature fails at request time. See the Bedrock structured output documentationboto_session- Custom boto3 session for AWS credentialsapi_key- Amazon Bedrock API key for bearer token authentication; requests use the key instead of SigV4 signingadditional_request_fields- Additional model-specific parameters
The BedrockModel supports various configuration parameters. For a complete list of available options, see the BedrockModelOptions API reference.
Common configuration parameters include:
modelId- The Bedrock model identifiertemperature- Controls randomness (higher = more random)maxTokens- Maximum number of tokens to generatestream- Enable/disable streaming modecacheConfig- Enable prompt caching with{ strategy: 'auto' }, or{ messagesTTL: false }to cache the tool definitions and system prompt onlyregion- AWS region to useapiKey- Bedrock API key for bearer token authentication (alternative to SigV4 signing)clientConfig- AWS SDK client configurationadditionalArgs- Additional model-specific parameters
Example with Configuration
Section titled “Example with Configuration”from strands import Agentfrom strands.models import BedrockModelfrom botocore.config import Config as BotocoreConfig
# Create a boto client config with custom settingsboto_config = BotocoreConfig( retries={"max_attempts": 3, "mode": "standard"}, connect_timeout=5, read_timeout=60)
# Create a configured Bedrock modelbedrock_model = BedrockModel( model_id="global.anthropic.claude-sonnet-5", region_name="us-east-1", # Specify a different region than the default temperature=0.3, stop_sequences=["###", "END"], boto_client_config=boto_config,)
# Create an agent with the configured modelagent = Agent(model=bedrock_model)
# Use the agentresponse = agent("Write a short story about an AI assistant.")// Create a configured Bedrock modelconst bedrockModel = new BedrockModel({ modelId: 'global.anthropic.claude-sonnet-5', region: 'us-east-1', // Specify a different region than the default temperature: 0.3, stopSequences: ['###', 'END'], clientConfig: { retryMode: 'standard', maxAttempts: 3, },})
// Create an agent with the configured modelconst agent = new Agent({ model: bedrockModel })
// Use the agentconst response = await agent.invoke('Write a short story about an AI assistant.')TypeScript Request Timeout
Section titled “TypeScript Request Timeout”The TypeScript SDK applies a default requestTimeout of 120000 ms (120 seconds) when constructing the Bedrock Runtime client, since the underlying AWS SDK defaults to 0 (disabled), which lets a stuck connection hang. The timeout counts stream inactivity, so a long-thinking model or a large tool-call payload that keeps the stream quiet past the limit fails with Stream timed out because of no activity. Raise it with the requestTimeout option:
import { BedrockModel } from '@strands-agents/sdk/models/bedrock'
const bedrockModel = new BedrockModel({ modelId: 'global.anthropic.claude-sonnet-5', requestTimeout: 600_000, // 10 minutes})The same value can also be set through clientConfig.requestHandler alongside other handler options; when both are given, the top-level requestTimeout wins:
const bedrockModel = new BedrockModel({ modelId: 'global.anthropic.claude-sonnet-5', clientConfig: { requestHandler: { requestTimeout: 600_000, connectionTimeout: 5_000 }, },})Passing a fully-constructed handler instance (rather than an options bag) bypasses both; the handler’s own timeouts apply unchanged and a requestTimeout option is ignored with a warning.
Advanced Features
Section titled “Advanced Features”Streaming vs Non-Streaming Mode
Section titled “Streaming vs Non-Streaming Mode”Some Bedrock models only support non-streaming tool use. Set the streaming configuration to false to use those models. Both modes give your agent the same event structure and behavior, since Strands converts non-streaming responses to the streaming format internally.
# Streaming model (default)streaming_model = BedrockModel( model_id="global.anthropic.claude-sonnet-5", streaming=True, # This is the default)
# Non-streaming modelnon_streaming_model = BedrockModel( model_id="us.meta.llama3-2-90b-instruct-v1:0", streaming=False, # Disable streaming)// Streaming model (default)const streamingModel = new BedrockModel({ modelId: 'global.anthropic.claude-sonnet-5', stream: true, // This is the default})
// Non-streaming modelconst nonStreamingModel = new BedrockModel({ modelId: 'us.meta.llama3-2-90b-instruct-v1:0', stream: false, // Disable streaming})See the Amazon Bedrock documentation for Supported models and model features to learn about the streaming support for different models.
Multimodal Support
Section titled “Multimodal Support”Some Bedrock models accept multimodal input such as documents, images, and audio. Pass the content blocks directly to the agent:
from strands import Agentfrom strands.models import BedrockModel
# Create a Bedrock model that supports multimodal inputsbedrock_model = BedrockModel( model_id="global.anthropic.claude-sonnet-5")agent = Agent(model=bedrock_model)
# Send the multimodal message to the agentresponse = agent( [ { "document": { "format": "txt", "name": "example", "source": { "bytes": b"Once upon a time..." } } }, { "text": "Tell me about the document." } ])const bedrockModel = new BedrockModel({ modelId: 'global.anthropic.claude-sonnet-5',})
const agent = new Agent({ model: bedrockModel })
const documentBytes = Buffer.from('Once upon a time...')
// Send multimodal content directly to invokeconst response = await agent.invoke([ new DocumentBlock({ format: 'txt', name: 'example', source: { bytes: documentBytes }, }), 'Tell me about the document.',])For the full list of input types, see the API Reference.
S3 Location Support
Section titled “S3 Location Support”As an alternative to providing media content as bytes, Amazon Bedrock supports referencing documents, images, videos, and audio stored in Amazon S3 directly. This is useful when working with large files or when your content is already stored in S3.
from strands import Agentfrom strands.models import BedrockModel
agent = Agent(model=BedrockModel())
response = agent( [ { "document": { "format": "pdf", "name": "report.pdf", "source": { "location": { "type": "s3", "uri": "s3://my-bucket/documents/report.pdf", "bucketOwner": "123456789012" # Optional: for cross-account access } } } }, { "text": "Summarize this document." } ])const agent = new Agent({ model: new BedrockModel() })
const response = await agent.invoke([ new DocumentBlock({ format: 'pdf', name: 'report.pdf', source: { location: { type: 's3', uri: 's3://my-bucket/documents/report.pdf', bucketOwner: '123456789012', // Optional: for cross-account access }, }, }), 'Summarize this document.',])Guardrails
Section titled “Guardrails”Configure a guardrail on your BedrockModel to keep model output within your policies:
from strands import Agentfrom strands.models import BedrockModel
# Using guardrails with BedrockModelbedrock_model = BedrockModel( model_id="global.anthropic.claude-sonnet-5", guardrail_id="your-guardrail-id", guardrail_version="DRAFT", guardrail_trace="enabled", # Options: "enabled", "disabled", "enabled_full" guardrail_stream_processing_mode="sync", # Options: "sync", "async" guardrail_redact_input=True, # Default: True guardrail_redact_input_message="Blocked Input!", # Default: [User input redacted.] guardrail_redact_output=False, # Default: False guardrail_redact_output_message="Blocked Output!", # Default: [Assistant output redacted.] guardrail_latest_message=True, # Only evaluate the latest user message (default: False))
guardrail_agent = Agent(model=bedrock_model)
response = guardrail_agent("Can you tell me about the Strands Harness SDK?")When a guardrail is triggered:
- Input redaction (enabled by default): If a guardrail policy is triggered, the input is redacted
- Output redaction (disabled by default): If a guardrail policy is triggered, the output is redacted
- Custom redaction messages can be specified for both input and output redactions
Configure a guardrail on your BedrockModel to keep model output within your policies:
// Using guardrails with BedrockModelconst bedrockModel = new BedrockModel({ modelId: 'global.anthropic.claude-sonnet-5', guardrailConfig: { guardrailIdentifier: 'your-guardrail-id', guardrailVersion: 'DRAFT', trace: 'enabled', // Options: 'enabled', 'disabled', 'enabled_full' streamProcessingMode: 'sync', // Options: 'sync', 'async' redaction: { input: true, // Default: true inputMessage: '[User input redacted.]', // Custom redaction message output: false, // Default: false outputMessage: '[Assistant output redacted.]', // Custom redaction message }, guardLatestUserMessage: true, // Only evaluate the latest user message (default: false) },})
const guardrailAgent = new Agent({ model: bedrockModel })
const response = await guardrailAgent.invoke('Can you tell me about the Strands Harness SDK?')When a guardrail is triggered:
- Input redaction (enabled by default): If a guardrail policy is triggered, the input is redacted
- Output redaction (disabled by default): If a guardrail policy is triggered, the output is redacted
- Custom redaction messages can be specified for both input and output redactions
Caching
Section titled “Caching”Strands caches system prompts, tools, and messages on Bedrock to reduce token usage and latency. See Bedrock prompt caching for automatic and manual cache point placement, per-model token minimums, and cache metrics.
Updating Configuration at Runtime
Section titled “Updating Configuration at Runtime”You can update the model configuration during runtime:
# Create the model with initial configurationbedrock_model = BedrockModel( model_id="global.anthropic.claude-sonnet-5", temperature=0.7)
# Update configuration laterbedrock_model.update_config( temperature=0.3,)// Create the model with initial configurationconst bedrockModel = new BedrockModel({ modelId: 'global.anthropic.claude-sonnet-5', temperature: 0.7,})
// Update configuration laterbedrockModel.updateConfig({ temperature: 0.3,})This is especially useful for tools that need to update the model’s configuration:
@tooldef update_model_id(model_id: str, agent: Agent) -> str: """ Update the model id of the agent
Args: model_id: Bedrock model id to use. """ print(f"Updating model_id to {model_id}") agent.model.update_config(model_id=model_id) return f"Model updated to {model_id}"
@tooldef update_temperature(temperature: float, agent: Agent) -> str: """ Update the temperature of the agent
Args: temperature: Temperature value for the model to use. """ print(f"Updating Temperature to {temperature}") agent.model.update_config(temperature=temperature) return f"Temperature updated to {temperature}"import { tool } from '@strands-agents/sdk'import { z } from 'zod'
// Define a tool that updates model configurationconst updateTemperature = tool({ name: 'update_temperature', description: 'Update the temperature of the agent', inputSchema: z.object({ temperature: z.number().describe('Temperature value for the model to use'), }), callback: async ({ temperature }, context) => { if (context.agent?.model && 'updateConfig' in context.agent.model) { context.agent.model.updateConfig({ temperature }) return `Temperature updated to ${temperature}` } return 'Failed to update temperature' },})
const agent = new Agent({ model: new BedrockModel({ modelId: 'global.anthropic.claude-sonnet-5' }), tools: [updateTemperature],})Reasoning Support
Section titled “Reasoning Support”Amazon Bedrock models can provide detailed reasoning steps when generating responses. For detailed information about supported models and reasoning token configuration, see the Amazon Bedrock documentation on inference reasoning.
Enable reasoning on your BedrockModel:
from strands import Agentfrom strands.models import BedrockModel
# Create a Bedrock model with reasoning configurationbedrock_model = BedrockModel( model_id="global.anthropic.claude-sonnet-5", additional_request_fields={ "thinking": { "type": "enabled", "budget_tokens": 4096 # Minimum of 1,024 } })
# Create an agent with the reasoning-enabled modelagent = Agent(model=bedrock_model)
# Ask a question that requires reasoningresponse = agent("If a train travels at 120 km/h and needs to cover 450 km, how long will the journey take?")Enable reasoning on your BedrockModel:
// Create a Bedrock model with reasoning configurationconst bedrockModel = new BedrockModel({ modelId: 'global.anthropic.claude-sonnet-5', additionalRequestFields: { thinking: { type: 'enabled', budget_tokens: 4096, // Minimum of 1,024 }, },})
// Create an agent with the reasoning-enabled modelconst agent = new Agent({ model: bedrockModel })
// Ask a question that requires reasoningconst response = await agent.invoke( 'If a train travels at 120 km/h and needs to cover 450 km, how long will the journey take?')Note: Not all models support structured reasoning output. Check the inference reasoning documentation for details on supported models.
Structured Output
Section titled “Structured Output”Amazon Bedrock models support structured output through their tool calling capabilities. Pass a schema to the agent, and Strands converts it to Bedrock’s tool specification format and validates the response.
Define a Pydantic model and pass it to agent.structured_output():
from pydantic import BaseModel, Fieldfrom strands import Agentfrom strands.models import BedrockModelfrom typing import List, Optional
class ProductAnalysis(BaseModel): """Analyze product information from text.""" name: str = Field(description="Product name") category: str = Field(description="Product category") price: float = Field(description="Price in USD") features: List[str] = Field(description="Key product features") rating: Optional[float] = Field(description="Customer rating 1-5", ge=1, le=5)
bedrock_model = BedrockModel()
agent = Agent(model=bedrock_model)
result = agent.structured_output( ProductAnalysis, """ Analyze this product: The UltraBook Pro is a premium laptop computer priced at $1,299. It features a 15-inch 4K display, 16GB RAM, 512GB SSD, and 12-hour battery life. Customer reviews average 4.5 stars. """)
print(f"Product: {result.name}")print(f"Category: {result.category}")print(f"Price: ${result.price}")print(f"Features: {result.features}")print(f"Rating: {result.rating}")Define a Zod schema and pass it as structuredOutputSchema. Validated output is on result.structuredOutput:
import { Agent } from '@strands-agents/sdk'import { BedrockModel } from '@strands-agents/sdk/models/bedrock'import { z } from 'zod'
const ProductAnalysis = z.object({ name: z.string().describe('Product name'), category: z.string().describe('Product category'), price: z.number().describe('Price in USD'), features: z.array(z.string()).describe('Key product features'), rating: z.number().min(1).max(5).optional().describe('Customer rating 1-5'),})
const bedrockModel = new BedrockModel()const agent = new Agent({ model: bedrockModel, structuredOutputSchema: ProductAnalysis,})
const result = await agent.invoke( `Analyze this product: The UltraBook Pro is a premium laptop computer priced at $1,299. It features a 15-inch 4K display, 16GB RAM, 512GB SSD, and 12-hour battery life. Customer reviews average 4.5 stars.`)
const product = result.structuredOutput as z.infer<typeof ProductAnalysis>console.log(`Product: ${product.name}`)console.log(`Category: ${product.category}`)console.log(`Price: $${product.price}`)console.log(`Features: ${product.features.join(', ')}`)console.log(`Rating: ${product.rating}`)For schema patterns, error handling, and per-invocation overrides, see Structured Output.
Token Counting
Section titled “Token Counting”Context management uses token counting to estimate input tokens before each model call.
The Bedrock provider can use the native count_tokens API via the CountTokens action in the Converse API. This includes system prompts, messages, and tool specifications in the count.
Not all Bedrock models support the CountTokens API. When a model doesn’t support it or the caller doesn’t have the required IAM permissions, the provider caches this result and falls back to estimation with a character-based heuristic (characters ÷ 4 for text, characters ÷ 2 for JSON) for subsequent calls.
You can enable native token counting with:
model = BedrockModel( model_id="global.anthropic.claude-sonnet-5", use_native_token_count=True,)The Bedrock provider can use the native CountTokensCommand API. This includes system prompts, messages, and tool specifications in the count.
Not all Bedrock models support the CountTokens API. When a model doesn’t support it or the caller doesn’t have the required IAM permissions, the provider caches this result and falls back to estimation with a character-based heuristic (characters ÷ 4 for text, characters ÷ 2 for JSON) for subsequent calls.
You can enable native token counting with:
const model = new BedrockModel({ modelId: 'global.anthropic.claude-sonnet-5', useNativeTokenCount: true,})OpenAI-Compatible Endpoints (Mantle)
Section titled “OpenAI-Compatible Endpoints (Mantle)”Mantle is not a separate service or model catalog: it is Amazon Bedrock’s second
endpoint family,
bedrock-mantle,
which serves Bedrock-hosted models through OpenAI-compatible APIs. The two families
serve different, overlapping model sets: many models are only on the standard
bedrock-runtime endpoint that BedrockModel uses, some model lines are only on
bedrock-mantle, and some are on both. AWS lists which endpoint serves each model in
endpoint availability by model.
Pick your provider by where the model is served. When it is on bedrock-runtime, use
BedrockModel as described on the rest of this page (AWS recommends that endpoint
when a model is on both). When it is served through Mantle, connect with the SDK’s
OpenAI Responses provider instead, in one of the two ways below.
In Python, that provider can also target bedrock-runtime; see
Choosing the Endpoint.
Connecting with AWS Credentials
Section titled “Connecting with AWS Credentials”Pass bedrock_mantle_configbedrockMantleConfig
from strands import Agentfrom strands.models.openai_responses import OpenAIResponsesModel
model = OpenAIResponsesModel( model_id="openai.gpt-oss-120b", bedrock_mantle_config={"region": "us-east-1"},)
agent = Agent(model=model)response = agent("What is 2+2?")print(response)import { Agent } from '@strands-agents/sdk'import { OpenAIModel } from '@strands-agents/sdk/models/openai'
const model = new OpenAIModel({ modelId: 'openai.gpt-oss-120b', bedrockMantleConfig: { region: 'us-east-1' },})
const agent = new Agent({ model })const response = await agent.invoke('What is 2+2?')console.log(response)Requires the optional dependency: npm install @aws/bedrock-token-generator
Omit the region to resolve it from your AWS environment. The config also accepts AWS
credentials to forward to the token generator
(credentials_providercredentialsexpiryexpiresInSecondsboto_session can also supply the region from a configured profile.
Choosing the Endpoint
Section titled “Choosing the Endpoint”The config targets bedrock-mantle by default. In Python, set endpoint to
bedrock-runtime, which is where the OpenAI GPT models are served through
cross-Region inference
profile ids such as global.openai.gpt-5.6-luna:
from strands import Agentfrom strands.models.openai_responses import OpenAIResponsesModel
model = OpenAIResponsesModel( model_id="global.openai.gpt-5.6-luna", bedrock_mantle_config={"endpoint": "bedrock-runtime", "region": "us-east-1"},)
agent = Agent(model=model)response = agent("What is 2+2?")print(response)AWS compares what the two endpoints support in endpoints supported by Amazon Bedrock.
Connecting with a Bedrock API Key
Section titled “Connecting with a Bedrock API Key”Authenticate with a
Bedrock API key
and point the client at your region’s Mantle endpoint yourself. Note that some model
lines are served from /openai/v1 rather than /v1; the config-based approach above
picks the right path for you.
from strands import Agentfrom strands.models.openai_responses import OpenAIResponsesModel
region = "us-east-1"model = OpenAIResponsesModel( model_id="openai.gpt-oss-120b", client_args={ "api_key": "<BEDROCK_API_KEY>", "base_url": f"https://bedrock-mantle.{region}.api.aws/v1", },)
agent = Agent(model=model)response = agent("What is 2+2?")print(response)import { Agent } from '@strands-agents/sdk'import { OpenAIModel } from '@strands-agents/sdk/models/openai'
const region = 'us-east-1'const model = new OpenAIModel({ modelId: 'openai.gpt-oss-120b', apiKey: '<BEDROCK_API_KEY>', clientConfig: { baseURL: `https://bedrock-mantle.${region}.api.aws/v1`, },})
const agent = new Agent({ model })const response = await agent.invoke('What is 2+2?')console.log(response)Troubleshooting
Section titled “Troubleshooting”On-demand throughput isn’t supported
Section titled “On-demand throughput isn’t supported”If you encounter the error:
Invocation of model ID XXXX with on-demand throughput isn’t supported. Retry your request with the ID or ARN of an inference profile that contains this model.
This typically indicates that the model requires Cross-Region Inference, as documented in the Amazon Bedrock documentation on inference profiles. To resolve this issue, prefix your model ID with the appropriate regional identifier (us.or eu.) based on where your agent is running. For example:
Instead of:
anthropic.claude-sonnet-5Use:
us.anthropic.claude-sonnet-5Model identifier is invalid
Section titled “Model identifier is invalid”If you encounter the error:
ValidationException: An error occurred (ValidationException) when calling the ConverseStream operation: The provided model identifier is invalid
This is very likely due to calling Bedrock with an inference model id, such as: us.anthropic.claude-sonnet-5 from a region that does not support inference profiles. If so, pass in a valid model id, as follows:
agent = Agent(model="anthropic.claude-3-5-sonnet-20241022-v2:0")const agent = new Agent({ model: 'anthropic.claude-3-5-sonnet-20241022-v2:0'})CacheConfig with ARN-based inference profiles
Section titled “CacheConfig with ARN-based inference profiles”If you’re using an ARN-based application inference profile as your model_id (e.g., arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/abc123), CacheConfig(strategy="auto") will not automatically enable prompt caching.
The strategy="auto" detection checks the model ID string for "claude" or "anthropic" substrings. Cross-region inference profile IDs like us.anthropic.claude-sonnet-5 contain "anthropic" and are detected correctly, but application inference profiles use opaque resource IDs (application-inference-profile/abc123) that carry no model name information, so detection returns None, caching is skipped, and Strands logs a warning: model_id=<your-arn> | cache_config is enabled but this model does not support automatic caching.
Use strategy="anthropic" explicitly to fix this:
from strands import Agentfrom strands.models import BedrockModel, CacheConfig
bedrock_model = BedrockModel( model_id="arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/abc123", cache_config=CacheConfig(strategy="anthropic"))
agent = Agent(model=bedrock_model)import { Agent } from '@strands-agents/sdk'import { BedrockModel } from '@strands-agents/sdk/models/bedrock'
const bedrockModel = new BedrockModel({ modelId: 'arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/abc123', cacheConfig: { strategy: 'anthropic' },})
const agent = new Agent({ model: bedrockModel })strategy="anthropic" has identical performance to strategy="auto" and requires no additional API calls or IAM permissions.