For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Amazon Bedrock
Verified Code examples on this page have been automatically tested and verified.Route agentgateway LLM traffic to foundation models on Amazon Bedrock.
Configure Amazon Bedrock as an LLM provider in agentgateway.
Note
Bedrock excludes cached tokens from the input count that it reports. The CEL field llm.inputTokens adds them back, so telemetry, metrics, and token-based limits count a cache-heavy request higher than the number that Bedrock reports. To read the Bedrock number itself, use llm.providerInputTokens. For more information, see Token usage fields.
Note
Agentgateway accepts requests in one of the supported API formats (such as the /v1/chat/completions request body shape) and returns responses in that format.
Agentgateway translates between these formats and Bedrock formats internally using Bedrock’s Converse API.
Directly sending Converse or Invoke request shapes are not directly supported; see passthrough for more information if you need these APIs.
Authentication
Before you can use Bedrock as an LLM provider, you must authenticate by using the standard AWS authentication sources.
Agentgateway will automatically detect the local ambient credentials, but these can be explicitly configured with auth.aws.
Configuration
Review the following example configuration.# yaml-language-server: $schema=https://agentgateway.dev/schema/config
llm:
models:
- name: "*"
provider: bedrock
params:
awsRegion: us-west-2| Setting | Description |
|---|---|
name | The model name to match in incoming requests. When a client sends "model": "<name>", the request is routed to this provider. Use * to match any model name. |
provider | The LLM provider, set to bedrock for Amazon Bedrock models. |
params.model | The specific Bedrock model to use. If set, this model is used for all requests. If not set, the request must include the model to use. |
params.awsRegion | The AWS region where the Bedrock model is hosted. |
Passthrough
If your applications directly use the AWS Converse or Invoke APIs, Agentgateway cannot translate these APIs to other providers.
However, it can pass the request through to Bedrock itself following the passthrough approach.
This can provide telemetry data for these requests.
First, setup passthrough mode:
# yaml-language-server: $schema=https://agentgateway.dev/schema/config
llm:
models:
- name: us.anthropic*
provider: bedrock
params:
awsRegion: us-west-2
passthrough: detectThen, you can send native Converse and Invoke requests:
import json
import boto3
client = boto3.client(
'bedrock-runtime',
region_name='us-west-2',
endpoint_url='http://localhost:4000',
)
response = client.converse(
modelId='us.anthropic.claude-sonnet-4-6',
messages=[
{
'role': 'user',
'content': [{'text': 'give 1 word answer'}]
}
]
)
print('converse response:')
print(response)Note
Model translations are not supported with passthrough, so avoid using a model match like aws/*, as it cannot be transformed.
Claude Platform on AWS
See here for connect to Claude Platform on AWS.
Bedrock Mantle
Bedrock serves models on two API surfaces: the Runtime endpoint, which carries the Converse and Invoke APIs, and the Mantle endpoint, which carries the native OpenAI and Anthropic APIs. Some models are served on only one of the two.
For chat requests, the endpoint is chosen per model from the runtime and mantle tags in your model cost catalog. Run agctl catalog import to populate those tags, because the default sources include aws-bedrock-mantle, which reads them from the AWS model cards. Without a catalog, no model carries either tag, so every chat request falls back to the preference alone.
Set params.bedrockEndpointPreference to choose how the tags are applied.
# yaml-language-server: $schema=https://agentgateway.dev/schema/config
llm:
models:
- name: "*"
provider: bedrock
params:
awsRegion: us-west-2
bedrockEndpointPreference: runtimePreferred| Value | Endpoint selection |
|---|---|
runtimePreferred | Use Runtime, except for a model tagged mantle but not runtime. This value is the default. |
mantlePreferred | Use Mantle, except for a model tagged runtime but not mantle. |
runtimeOnly | Always use Runtime, whatever the tags say. |
mantleOnly | Always use Mantle, whatever the tags say. |
The Kubernetes API takes the same four values capitalized, such as RuntimePreferred, under spec.ai.provider.bedrock.endpointPreference. A value that you copy from one mode to the other fails to load.
The preference applies to four route types: chat completions, messages, responses, and Anthropic token counting. Every other route type ignores the preference and uses a fixed endpoint.
- Model listing always uses Mantle.
- Embeddings, realtime, Gemini token counting, detection, passthrough, and content generation always use Runtime.
- Reranking uses a separate Bedrock agent-runtime host rather than the Runtime or Mantle endpoint.
Whether the preference changes the request format that a model accepts depends on the endpoint that it selects. A model that resolves to Runtime accepts the Bedrock Converse format only, and its chat format tags do not apply. A model that resolves to Mantle accepts the formats in its tags, except for anthropic.claude* models, which always take the Anthropic Messages format. For more information, see Chat format tags.
Note
Requests to the Mantle endpoint are signed for the bedrock-mantle service rather than bedrock. If you scope an IAM policy by service name, grant both before you switch a route to Mantle.
Token counting
Bedrock supports token counting for Anthropic models via the count_tokens endpoint.
Agentgateway automatically handles the required formatting for Bedrock’s count-tokens endpoint.
curl -X POST http://localhost:4000/v1/messages/count_tokens \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic.claude-3-5-sonnet-20241022-v2:0",
"messages": [{"role": "user", "content": "Hello!"}],
"system": "You are a helpful assistant."
}'Example response:
{
"input_tokens": 15
}Extended thinking and reasoning
Extended thinking and reasoning lets models reason through complex problems before generating a response. To opt in, add the OpenAI reasoning_effort field to your request. The value is added to the additionalModelRequestFields of the Bedrock request, in a form that depends on the model family. The family is chosen by matching the model ID.
| Model ID contains | What the Bedrock request receives |
|---|---|
gpt-oss or deepseek | reasoning_effort, with the value from your request unchanged. |
openai., other than gpt-oss models | reasoning.effort, with the value from your request unchanged. |
amazon.nova-2- | reasoningConfig with maxReasoningEffort set to low, medium, or high. If you set none or omit reasoning_effort, no reasoning configuration is sent. Any other value is rejected. |
| Anything else | Claude thinking fields, as described in the rest of this section. |
For Claude models that support adaptive thinking, the request is sent with thinking.type set to adaptive and the effort level in output_config.effort, instead of a token budget. The value minimal is sent as low. Which models take this form depends on the adaptive_thinking tag in the model cost catalog. The built-in catalog sets this tag for these models.
Other Claude models, such as us.anthropic.claude-opus-4-20250514-v1:0, receive a thinking budget.
reasoning_effort value | Thinking budget |
|---|---|
minimal or low | 1,024 tokens |
medium | 2,048 tokens |
high | 4,096 tokens |
xhigh | 8,192 tokens |
max | 16,384 tokens |
Note that max_tokens must be greater than the thinking budget, and the minimum thinking budget is 1,024 tokens.
curl "localhost:4000/v1/chat/completions" -H content-type:application/json -d '{
"model": "",
"max_tokens": 6000,
"reasoning_effort": "high",
"messages": [
{
"role": "user",
"content": "Explain the trade-offs between consistency and availability in distributed systems."
}
]
}' | jqStructured outputs
Structured outputs constrain the model to respond with a specific JSON schema. Provide the schema definition in the OpenAI response_format field of your request. Agentgateway translates this to Bedrock’s native format automatically.
curl "localhost:4000/v1/chat/completions" -H content-type:application/json -d '{
"model": "",
"max_tokens": 256,
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "answer_schema",
"schema": {
"type": "object",
"properties": {
"answer": { "type": "string" },
"confidence": { "type": "number" }
},
"required": ["answer", "confidence"],
"additionalProperties": false
}
}
},
"messages": [
{
"role": "user",
"content": "Is the sky blue? Respond with your answer and a confidence score between 0 and 1."
}
]
}' | jq