AWS Bedrock ↗
noOriginal Documentation
This guide demonstrates how to use AWS Bedrock with Instructor to generate structured outputs. You’ll learn how to use AWS Bedrock’s LLM models with Pydantic to create type-safe, validated responses.
Prerequisites#
You’ll need to have an AWS account with access to Bedrock and the appropriate permissions. You’ll also need to set up your AWS credentials.
pip install "instructor[bedrock]"See Also#
- Getting Started - Quick start guide
- from_provider Guide - Detailed client configuration
- Mode Migration Guide - Move to core modes
- Provider Examples - Quick examples for all providers
- AWS Integration Guide - More AWS examples
AWS Bedrock#
AWS Bedrock is a fully managed service that offers a choice of high-performing foundation models (FMs) from leading AI companies like AI21 Labs, Anthropic, Cohere, Meta, Stability AI, and Amazon through a single API.
Auto Client Setup#
For simplified setup, you can use the auto client pattern:
import instructor
# Auto client with model specification
client = instructor.from_provider("bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0")
# The auto client automatically handles:
# - AWS credential detection from environment
# - Region configuration (defaults to us-east-1)
# - Mode selection based on model (Claude models use TOOLS)Deprecation Notice#
Deprecation Notice:
The
_asyncargument toinstructor.from_bedrockis deprecated. Please useasync_client=Truefor async clients instead. Support for_asyncmay be removed in a future release. All new code and examples should useasync_client.
Environment Configuration#
Set your AWS credentials and region:
export AWS_ACCESS_KEY_ID=your_access_key
export AWS_SECRET_ACCESS_KEY=your_secret_key
export AWS_DEFAULT_REGION=us-east-1Or configure using AWS CLI:
aws configureSync Example#
import boto3
import instructor
from pydantic import BaseModel
bedrock_client = boto3.client('bedrock-runtime')
client = instructor.from_provider("bedrock/claude-3-5-sonnet-20241022")
class User(BaseModel):
name: str
age: int
user = client.create(
modelId="anthropic.claude-3-sonnet-20240229-v1:0",
messages=[
{"role": "user", "content": "Extract: Jason is 25 years old"},
],
response_model=User,
)
print(user)
# > User(name='Jason', age=25)Async Example#
Warning: AWS Bedrock’s official SDK (
boto3) does not support async natively. If you need to call Bedrock from async code, you can useasyncio.to_threadto run synchronous Bedrock calls in a non-blocking way.
import instructor
from pydantic import BaseModel
import asyncio
client = instructor.from_provider("bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
class User(BaseModel):
name: str
age: int
def get_user():
return client.create(
modelId="anthropic.claude-3-sonnet-20240229-v1:0",
messages=[{"role": "user", "content": "Extract Jason is 25 years old"}],
response_model=User,
)
async def get_user_async():
return await asyncio.to_thread(get_user)
user = asyncio.run(get_user_async())
print(user)Supported Modes#
AWS Bedrock supports the following core modes:
TOOLS: Uses function calling for models that support it (like Claude models)MD_JSON: Direct JSON response generation (text extraction fallback)
Legacy modes (
BEDROCK_TOOLS,BEDROCK_JSON) are deprecated and map toMode.TOOLSandMode.MD_JSON. modes above. UseTOOLSorMD_JSONin new code.
import boto3
import instructor
from instructor import Mode
from pydantic import BaseModel
# Use from_provider for simplified setup
client = instructor.from_provider("bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0", mode=Mode.TOOLS)
# Or if you need to use a custom boto3 client:
# bedrock_client = boto3.client('bedrock-runtime')
# client = instructor.from_provider("bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0", client=bedrock_client, mode=Mode.TOOLS)
class User(BaseModel):
name: str
age: intOpenAI Compatibility: Flexible Input Format and Model Parameter#
Instructor’s Bedrock integration supports both OpenAI-style and Bedrock-native message formats, as well as any mix of the two. You can use either:
- OpenAI-style:
{"role": "user", "content": "Extract: Jason is 25 years old"} - Bedrock-native:
{"role": "user", "content": [{"text": "Extract: Jason is 25 years old"}]} - Mixed:
You can freely mix OpenAI-style and Bedrock-native messages in the same request. The integration will automatically convert OpenAI-style messages to the correct Bedrock format, while preserving any Bedrock-native fields you provide.
This flexibility also applies to other keyword arguments, such as the model name:
- You can use either
model(OpenAI-style) ormodelId(Bedrock-native) as a keyword argument. - If you provide
model, Instructor will automatically convert it tomodelIdfor Bedrock. - If you provide both,
modelIdtakes precedence.
Example:
import instructor
messages = [
{"role": "system", "content": "Extract the name and age."}, # OpenAI-style
{"role": "user", "content": [{"text": "Extract: Jason is 25 years old"}]}, # Bedrock-native
{"role": "assistant", "content": "Sure! Jason is 25."}, # OpenAI-style
]
# Both of these are valid:
user = client.create(
model="anthropic.claude-3-sonnet-20240229-v1:0", # OpenAI-style
messages=messages,
response_model=User,
)
user = client.create(
modelId="anthropic.claude-3-sonnet-20240229-v1:0", # Bedrock-native
messages=messages,
response_model=User,
)All of the above will work seamlessly with Instructor’s Bedrock integration.
Multimodal: Images and Documents#
Instructor will convert OpenAI-style image parts into Bedrock image blocks automatically. For documents (PDFs), Bedrock expects a native document block, so you should either pass a Bedrock-native document dict directly or build one with the PDF helper.
import instructor
from instructor.processing.multimodal import PDF
client = instructor.from_provider("bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0")
pdf = PDF.from_url("https://raw.githubusercontent.com/instructor-ai/instructor/main/tests/assets/invoice.pdf")
response = client.create(
modelId="anthropic.claude-3-sonnet-20240229-v1:0",
messages=[
{
"role": "user",
"content": [
"Analyze this document",
pdf.to_bedrock(),
],
}
],
)Bedrock document blocks also support S3 URIs (for example, s3://bucket/key.pdf) and local files; PDF.to_bedrock() will load the bytes and sanitize the document name for you.
Nested Objects#
import boto3
import instructor
from pydantic import BaseModel
# Initialize the Bedrock client
bedrock_client = boto3.client('bedrock-runtime')
# Enable instructor patches for Bedrock client
client = instructor.from_provider("bedrock/claude-3-5-sonnet-20241022")
class Address(BaseModel):
street: str
city: str
country: str
class User(BaseModel):
name: str
age: int
addresses: list[Address]
# Create structured output with nested objects
user = client.create(
modelId="anthropic.claude-3-sonnet-20240229-v1:0",
messages=[
{
"role": "user",
"content": """
Extract: Jason is 25 years old.
He lives at 123 Main St, New York, USA
and has a summer house at 456 Beach Rd, Miami, USA
""",
},
],
response_model=User,
)
print(user)
#> User(
#> name='Jason',
#> age=25,
#> addresses=[
#> Address(street='123 Main St', city='New York', country='USA'),
#> Address(street='456 Beach Rd', city='Miami', country='USA')
#> ]
#> )Modern Models and Features#
Latest Model Support#
AWS Bedrock supports many modern foundation models:
import instructor
# Claude 3.5 models (latest)
client = instructor.from_provider("bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0")
# or
client = instructor.from_provider("bedrock/anthropic.claude-3-5-haiku-20241022-v1:0")
# Amazon Nova models (multimodal)
client = instructor.from_provider("bedrock/amazon.nova-micro-v1:0")
# Meta Llama 3 models
client = instructor.from_provider("bedrock/meta.llama3-70b-instruct-v1:0")
# Mistral models
client = instructor.from_provider("bedrock/mistral.mistral-large-2402-v1:0")Advanced Configuration#
import boto3
import instructor
# Custom AWS configuration
bedrock_client = boto3.client(
'bedrock-runtime',
region_name='us-west-2',
aws_access_key_id='your_key',
aws_secret_access_key='your_secret'
)
# Use from_provider with custom client
client = instructor.from_provider(
"bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0",
client=bedrock_client,
mode=instructor.Mode.TOOLS
)
# Advanced inference configuration
user = client.create(
modelId="anthropic.claude-3-5-sonnet-20241022-v2:0",
messages=[{"role": "user", "content": "Extract user info"}],
response_model=User,
inferenceConfig={
"maxTokens": 2048,
"temperature": 0.1,
"topP": 0.9,
"stopSequences": ["STOP"]
}
)