How to Build Applications with Amazon Bedrock Foundation Models: Complete Developer Guide
Build applications with Amazon Bedrock foundation models by selecting a model ID, configuring the AWS SDK for Python or TypeScript, invoking the Converse API with mandatory maxTokens settings, and optionally integrating Knowledge Bases for RAG, Guardrails for content safety, and prompt caching for cost optimization.
The aws/agent-toolkit-for-aws repository provides canonical architectural guidance for building generative-AI applications on Amazon Bedrock. According to skills/core-skills/amazon-bedrock/SKILL.md, the toolkit defines a layered approach covering model selection, SDK integration, and operational best practices. This guide extracts the essential patterns, code examples, and critical configuration requirements from the official skill definition.
Understanding the Bedrock Application Architecture
The Bedrock skill organizes application development into distinct layers. Each layer maps to specific implementation tasks and reference documentation.
- Model invocation – Select a foundation model and call the Bedrock Converse or InvokeModel API. The
SKILL.mdfile details the API landscape and recommends Converse for multi-turn conversations. - Model selection – Choose from Claude, Llama, Titan, Nova, or other available models using the latest model IDs and cross-region inference profiles documented in
model-selection-guide.md. - SDK integration – Use
boto3for Python or@aws-sdk/client-bedrock-runtimefor TypeScript to invoke the Converse endpoint with proper retry configurations. - RAG and Knowledge Bases – Embed documents, store vectors, and retrieve context using the patterns in
knowledge-bases-setup.md. - Guardrails and caching – Enforce content safety with guardrails and reduce latency using prompt caching as described in
guardrails.mdandprompt-caching.md. - Cost and quota management – Track token consumption and handle throttling using the CloudWatch metrics and CUR queries in
quota-health.mdandcost-tracking.md.
Selecting the Right Model and API
Model Selection Strategy
Before writing code, identify the appropriate foundation model for your use case. The model-selection-guide.md reference file lists current model IDs, cost-performance trade-offs, and cross-region inference prefixes. Run the following AWS CLI command to verify model availability in your target region:
aws bedrock list-foundation-models --region us-east-1
Converse API vs InvokeModel
According to skills/core-skills/amazon-bedrock/SKILL.md, you should prefer the Converse API for conversational applications. It provides a unified interface across model providers and manages message formatting automatically. Use InvokeModel only when you need direct access to provider-specific request schemas or features not yet supported by Converse.
Setting Up IAM and SDK Prerequisites
Your application requires specific IAM permissions and SDK configurations before invoking Bedrock.
Configuring IAM Permissions
Grant minimal necessary actions based on your use case:
bedrock:InvokeModelandbedrock-runtime:InvokeModelfor direct inferencebedrock-runtime:Converseandbedrock-runtime:ConverseStreamfor conversational APIsbedrock-agent:*for Knowledge Base operations
Enable confused-deputy protection by including external ID conditions in your trust policies when assuming cross-account roles.
Installing the AWS SDK
Install the minimum required SDK versions to access Bedrock features:
Python:
pip install boto3>=1.34
TypeScript:
npm install @aws-sdk/client-bedrock-runtime
Implementing Model Invocation with Python
The Python SDK quick-reference in sdk-converse-api-python.md provides the canonical pattern for synchronous inference. Always configure adaptive retries and explicitly set the maxTokens parameter.
import boto3
from botocore.config import Config
# Configure adaptive retries
bedrock_cfg = Config(
retries={"max_attempts": 5, "mode": "adaptive"}
)
client = boto3.client(
"bedrock-runtime",
region_name="us-east-1",
config=bedrock_cfg,
)
model_id = "anthropic.claude-sonnet-4-6"
response = client.converse(
modelId=model_id,
messages=[{
"role": "user",
"content": [{"text": "Explain Bedrock prompt caching"}]
}],
inferenceConfig={"maxTokens": 1024}, # MANDATORY per SKILL.md
)
print(response["output"]["message"]["content"][0]["text"])
Critical: The skill definition warns that omitting maxTokens silently reserves the model's maximum token limit, which frequently triggers throttling errors. Always specify this parameter.
Building Streaming Applications with TypeScript
For real-time streaming responses, use the ConverseStreamCommand class from the Bedrock Runtime client. The sdk-converse-api-typescript.md reference demonstrates this pattern with proper async iteration.
import {
BedrockRuntimeClient,
ConverseStreamCommand,
} from "@aws-sdk/client-bedrock-runtime";
const client = new BedrockRuntimeClient({ region: "eu-west-1" });
const input = {
modelId: "anthropic.claude-haiku-20240307-v1:0",
messages: [{
role: "user",
content: [{ text: "Summarize the latest Bedrock pricing" }]
}],
inferenceConfig: { maxTokens: 512 }, // Required parameter
};
const command = new ConverseStreamCommand(input);
const response = await client.send(command);
for await (const chunk of response) {
process.stdout.write(chunk.bytes?.toString() ?? '');
}
Implementing Retrieval-Augmented Generation (RAG)
Creating a Knowledge Base
The knowledge-bases-setup.md reference file documents the complete workflow for RAG applications. First, provision a Knowledge Base with your vector store configuration:
aws bedrock-agent create-knowledge-base \
--knowledgeBaseName myDocKB \
--roleArn arn:aws:iam::123456789012:role/BedrockKBRole \
--storageConfiguration '{"type":"OPENSEARCH","opensearch":{"domainName":"my-os-domain"}}' \
--vectorEmbeddingConfiguration '{"modelArn":"arn:aws:bedrock:us-east-1::model/amazon.titan-embed-text-v2"}'
Ingesting Documents
Start an ingestion job to process documents from S3:
aws bedrock-agent start-ingestion-job \
--knowledgeBaseId <kb-id> \
--sourceConfiguration '{"s3":{"bucket":"my-doc-bucket","keyPrefix":"data/"}}'
Querying with Retrieve-and-Generate
Use the retrieve-and-generate API to query your Knowledge Base and generate responses in a single operation:
aws bedrock-agent-runtime retrieve-and-generate \
--input '{"text":"What are the security best-practices for Bedrock?"}' \
--retrieve-and-generate-configuration '{
"type":"KNOWLEDGE_BASE",
"knowledgeBaseConfiguration": {
"knowledgeBaseId":"<kb-id>",
"modelArn":"arn:aws:bedrock:us-east-1::model/anthropic.claude-sonnet-4-6"
}
}'
Securing and Optimizing Production Workloads
Implementing Guardrails
Attach content safety policies using the patterns in guardrails.md. Configure guardrails to mask PII and block harmful content before the model processes the prompt. Pass the guardrail ARN in your converse() or ConverseStreamCommand invocation.
Enabling Prompt Caching
Reduce latency and costs for repetitive prompts by implementing prompt caching as documented in prompt-caching.md. This feature caches common prompt prefixes across multiple requests, significantly improving response times for multi-turn conversations.
Monitoring Costs and Quotas
Track usage and prevent throttling using the metrics defined in quota-health.md and cost-tracking.md. Set up CloudWatch alarms for Invocations and InputTokenCount metrics. Use Cost and Usage Report (CUR) 2.0 queries to attribute costs by application tag.
Summary
- Always set
maxTokenswhen calling the Converse API to avoid silent throttling issues. - Use the Converse API (not InvokeModel) for multi-turn conversations to ensure consistent message formatting across model providers.
- Install
boto3>=1.34for Python or@aws-sdk/client-bedrock-runtimefor TypeScript to access the latest Bedrock features. - Implement RAG by creating Knowledge Bases through the
bedrock-agentAPI and querying viaretrieve-and-generate. - Secure applications with Guardrails and optimize costs using prompt caching and proper quota monitoring.
Frequently Asked Questions
What's the difference between the Converse API and InvokeModel?
The Converse API provides a unified, model-agnostic interface for conversational applications, automatically handling message formatting for different providers. InvokeModel requires provider-specific request schemas and is recommended only when you need access to features not yet supported by Converse, such as specific fine-tuning parameters or legacy model versions.
Why must I always set the maxTokens parameter explicitly?
According to skills/core-skills/amazon-bedrock/SKILL.md, omitting maxTokens causes the API to silently reserve the model's maximum token capacity. This reservation frequently triggers throttling errors because Bedrock interprets the request as potentially consuming the full quota. Explicitly setting this parameter ensures predictable resource allocation.
How do I choose the right foundation model for my use case?
Consult model-selection-guide.md in the repository for current model IDs, latency benchmarks, and cost comparisons. Run aws bedrock list-foundation-models to verify regional availability, and consider cross-region inference profiles for improved resilience. The skill definition recommends Claude Sonnet for complex reasoning, Haiku for low-latency tasks, and Titan for balanced cost-performance.
Can I use Bedrock without managing vector stores for RAG?
Yes. While the Knowledge Bases feature requires you to configure vector stores (OpenSearch or Pinecone), you can implement lightweight RAG by retrieving context from your own database and passing it directly in the prompt text to the Converse API. However, for production-scale document retrieval, the managed Knowledge Base service provides automatic chunking, embedding, and retrieval optimization as documented in knowledge-bases-setup.md.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →