Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:28:30 +08:00
commit 171acedaa4
220 changed files with 85967 additions and 0 deletions

View File

@@ -0,0 +1,377 @@
---
name: aws-sdk-java-v2-bedrock
description: Amazon Bedrock patterns using AWS SDK for Java 2.x. Use when working with foundation models (listing, invoking), text generation, image generation, embeddings, streaming responses, or integrating generative AI with Spring Boot applications.
category: aws
tags: [aws, bedrock, java, sdk, generative-ai, foundation-models]
version: 2.0.0
allowed-tools: Read, Write, Bash
---
# AWS SDK for Java 2.x - Amazon Bedrock
## When to Use
Use this skill when:
- Listing and inspecting foundation models on Amazon Bedrock
- Invoking foundation models for text generation (Claude, Llama, Titan)
- Generating images with AI models (Stable Diffusion)
- Creating text embeddings for RAG applications
- Implementing streaming responses for real-time generation
- Working with multiple AI providers through unified API
- Integrating generative AI into Spring Boot applications
- Building AI-powered chatbots and assistants
## Overview
Amazon Bedrock provides access to foundation models from leading AI providers through a unified API. This skill covers patterns for working with various models including Claude, Llama, Titan, and Stability Diffusion using AWS SDK for Java 2.x.
## Quick Start
### Dependencies
```xml
<!-- Bedrock (model management) -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bedrock</artifactId>
</dependency>
<!-- Bedrock Runtime (model invocation) -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bedrockruntime</artifactId>
</dependency>
<!-- For JSON processing -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
</dependency>
```
### Basic Client Setup
```java
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.bedrock.BedrockClient;
import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient;
// Model management client
BedrockClient bedrockClient = BedrockClient.builder()
.region(Region.US_EAST_1)
.build();
// Model invocation client
BedrockRuntimeClient bedrockRuntimeClient = BedrockRuntimeClient.builder()
.region(Region.US_EAST_1)
.build();
```
## Core Patterns
### Model Discovery
```java
import software.amazon.awssdk.services.bedrock.model.*;
import java.util.List;
public List<FoundationModelSummary> listFoundationModels(BedrockClient bedrockClient) {
return bedrockClient.listFoundationModels().modelSummaries();
}
```
### Model Invocation
```java
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.services.bedrockruntime.model.*;
import org.json.JSONObject;
public String invokeModel(BedrockRuntimeClient client, String modelId, String prompt) {
JSONObject payload = createPayload(modelId, prompt);
InvokeModelResponse response = client.invokeModel(request -> request
.modelId(modelId)
.body(SdkBytes.fromUtf8String(payload.toString())));
return extractTextFromResponse(modelId, response.body().asUtf8String());
}
private JSONObject createPayload(String modelId, String prompt) {
if (modelId.startsWith("anthropic.claude")) {
return new JSONObject()
.put("anthropic_version", "bedrock-2023-05-31")
.put("max_tokens", 1000)
.put("messages", new JSONObject[]{
new JSONObject().put("role", "user").put("content", prompt)
});
} else if (modelId.startsWith("amazon.titan")) {
return new JSONObject()
.put("inputText", prompt)
.put("textGenerationConfig", new JSONObject()
.put("maxTokenCount", 512)
.put("temperature", 0.7));
} else if (modelId.startsWith("meta.llama")) {
return new JSONObject()
.put("prompt", "[INST] " + prompt + " [/INST]")
.put("max_gen_len", 512)
.put("temperature", 0.7);
}
throw new IllegalArgumentException("Unsupported model: " + modelId);
}
```
### Streaming Responses
```java
public void streamResponse(BedrockRuntimeClient client, String modelId, String prompt) {
JSONObject payload = createPayload(modelId, prompt);
InvokeModelWithResponseStreamRequest streamRequest =
InvokeModelWithResponseStreamRequest.builder()
.modelId(modelId)
.body(SdkBytes.fromUtf8String(payload.toString()))
.build();
client.invokeModelWithResponseStream(streamRequest,
InvokeModelWithResponseStreamResponseHandler.builder()
.onEventStream(stream -> {
stream.forEach(event -> {
if (event instanceof PayloadPart) {
PayloadPart payloadPart = (PayloadPart) event;
String chunk = payloadPart.bytes().asUtf8String();
processChunk(modelId, chunk);
}
});
})
.build());
}
```
### Text Embeddings
```java
public double[] createEmbeddings(BedrockRuntimeClient client, String text) {
String modelId = "amazon.titan-embed-text-v1";
JSONObject payload = new JSONObject().put("inputText", text);
InvokeModelResponse response = client.invokeModel(request -> request
.modelId(modelId)
.body(SdkBytes.fromUtf8String(payload.toString())));
JSONObject responseBody = new JSONObject(response.body().asUtf8String());
JSONArray embeddingArray = responseBody.getJSONArray("embedding");
double[] embeddings = new double[embeddingArray.length()];
for (int i = 0; i < embeddingArray.length(); i++) {
embeddings[i] = embeddingArray.getDouble(i);
}
return embeddings;
}
```
### Spring Boot Integration
```java
@Configuration
public class BedrockConfiguration {
@Bean
public BedrockClient bedrockClient() {
return BedrockClient.builder()
.region(Region.US_EAST_1)
.build();
}
@Bean
public BedrockRuntimeClient bedrockRuntimeClient() {
return BedrockRuntimeClient.builder()
.region(Region.US_EAST_1)
.build();
}
}
@Service
public class BedrockAIService {
private final BedrockRuntimeClient bedrockRuntimeClient;
@Value("${bedrock.default-model-id:anthropic.claude-sonnet-4-5-20250929-v1:0}")
private String defaultModelId;
public BedrockAIService(BedrockRuntimeClient bedrockRuntimeClient) {
this.bedrockRuntimeClient = bedrockRuntimeClient;
}
public String generateText(String prompt) {
return generateText(prompt, defaultModelId);
}
public String generateText(String prompt, String modelId) {
Map<String, Object> payload = createPayload(modelId, prompt);
String payloadJson = new ObjectMapper().writeValueAsString(payload);
InvokeModelResponse response = bedrockRuntimeClient.invokeModel(
request -> request
.modelId(modelId)
.body(SdkBytes.fromUtf8String(payloadJson)));
return extractTextFromResponse(modelId, response.body().asUtf8String());
}
}
```
## Basic Usage Example
```java
BedrockRuntimeClient client = BedrockRuntimeClient.builder()
.region(Region.US_EAST_1)
.build();
String prompt = "Explain quantum computing in simple terms";
String response = invokeModel(client, "anthropic.claude-sonnet-4-5-20250929-v1:0", prompt);
System.out.println(response);
```
## Best Practices
### Model Selection
- **Claude 4.5 Sonnet**: Best for complex reasoning, analysis, and creative tasks
- **Claude 4.5 Haiku**: Fast and affordable for real-time applications
- **Claude 3.7 Sonnet**: Most advanced reasoning capabilities
- **Llama 3.1**: Latest generation open-source alternative, good for general tasks
- **Titan**: AWS native, cost-effective for simple text generation
### Performance Optimization
- Reuse client instances (don't create new clients for each request)
- Use async clients for I/O operations
- Implement streaming for long responses
- Cache foundation model lists
### Security
- Never log sensitive prompt data
- Use IAM roles for authentication (never access keys)
- Implement rate limiting for public applications
- Sanitize user inputs to prevent prompt injection
### Error Handling
- Implement retry logic for throttling (exponential backoff)
- Handle model-specific validation errors
- Validate responses before processing
- Use proper exception handling for different error types
### Cost Optimization
- Use appropriate max_tokens limits
- Choose cost-effective models for simple tasks
- Cache embeddings when possible
- Monitor usage and set budget alerts
## Common Model IDs
```java
// Claude Models
public static final String CLAUDE_SONNET_4_5 = "anthropic.claude-sonnet-4-5-20250929-v1:0";
public static final String CLAUDE_HAIKU_4_5 = "anthropic.claude-haiku-4-5-20251001-v1:0";
public static final String CLAUDE_OPUS_4_1 = "anthropic.claude-opus-4-1-20250805-v1:0";
public static final String CLAUDE_3_7_SONNET = "anthropic.claude-3-7-sonnet-20250219-v1:0";
public static final String CLAUDE_OPUS_4 = "anthropic.claude-opus-4-20250514-v1:0";
public static final String CLAUDE_SONNET_4 = "anthropic.claude-sonnet-4-20250514-v1:0";
public static final String CLAUDE_3_5_SONNET_V2 = "anthropic.claude-3-5-sonnet-20241022-v2:0";
public static final String CLAUDE_3_5_HAIKU = "anthropic.claude-3-5-haiku-20241022-v1:0";
public static final String CLAUDE_3_OPUS = "anthropic.claude-3-opus-20240229-v1:0";
// Llama Models
public static final String LLAMA_3_3_70B = "meta.llama3-3-70b-instruct-v1:0";
public static final String LLAMA_3_2_90B = "meta.llama3-2-90b-instruct-v1:0";
public static final String LLAMA_3_2_11B = "meta.llama3-2-11b-instruct-v1:0";
public static final String LLAMA_3_2_3B = "meta.llama3-2-3b-instruct-v1:0";
public static final String LLAMA_3_2_1B = "meta.llama3-2-1b-instruct-v1:0";
public static final String LLAMA_4_MAV_17B = "meta.llama4-maverick-17b-instruct-v1:0";
public static final String LLAMA_4_SCOUT_17B = "meta.llama4-scout-17b-instruct-v1:0";
public static final String LLAMA_3_1_405B = "meta.llama3-1-405b-instruct-v1:0";
public static final String LLAMA_3_1_70B = "meta.llama3-1-70b-instruct-v1:0";
public static final String LLAMA_3_1_8B = "meta.llama3-1-8b-instruct-v1:0";
public static final String LLAMA_3_70B = "meta.llama3-70b-instruct-v1:0";
public static final String LLAMA_3_8B = "meta.llama3-8b-instruct-v1:0";
// Amazon Titan Models
public static final String TITAN_TEXT_EXPRESS = "amazon.titan-text-express-v1";
public static final String TITAN_TEXT_LITE = "amazon.titan-text-lite-v1";
public static final String TITAN_EMBEDDINGS = "amazon.titan-embed-text-v1";
public static final String TITAN_IMAGE_GENERATOR = "amazon.titan-image-generator-v1";
// Stable Diffusion
public static final String STABLE_DIFFUSION_XL = "stability.stable-diffusion-xl-v1";
// Mistral AI Models
public static final String MISTRAL_LARGE_2407 = "mistral.mistral-large-2407-v1:0";
public static final String MISTRAL_LARGE_2402 = "mistral.mistral-large-2402-v1:0";
public static final String MISTRAL_SMALL_2402 = "mistral.mistral-small-2402-v1:0";
public static final String MISTRAL_PIXTRAL_2502 = "mistral.pixtral-large-2502-v1:0";
public static final String MISTRAL_MIXTRAL_8X7B = "mistral.mixtral-8x7b-instruct-v0:1";
public static final String MISTRAL_7B = "mistral.mistral-7b-instruct-v0:2";
// Amazon Nova Models
public static final String NOVA_PREMIER = "amazon.nova-premier-v1:0";
public static final String NOVA_PRO = "amazon.nova-pro-v1:0";
public static final String NOVA_LITE = "amazon.nova-lite-v1:0";
public static final String NOVA_MICRO = "amazon.nova-micro-v1:0";
public static final String NOVA_CANVAS = "amazon.nova-canvas-v1:0";
public static final String NOVA_REEL = "amazon.nova-reel-v1:1";
// Other Models
public static final String COHERE_COMMAND = "cohere.command-text-v14";
public static final String DEEPSEEK_R1 = "deepseek.r1-v1:0";
public static final String DEEPSEEK_V3_1 = "deepseek.v3-v1:0";
```
## Examples
See the [examples directory](examples/) for comprehensive usage patterns.
## Advanced Topics
See the [Advanced Topics](references/advanced-topics.md) for:
- Multi-model service patterns
- Advanced error handling with retries
- Batch processing strategies
- Performance optimization techniques
- Custom response parsing
## Model Reference
See the [Model Reference](references/model-reference.md) for:
- Detailed model specifications
- Payload/response formats for each provider
- Performance characteristics
- Model selection guidelines
- Configuration templates
## Testing Strategies
See the [Testing Strategies](references/testing-strategies.md) for:
- Unit testing with mocked clients
- Integration testing with LocalStack
- Performance testing
- Streaming response testing
- Test data management
## Related Skills
- `aws-sdk-java-v2-core` - Core AWS SDK patterns
- `langchain4j-ai-services-patterns` - LangChain4j integration
- `spring-boot-dependency-injection` - Spring DI patterns
- `spring-boot-test-patterns` - Spring testing patterns
## References
- [AWS Bedrock User Guide](references/aws-bedrock-user-guide.md)
- [AWS SDK for Java 2.x Documentation](references/aws-sdk-java-bedrock-api.md)
- [Bedrock API Reference](references/aws-bedrock-api-reference.md)
- [AWS SDK Examples](references/aws-sdk-examples.md)
- [Official AWS Examples](bedrock_code_examples.md)
- [Supported Models](bedrock_models_supported.md)
- [Runtime Examples](bedrock_runtime_code_examples.md)

View File

@@ -0,0 +1,249 @@
Amazon Bedrock examples using SDK for Java 2.x - AWS SDK for Java 2.x
Amazon Bedrock examples using SDK for Java 2.x - AWS SDK for Java 2.x
[Open PDF](http://https:%2F%2Fdocs.aws.amazon.com%2Fsdk-for-java%2Flatest%2Fdeveloper-guide%2Fjava_bedrock_code_examples.html/pdfs/sdk-for-java/latest/developer-guide/aws-sdk-java-dg-v2.pdf#java_bedrock_code_examples "Open PDF")
[Documentation](http://https:%2F%2Fdocs.aws.amazon.com%2Fsdk-for-java%2Flatest%2Fdeveloper-guide%2Fjava_bedrock_code_examples.html/index.html) [AWS SDK for Java](http://https:%2F%2Fdocs.aws.amazon.com%2Fsdk-for-java%2Flatest%2Fdeveloper-guide%2Fjava_bedrock_code_examples.html/sdk-for-java/index.html) [Developer Guide for version 2.x](http://https:%2F%2Fdocs.aws.amazon.com%2Fsdk-for-java%2Flatest%2Fdeveloper-guide%2Fjava_bedrock_code_examples.html/home.html)
[Actions](http://https:%2F%2Fdocs.aws.amazon.com%2Fsdk-for-java%2Flatest%2Fdeveloper-guide%2Fjava_bedrock_code_examples.html#actions)
# Amazon Bedrock examples using SDK for Java 2.x
The following code examples show you how to perform actions and implement common scenarios by using
the AWS SDK for Java 2.x with Amazon Bedrock.
_Actions_ are code excerpts from larger programs and must be run in context. While actions show you how to call individual service functions, you can see actions in context in their related scenarios.
Each example includes a link to the complete source code, where you can find
instructions on how to set up and run the code in context.
###### Topics
- [Actions](http://https:%2F%2Fdocs.aws.amazon.com%2Fsdk-for-java%2Flatest%2Fdeveloper-guide%2Fjava_bedrock_code_examples.html#actions)
## Actions
The following code example shows how to use `GetFoundationModel`.
**SDK for Java 2.x**
###### Note
There's more on GitHub. Find the complete example and learn how to set up and run in the
[AWS Code\
Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/bedrock#code-examples).
Get details about a foundation model using the synchronous Amazon Bedrock client.
```java
/**
* Get details about an Amazon Bedrock foundation model.
*
* @param bedrockClient The service client for accessing Amazon Bedrock.
* @param modelIdentifier The model identifier.
* @return An object containing the foundation model's details.
*/
public static FoundationModelDetails getFoundationModel(BedrockClient bedrockClient, String modelIdentifier) {
try {
GetFoundationModelResponse response = bedrockClient.getFoundationModel(
r -> r.modelIdentifier(modelIdentifier)
);
FoundationModelDetails model = response.modelDetails();
System.out.println(" Model ID: " + model.modelId());
System.out.println(" Model ARN: " + model.modelArn());
System.out.println(" Model Name: " + model.modelName());
System.out.println(" Provider Name: " + model.providerName());
System.out.println(" Lifecycle status: " + model.modelLifecycle().statusAsString());
System.out.println(" Input modalities: " + model.inputModalities());
System.out.println(" Output modalities: " + model.outputModalities());
System.out.println(" Supported customizations: " + model.customizationsSupported());
System.out.println(" Supported inference types: " + model.inferenceTypesSupported());
System.out.println(" Response streaming supported: " + model.responseStreamingSupported());
return model;
} catch (ValidationException e) {
throw new IllegalArgumentException(e.getMessage());
} catch (SdkException e) {
System.err.println(e.getMessage());
throw new RuntimeException(e);
}
}
```
Get details about a foundation model using the asynchronous Amazon Bedrock client.
```java
/**
* Get details about an Amazon Bedrock foundation model.
*
* @param bedrockClient The async service client for accessing Amazon Bedrock.
* @param modelIdentifier The model identifier.
* @return An object containing the foundation model's details.
*/
public static FoundationModelDetails getFoundationModel(BedrockAsyncClient bedrockClient, String modelIdentifier) {
try {
CompletableFuture<GetFoundationModelResponse> future = bedrockClient.getFoundationModel(
r -> r.modelIdentifier(modelIdentifier)
);
FoundationModelDetails model = future.get().modelDetails();
System.out.println(" Model ID: " + model.modelId());
System.out.println(" Model ARN: " + model.modelArn());
System.out.println(" Model Name: " + model.modelName());
System.out.println(" Provider Name: " + model.providerName());
System.out.println(" Lifecycle status: " + model.modelLifecycle().statusAsString());
System.out.println(" Input modalities: " + model.inputModalities());
System.out.println(" Output modalities: " + model.outputModalities());
System.out.println(" Supported customizations: " + model.customizationsSupported());
System.out.println(" Supported inference types: " + model.inferenceTypesSupported());
System.out.println(" Response streaming supported: " + model.responseStreamingSupported());
return model;
} catch (ExecutionException e) {
if (e.getMessage().contains("ValidationException")) {
throw new IllegalArgumentException(e.getMessage());
} else {
System.err.println(e.getMessage());
throw new RuntimeException(e);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println(e.getMessage());
throw new RuntimeException(e);
}
}
```
- For API details, see
[GetFoundationModel](https://docs.aws.amazon.com/goto/SdkForJavaV2/bedrock-2023-04-20/GetFoundationModel)
in _AWS SDK for Java 2.x API Reference_.
The following code example shows how to use `ListFoundationModels`.
**SDK for Java 2.x**
###### Note
There's more on GitHub. Find the complete example and learn how to set up and run in the
[AWS Code\
Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/bedrock#code-examples).
List the available Amazon Bedrock foundation models using the synchronous Amazon Bedrock client.
```java
/**
* Lists Amazon Bedrock foundation models that you can use.
* You can filter the results with the request parameters.
*
* @param bedrockClient The service client for accessing Amazon Bedrock.
* @return A list of objects containing the foundation models' details
*/
public static List<FoundationModelSummary> listFoundationModels(BedrockClient bedrockClient) {
try {
ListFoundationModelsResponse response = bedrockClient.listFoundationModels(r -> {});
List<FoundationModelSummary> models = response.modelSummaries();
if (models.isEmpty()) {
System.out.println("No available foundation models in " + region.toString());
} else {
for (FoundationModelSummary model : models) {
System.out.println("Model ID: " + model.modelId());
System.out.println("Provider: " + model.providerName());
System.out.println("Name: " + model.modelName());
System.out.println();
}
}
return models;
} catch (SdkClientException e) {
System.err.println(e.getMessage());
throw new RuntimeException(e);
}
}
```
List the available Amazon Bedrock foundation models using the asynchronous Amazon Bedrock client.
```java
/**
* Lists Amazon Bedrock foundation models that you can use.
* You can filter the results with the request parameters.
*
* @param bedrockClient The async service client for accessing Amazon Bedrock.
* @return A list of objects containing the foundation models' details
*/
public static List<FoundationModelSummary> listFoundationModels(BedrockAsyncClient bedrockClient) {
try {
CompletableFuture<ListFoundationModelsResponse> future = bedrockClient.listFoundationModels(r -> {});
List<FoundationModelSummary> models = future.get().modelSummaries();
if (models.isEmpty()) {
System.out.println("No available foundation models in " + region.toString());
} else {
for (FoundationModelSummary model : models) {
System.out.println("Model ID: " + model.modelId());
System.out.println("Provider: " + model.providerName());
System.out.println("Name: " + model.modelName());
System.out.println();
}
}
return models;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println(e.getMessage());
throw new RuntimeException(e);
} catch (ExecutionException e) {
System.err.println(e.getMessage());
throw new RuntimeException(e);
}
}
```
- For API details, see
[ListFoundationModels](https://docs.aws.amazon.com/goto/SdkForJavaV2/bedrock-2023-04-20/ListFoundationModels)
in _AWS SDK for Java 2.x API Reference_.
[Document Conventions](http://https:%2F%2Fdocs.aws.amazon.com%2Fsdk-for-java%2Flatest%2Fdeveloper-guide%2Fjava_bedrock_code_examples.html/general/latest/gr/docconventions.html)
AWS Batch
Amazon Bedrock Runtime
Did this page help you? - Yes
Thanks for letting us know we're doing a good job!
If you've got a moment, please tell us what we did right so we can do more of it.
Did this page help you? - No
Thanks for letting us know this page needs work. We're sorry we let you down.
If you've got a moment, please tell us how we can make the documentation better.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,274 @@
# Advanced Model Patterns
## Model-Specific Configuration
### Claude Models Configuration
```java
// Claude 3 Sonnet
public String invokeClaude3Sonnet(BedrockRuntimeClient client, String prompt) {
String modelId = "anthropic.claude-3-sonnet-20240229-v1:0";
JSONObject payload = new JSONObject()
.put("anthropic_version", "bedrock-2023-05-31")
.put("max_tokens", 1000)
.put("temperature", 0.7)
.put("top_p", 1.0)
.put("messages", new JSONObject[]{
new JSONObject()
.put("role", "user")
.put("content", prompt)
});
InvokeModelResponse response = client.invokeModel(request -> request
.modelId(modelId)
.body(SdkBytes.fromUtf8String(payload.toString())));
JSONObject responseBody = new JSONObject(response.body().asUtf8String());
return responseBody.getJSONArray("content")
.getJSONObject(0)
.getString("text");
}
// Claude 3 Haiku (faster, cheaper)
public String invokeClaude3Haiku(BedrockRuntimeClient client, String prompt) {
String modelId = "anthropic.claude-3-haiku-20240307-v1:0";
JSONObject payload = new JSONObject()
.put("anthropic_version", "bedrock-2023-05-31")
.put("max_tokens", 400)
.put("messages", new JSONObject[]{
new JSONObject()
.put("role", "user")
.put("content", prompt)
});
// Similar invocation pattern as above
}
```
### Llama Models Configuration
```java
// Llama 3 70B
public String invokeLlama3_70B(BedrockRuntimeClient client, String prompt) {
String modelId = "meta.llama3-70b-instruct-v1:0";
JSONObject payload = new JSONObject()
.put("prompt", prompt)
.put("max_gen_len", 512)
.put("temperature", 0.7)
.put("top_p", 0.9)
.put("stop", new String[]{"[INST]", "[/INST]"}); // Custom stop tokens
InvokeModelResponse response = client.invokeModel(request -> request
.modelId(modelId)
.body(SdkBytes.fromUtf8String(payload.toString())));
JSONObject responseBody = new JSONObject(response.body().asUtf8String());
return responseBody.getString("generation");
}
```
## Multi-Model Service Layer
```java
@Service
public class MultiModelService {
private final BedrockRuntimeClient bedrockRuntimeClient;
private final ObjectMapper objectMapper;
public MultiModelService(BedrockRuntimeClient bedrockRuntimeClient,
ObjectMapper objectMapper) {
this.bedrockRuntimeClient = bedrockRuntimeClient;
this.objectMapper = objectMapper;
}
public String invokeModel(String modelId, String prompt, Map<String, Object> additionalParams) {
Map<String, Object> payload = createModelPayload(modelId, prompt, additionalParams);
try {
InvokeModelResponse response = bedrockRuntimeClient.invokeModel(
request -> request
.modelId(modelId)
.body(SdkBytes.fromUtf8String(objectMapper.writeValueAsString(payload))));
return extractResponseContent(modelId, response.body().asUtf8String());
} catch (Exception e) {
throw new RuntimeException("Model invocation failed: " + e.getMessage(), e);
}
}
private Map<String, Object> createModelPayload(String modelId, String prompt,
Map<String, Object> additionalParams) {
Map<String, Object> payload = new HashMap<>();
if (modelId.startsWith("anthropic.claude")) {
payload.put("anthropic_version", "bedrock-2023-05-31");
payload.put("messages", List.of(Map.of("role", "user", "content", prompt)));
// Add common parameters with defaults
payload.putIfAbsent("max_tokens", 1000);
payload.putIfAbsent("temperature", 0.7);
} else if (modelId.startsWith("meta.llama")) {
payload.put("prompt", prompt);
payload.putIfAbsent("max_gen_len", 512);
payload.putIfAbsent("temperature", 0.7);
} else if (modelId.startsWith("amazon.titan")) {
payload.put("inputText", prompt);
payload.putIfAbsent("textGenerationConfig",
Map.of("maxTokenCount", 512, "temperature", 0.7));
}
// Add additional parameters
if (additionalParams != null) {
payload.putAll(additionalParams);
}
return payload;
}
}
```
## Advanced Error Handling
```java
@Component
public class BedrockErrorHandler {
@Retryable(value = {SdkClientException.class}, maxAttempts = 3, backoff = @Backoff(delay = 1000))
public String invokeWithRetry(BedrockRuntimeClient client, String modelId,
String payloadJson) {
try {
InvokeModelResponse response = client.invokeModel(request -> request
.modelId(modelId)
.body(SdkBytes.fromUtf8String(payloadJson)));
return response.body().asUtf8String();
} catch (ThrottlingException e) {
// Exponential backoff for throttling
throw new RuntimeException("Rate limit exceeded, please try again later", e);
} catch (ValidationException e) {
throw new IllegalArgumentException("Invalid request: " + e.getMessage(), e);
} catch (SdkException e) {
throw new RuntimeException("AWS SDK error: " + e.getMessage(), e);
}
}
}
```
## Batch Processing
```java
@Service
public class BedrockBatchService {
public List<String> processBatch(BedrockRuntimeClient client, String modelId,
List<String> prompts) {
return prompts.parallelStream()
.map(prompt -> invokeModelWithTimeout(client, modelId, prompt, 30))
.collect(Collectors.toList());
}
private String invokeModelWithTimeout(BedrockRuntimeClient client, String modelId,
String prompt, int timeoutSeconds) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(() -> {
JSONObject payload = new JSONObject()
.put("prompt", prompt)
.put("max_tokens", 500);
InvokeModelResponse response = client.invokeModel(request -> request
.modelId(modelId)
.body(SdkBytes.fromUtf8String(payload.toString())));
return response.body().asUtf8String();
});
try {
return future.get(timeoutSeconds, TimeUnit.SECONDS);
} catch (TimeoutException e) {
future.cancel(true);
throw new RuntimeException("Model invocation timed out");
} catch (Exception e) {
throw new RuntimeException("Batch processing error", e);
} finally {
executor.shutdown();
}
}
}
```
## Model Performance Optimization
```java
@Configuration
public class BedrockOptimizationConfig {
@Bean
public BedrockRuntimeClient optimizedBedrockRuntimeClient() {
return BedrockRuntimeClient.builder()
.region(Region.US_EAST_1)
.overrideConfiguration(ClientOverrideConfiguration.builder()
.apiCallTimeout(Duration.ofSeconds(30))
.apiCallAttemptTimeout(Duration.ofSeconds(20))
.build())
.httpClient(ApacheHttpClient.builder()
.connectionTimeout(Duration.ofSeconds(10))
.socketTimeout(Duration.ofSeconds(30))
.build())
.build();
}
}
```
## Custom Response Parsing
```java
public class BedrockResponseParser {
public static TextResponse parseTextResponse(String modelId, String responseBody) {
try {
switch (getModelProvider(modelId)) {
case ANTHROPIC:
return parseAnthropicResponse(responseBody);
case META:
return parseMetaResponse(responseBody);
case AMAZON:
return parseAmazonResponse(responseBody);
default:
throw new IllegalArgumentException("Unsupported model: " + modelId);
}
} catch (Exception e) {
throw new ResponseParsingException("Failed to parse response for model: " + modelId, e);
}
}
private static TextResponse parseAnthropicResponse(String responseBody) throws JSONException {
JSONObject json = new JSONObject(responseBody);
JSONArray content = json.getJSONArray("content");
String text = content.getJSONObject(0).getString("text");
int usage = json.getJSONObject("usage").getInt("input_tokens");
return new TextResponse(text, usage, "anthropic");
}
private static TextResponse parseMetaResponse(String responseBody) throws JSONException {
JSONObject json = new JSONObject(responseBody);
String text = json.getString("generation");
// Note: Meta doesn't provide token usage in basic response
return new TextResponse(text, 0, "meta");
}
private enum ModelProvider {
ANTHROPIC, META, AMAZON
}
public record TextResponse(String content, int tokensUsed, String provider) {}
}
```

View File

@@ -0,0 +1,372 @@
# Advanced Amazon Bedrock Topics
This document covers advanced patterns and topics for working with Amazon Bedrock using AWS SDK for Java 2.x.
## Multi-Model Service Pattern
Create a service that can handle multiple foundation models with unified interfaces.
```java
@Service
public class MultiModelAIService {
private final BedrockRuntimeClient bedrockRuntimeClient;
public MultiModelAIService(BedrockRuntimeClient bedrockRuntimeClient) {
this.bedrockRuntimeClient = bedrockRuntimeClient;
}
public GenerationResult generate(GenerationRequest request) {
String modelId = request.getModelId();
String prompt = request.getPrompt();
switch (getModelProvider(modelId)) {
case ANTHROPIC:
return generateWithAnthropic(modelId, prompt, request.getConfig());
case AMAZON:
return generateWithAmazon(modelId, prompt, request.getConfig());
case META:
return generateWithMeta(modelId, prompt, request.getConfig());
default:
throw new IllegalArgumentException("Unsupported model provider: " + modelId);
}
}
private GenerationProvider getModelProvider(String modelId) {
if (modelId.startsWith("anthropic.")) return GenerationProvider.ANTHROPIC;
if (modelId.startsWith("amazon.")) return GenerationProvider.AMazon;
if (modelId.startsWith("meta.")) return GenerationProvider.META;
throw new IllegalArgumentException("Unknown provider for model: " + modelId);
}
}
```
## Advanced Error Handling with Retries
Implement robust error handling with exponential backoff:
```java
import software.amazon.awssdk.core.retry.RetryPolicy;
import software.amazon.awssdk.core.retry.backoff.BackoffStrategy;
import software.amazon.awssdk.core.retry.conditions.RetryCondition;
import software.amazon.awssdk.core.retry.predicates.RetryExceptionPredicates;
public class BedrockWithRetry {
private final BedrockRuntimeClient client;
private final RetryPolicy retryPolicy;
public BedrockWithRetry(BedrockRuntimeClient client) {
this.client = client;
this.retryPolicy = RetryPolicy.builder()
.numRetries(3)
.retryCondition(RetryExceptionPredicates.equalTo(
ThrottlingException.class))
.backoffStrategy(BackoffStrategy.defaultStrategy())
.build();
}
public String invokeModelWithRetry(String modelId, String payload) {
try {
InvokeModelRequest request = InvokeModelRequest.builder()
.modelId(modelId)
.body(SdkBytes.fromUtf8String(payload))
.build();
InvokeModelResponse response = client.invokeModel(request);
return response.body().asUtf8String();
} catch (ThrottlingException e) {
throw new BedrockThrottledException("Rate limit exceeded for model: " + modelId, e);
} catch (ValidationException e) {
throw new BedrockValidationException("Invalid request for model: " + modelId, e);
}
}
}
```
## Batch Processing Strategies
Process multiple requests efficiently:
```java
@Service
public class BatchGenerationService {
private final BedrockRuntimeClient bedrockRuntimeClient;
public BatchGenerationService(BedrockRuntimeClient bedrockRuntimeClient) {
this.bedrockRuntimeClient = bedrockRuntimeClient;
}
public List<BatchResult> processBatch(List<BatchRequest> requests) {
// Process in parallel
return requests.parallelStream()
.map(this::processSingleRequest)
.collect(Collectors.toList());
}
private BatchResult processSingleRequest(BatchRequest request) {
try {
InvokeModelRequest modelRequest = InvokeModelRequest.builder()
.modelId(request.getModelId())
.body(SdkBytes.fromUtf8String(request.getPayload()))
.build();
InvokeModelResponse response = bedrockRuntimeClient.invokeModel(modelRequest);
return BatchResult.success(
request.getRequestId(),
response.body().asUtf8String()
);
} catch (Exception e) {
return BatchResult.failure(request.getRequestId(), e.getMessage());
}
}
}
```
## Performance Optimization Techniques
### Connection Pooling
```java
import software.amazon.awssdk.http.nio.apache.ApacheHttpClient;
import software.amazon.awssdk.http.apache.ProxyConfiguration;
import software.amazon.awssdk.regions.Region;
public class BedrockClientFactory {
public static BedrockRuntimeClient createOptimizedClient() {
ApacheHttpClient httpClient = ApacheHttpClient.builder()
.connectionPoolMaxConnections(50)
.socketTimeout(Duration.ofSeconds(30))
.connectionTimeout(Duration.ofSeconds(30))
.build();
return BedrockRuntimeClient.builder()
.region(Region.US_EAST_1)
.httpClient(httpClient)
.build();
}
}
```
### Response Caching
```java
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
@Service
public class CachedAIService {
private final BedrockRuntimeClient bedrockRuntimeClient;
private final Cache<String, String> responseCache;
public CachedAIService(BedrockRuntimeClient bedrockRuntimeClient) {
this.bedrockRuntimeClient = bedrockRuntimeClient;
this.responseCache = Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(1, TimeUnit.HOURS)
.build();
}
public String generateText(String prompt, String modelId) {
String cacheKey = modelId + ":" + prompt.hashCode();
return responseCache.get(cacheKey, key -> {
String payload = createPayload(modelId, prompt);
InvokeModelRequest request = InvokeModelRequest.builder()
.modelId(modelId)
.body(SdkBytes.fromUtf8String(payload))
.build();
InvokeModelResponse response = bedrockRuntimeClient.invokeModel(request);
return response.body().asUtf8String();
});
}
}
```
## Custom Response Parsing
Create specialized parsers for different model responses:
```java
public interface ResponseParser {
String parse(String responseJson);
}
public class AnthropicResponseParser implements ResponseParser {
@Override
public String parse(String responseJson) {
try {
JSONObject jsonResponse = new JSONObject(responseJson);
return jsonResponse.getJSONArray("content")
.getJSONObject(0)
.getString("text");
} catch (Exception e) {
throw new ResponseParsingException("Failed to parse Anthropic response", e);
}
}
}
public class AmazonTitanResponseParser implements ResponseParser {
@Override
public String parse(String responseJson) {
try {
JSONObject jsonResponse = new JSONObject(responseJson);
return jsonResponse.getJSONArray("results")
.getJSONObject(0)
.getString("outputText");
} catch (Exception e) {
throw new ResponseParsingException("Failed to parse Amazon Titan response", e);
}
}
}
public class LlamaResponseParser implements ResponseParser {
@Override
public String parse(String responseJson) {
try {
JSONObject jsonResponse = new JSONObject(responseJson);
return jsonResponse.getString("generation");
} catch (Exception e) {
throw new ResponseParsingException("Failed to parse Llama response", e);
}
}
}
```
## Metrics and Monitoring
Implement comprehensive monitoring:
```java
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
@Service
public class MonitoredAIService {
private final BedrockRuntimeClient bedrockRuntimeClient;
private final Timer generationTimer;
private final Counter errorCounter;
public MonitoredAIService(BedrockRuntimeClient bedrockRuntimeClient,
MeterRegistry meterRegistry) {
this.bedrockRuntimeClient = bedrockRuntimeClient;
this.generationTimer = Timer.builder("bedrock.generation.time")
.description("Time spent generating text with Bedrock")
.register(meterRegistry);
this.errorCounter = Counter.builder("bedrock.generation.errors")
.description("Number of generation errors")
.register(meterRegistry);
}
public String generateText(String prompt, String modelId) {
return generationTimer.record(() -> {
try {
String payload = createPayload(modelId, prompt);
InvokeModelRequest request = InvokeModelRequest.builder()
.modelId(modelId)
.body(SdkBytes.fromUtf8String(payload))
.build();
InvokeModelResponse response = bedrockRuntimeClient.invokeModel(request);
return response.body().asUtf8String();
} catch (Exception e) {
errorCounter.increment();
throw new GenerationException("Failed to generate text", e);
}
});
}
}
```
## Advanced Configuration Management
```java
@Configuration
@ConfigurationProperties(prefix = "bedrock")
public class AdvancedBedrockConfiguration {
private String defaultRegion = "us-east-1";
private int maxRetries = 3;
private Duration timeout = Duration.ofSeconds(30);
private boolean enableMetrics = true;
private int maxCacheSize = 1000;
private Duration cacheExpireAfter = Duration.ofHours(1);
@Bean
@Primary
public BedrockRuntimeClient bedrockRuntimeClient() {
BedrockRuntimeClient.Builder builder = BedrockRuntimeClient.builder()
.region(Region.of(defaultRegion));
if (enableMetrics) {
builder.overrideConfiguration(c -> c.putAdvancedProperty(
"metrics.enabled", "true"));
}
return builder.build();
}
// Getters and setters
}
```
## Streaming Response Handling
Advanced streaming with proper backpressure handling:
```java
@Service
public class StreamingAIService {
private final BedrockRuntimeClient bedrockRuntimeClient;
public StreamingAIService(BedrockRuntimeClient bedrockRuntimeClient) {
this.bedrockRuntimeClient = bedrockRuntimeClient;
}
public Flux<String> streamResponse(String modelId, String prompt) {
InvokeModelWithResponseStreamRequest request =
InvokeModelWithResponseStreamRequest.builder()
.modelId(modelId)
.body(SdkBytes.fromUtf8String(createPayload(modelId, prompt)))
.build();
return Mono.fromCallable(() ->
bedrockRuntimeClient.invokeModelWithResponseStream(request))
.flatMapMany(responseStream -> Flux.defer(() ->
Flux.create(sink -> {
responseStream.stream().forEach(event -> {
if (event instanceof PayloadPart) {
PayloadPart payloadPart = (PayloadPart) event;
String chunk = payloadPart.bytes().asUtf8String();
processChunk(chunk, sink);
}
});
sink.complete();
}))
)
.onErrorResume(e -> Flux.error(new StreamingException("Stream failed", e)));
}
private void processChunk(String chunk, FluxSink<String> sink) {
try {
JSONObject chunkJson = new JSONObject(chunk);
if (chunkJson.getString("type").equals("content_block_delta")) {
String text = chunkJson.getJSONObject("delta").getString("text");
sink.next(text);
}
} catch (Exception e) {
sink.error(new ChunkProcessingException("Failed to process chunk", e));
}
}
}
```

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<!DOCTYPE HTML><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Amazon Bedrock</title><meta xmlns="" name="subtitle" content="API Reference"><meta xmlns="" name="abstract" content="Details about operations and parameters in the Amazon Bedrock API Reference"><meta http-equiv="refresh" content="10;URL=welcome.html"><script type="text/javascript"><!--
var myDefaultPage = "welcome.html";
var myPage = document.location.search.substr(1);
var myHash = document.location.hash;
if (myPage == null || myPage.length == 0) {
myPage = myDefaultPage;
} else {
var docfile = myPage.match(/[^=\;\/?:\s]+\.html/);
if (docfile == null) {
myPage = myDefaultPage;
} else {
myPage = docfile + myHash;
}
}
self.location.replace(myPage);
--></script></head><body></body></html>

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<!DOCTYPE HTML><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Amazon Bedrock</title><meta xmlns="" name="subtitle" content="User Guide"><meta xmlns="" name="abstract" content="User Guide for the Amazon Bedrock service."><meta http-equiv="refresh" content="10;URL=what-is-bedrock.html"><script type="text/javascript"><!--
var myDefaultPage = "what-is-bedrock.html";
var myPage = document.location.search.substr(1);
var myHash = document.location.hash;
if (myPage == null || myPage.length == 0) {
myPage = myDefaultPage;
} else {
var docfile = myPage.match(/[^=\;\/?:\s]+\.html/);
if (docfile == null) {
myPage = myDefaultPage;
} else {
myPage = docfile + myHash;
}
}
self.location.replace(myPage);
--></script></head><body></body></html>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,148 @@
<!DOCTYPE HTML>
<html lang="en">
<head>
<!-- Generated by javadoc (23) on Tue Oct 28 00:04:26 UTC 2025 -->
<title>software.amazon.awssdk.services.bedrock (AWS SDK for Java - 2.36.3)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="dc.created" content="2025-10-28">
<meta name="description" content="declaration: package: software.amazon.awssdk.services.bedrock">
<meta name="generator" content="javadoc/PackageWriter">
<link rel="stylesheet" type="text/css" href="../../../../../resource-files/jquery-ui.min.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../../../resource-files/stylesheet.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../../../resource-files/aws-sdk-java-v2-javadoc.css" title="Style">
<script type="text/javascript" src="../../../../../script-files/script.js"></script>
<script type="text/javascript" src="../../../../../script-files/jquery-3.7.1.min.js"></script>
<script type="text/javascript" src="../../../../../script-files/jquery-ui.min.js"></script>
</head>
<body class="package-declaration-page">
<script type="text/javascript">const pathtoroot = "../../../../../";
loadScripts(document, 'script');</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<header role="banner">
<nav role="navigation">
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="top-nav" id="navbar-top">
<div class="nav-content">
<div class="nav-menu-button"><button id="navbar-toggle-button" aria-controls="navbar-top" aria-expanded="false" aria-label="Toggle navigation links"><span class="nav-bar-toggle-icon">&nbsp;</span><span class="nav-bar-toggle-icon">&nbsp;</span><span class="nav-bar-toggle-icon">&nbsp;</span></button></div>
<div class="skip-nav"><a href="#skip-navbar-top" title="Skip navigation links">Skip navigation links</a></div>
<ul id="navbar-top-firstrow" class="nav-list" title="Navigation">
<li><a href="../../../../../index.html">Overview</a></li>
<li class="nav-bar-cell1-rev">Package</li>
<li><a href="../../../../../index-all.html">Index</a></li>
<li><a href="../../../../../search.html">Search</a></li>
<li><a href="../../../../../help-doc.html#package">Help</a></li>
</ul>
<div class="about-language"><h2>AWS SDK for Java API Reference - 2.36.3</h2></div>
</div>
</div>
<div class="sub-nav">
<div class="nav-content">
<ol class="sub-nav-list">
<li><a href="package-summary.html" class="current-selection">software.amazon.awssdk.services.bedrock</a></li>
</ol>
<div class="nav-list-search">
<input type="text" id="search-input" disabled placeholder="Search" aria-label="Search in documentation" autocomplete="off">
<input type="reset" id="reset-search" disabled value="Reset">
</div>
</div>
</div>
<!-- ========= END OF TOP NAVBAR ========= -->
<span class="skip-nav" id="skip-navbar-top"></span></nav>
</header>
<div class="main-grid">
<nav role="navigation" class="toc" aria-label="Table of contents">
<div class="toc-header">Contents</div>
<button class="hide-sidebar"><span>Hide sidebar&nbsp;</span>&#10094;</button><button class="show-sidebar">&#10095;<span>&nbsp;Show sidebar</span></button>
<ol class="toc-list">
<li><a href="#" tabindex="0">Description</a></li>
<li><a href="#related-package-summary" tabindex="0">Related Packages</a></li>
<li><a href="#class-summary" tabindex="0">Classes and Interfaces</a></li>
</ol>
</nav>
<main role="main">
<div class="header">
<h1 title="Package software.amazon.awssdk.services.bedrock" class="title">Package software.amazon.awssdk.services.bedrock</h1>
</div>
<hr>
<div class="horizontal-scroll">
<div class="package-signature">package <span class="element-name">software.amazon.awssdk.services.bedrock</span></div>
<section class="package-description" id="package-description">
<div class="block"><p>
Describes the API operations for creating, managing, fine-turning, and evaluating Amazon Bedrock models.
</p></div>
</section>
</div>
<section class="summary">
<ul class="summary-list">
<li>
<div id="related-package-summary">
<div class="caption"><span>Related Packages</span></div>
<div class="summary-table two-column-summary">
<div class="table-header col-first">Package</div>
<div class="table-header col-last">Description</div>
<div class="col-first even-row-color"><a href="endpoints/package-summary.html">software.amazon.awssdk.services.bedrock.endpoints</a></div>
<div class="col-last even-row-color">&nbsp;</div>
<div class="col-first odd-row-color"><a href="internal/package-summary.html">software.amazon.awssdk.services.bedrock.internal</a></div>
<div class="col-last odd-row-color">&nbsp;</div>
<div class="col-first even-row-color"><a href="model/package-summary.html">software.amazon.awssdk.services.bedrock.model</a></div>
<div class="col-last even-row-color">&nbsp;</div>
<div class="col-first odd-row-color"><a href="paginators/package-summary.html">software.amazon.awssdk.services.bedrock.paginators</a></div>
<div class="col-last odd-row-color">&nbsp;</div>
<div class="col-first even-row-color"><a href="transform/package-summary.html">software.amazon.awssdk.services.bedrock.transform</a></div>
<div class="col-last even-row-color">&nbsp;</div>
</div>
</div>
</li>
<li>
<div id="class-summary">
<div class="table-tabs" role="tablist" aria-orientation="horizontal"><button id="class-summary-tab0" role="tab" aria-selected="true" aria-controls="class-summary.tabpanel" tabindex="0" onkeydown="switchTab(event)" onclick="show('class-summary', 'class-summary', 2)" class="active-table-tab">All Classes and Interfaces</button><button id="class-summary-tab1" role="tab" aria-selected="false" aria-controls="class-summary.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('class-summary', 'class-summary-tab1', 2)" class="table-tab">Interfaces</button><button id="class-summary-tab2" role="tab" aria-selected="false" aria-controls="class-summary.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('class-summary', 'class-summary-tab2', 2)" class="table-tab">Classes</button></div>
<div id="class-summary.tabpanel" role="tabpanel" aria-labelledby="class-summary-tab0">
<div class="summary-table two-column-summary">
<div class="table-header col-first">Class</div>
<div class="table-header col-last">Description</div>
<div class="col-first even-row-color class-summary class-summary-tab1"><a href="BedrockAsyncClient.html" title="interface in software.amazon.awssdk.services.bedrock">BedrockAsyncClient</a></div>
<div class="col-last even-row-color class-summary class-summary-tab1">
<div class="block">Service client for accessing Amazon Bedrock asynchronously.</div>
</div>
<div class="col-first odd-row-color class-summary class-summary-tab1"><a href="BedrockAsyncClientBuilder.html" title="interface in software.amazon.awssdk.services.bedrock">BedrockAsyncClientBuilder</a></div>
<div class="col-last odd-row-color class-summary class-summary-tab1">
<div class="block">A builder for creating an instance of <a href="BedrockAsyncClient.html" title="interface in software.amazon.awssdk.services.bedrock"><code>BedrockAsyncClient</code></a>.</div>
</div>
<div class="col-first even-row-color class-summary class-summary-tab1"><a href="BedrockBaseClientBuilder.html" title="interface in software.amazon.awssdk.services.bedrock">BedrockBaseClientBuilder</a>&lt;B extends <a href="BedrockBaseClientBuilder.html" title="interface in software.amazon.awssdk.services.bedrock">BedrockBaseClientBuilder</a>&lt;B,<wbr>C&gt;,<wbr>C&gt;</div>
<div class="col-last even-row-color class-summary class-summary-tab1">
<div class="block">This includes configuration specific to Amazon Bedrock that is supported by both <a href="BedrockClientBuilder.html" title="interface in software.amazon.awssdk.services.bedrock"><code>BedrockClientBuilder</code></a> and
<a href="BedrockAsyncClientBuilder.html" title="interface in software.amazon.awssdk.services.bedrock"><code>BedrockAsyncClientBuilder</code></a>.</div>
</div>
<div class="col-first odd-row-color class-summary class-summary-tab1"><a href="BedrockClient.html" title="interface in software.amazon.awssdk.services.bedrock">BedrockClient</a></div>
<div class="col-last odd-row-color class-summary class-summary-tab1">
<div class="block">Service client for accessing Amazon Bedrock.</div>
</div>
<div class="col-first even-row-color class-summary class-summary-tab1"><a href="BedrockClientBuilder.html" title="interface in software.amazon.awssdk.services.bedrock">BedrockClientBuilder</a></div>
<div class="col-last even-row-color class-summary class-summary-tab1">
<div class="block">A builder for creating an instance of <a href="BedrockClient.html" title="interface in software.amazon.awssdk.services.bedrock"><code>BedrockClient</code></a>.</div>
</div>
<div class="col-first odd-row-color class-summary class-summary-tab2"><a href="BedrockServiceClientConfiguration.html" title="class in software.amazon.awssdk.services.bedrock">BedrockServiceClientConfiguration</a></div>
<div class="col-last odd-row-color class-summary class-summary-tab2">
<div class="block">Class to expose the service client settings to the user.</div>
</div>
<div class="col-first even-row-color class-summary class-summary-tab1"><a href="BedrockServiceClientConfiguration.Builder.html" title="interface in software.amazon.awssdk.services.bedrock">BedrockServiceClientConfiguration.Builder</a></div>
<div class="col-last even-row-color class-summary class-summary-tab1">
<div class="block">A builder for creating a <a href="BedrockServiceClientConfiguration.html" title="class in software.amazon.awssdk.services.bedrock"><code>BedrockServiceClientConfiguration</code></a></div>
</div>
</div>
</div>
</div>
</li>
</ul>
</section>
<footer role="contentinfo">
<hr>
<p class="legal-copy"><small><div style="margin:1.2em;"><h3><a id="fdbk" target="_blank">Provide feedback</a><h3></div> <span id="awsdocs-legal-zone-copyright"></span> <script type="text/javascript">document.addEventListener("DOMContentLoaded",()=>{ var a=document.createElement("meta"),b=document.createElement("meta"),c=document.createElement("script"), h=document.getElementsByTagName("head")[0],l=location.href,f=document.getElementById("fdbk"); a.name="guide-name",a.content="API Reference";b.name="service-name",b.content="AWS SDK for Java"; c.setAttribute("type","text/javascript"),c.setAttribute("src", "https://docs.aws.amazon.com/assets/js/awsdocs-boot.js");h.appendChild(a);h.appendChild(b); h.appendChild(c);f.setAttribute("href", "https://docs-feedback.aws.amazon.com/feedback.jsp?hidden_service_name="+ encodeURI("AWS SDK for Java")+"&topic_url="+encodeURI(l))}); </script></small></p>
</footer>
</main>
</div>
</body>
</html>

View File

@@ -0,0 +1,340 @@
# Model Reference
## Supported Foundation Models
### Amazon Models
#### Amazon Titan Text
**Model ID:** `amazon.titan-text-express-v1`
- **Description:** High-quality text generation model
- **Context Window:** Up to 8K tokens
- **Languages:** English, Spanish, French, German, Italian, Portuguese
**Payload Format:**
```json
{
"inputText": "Your prompt here",
"textGenerationConfig": {
"maxTokenCount": 512,
"temperature": 0.7,
"topP": 0.9
}
}
```
**Response Format:**
```json
{
"results": [{
"outputText": "Generated text"
}]
}
```
#### Amazon Titan Text Lite
**Model ID:** `amazon.titan-text-lite-v1`
- **Description:** Cost-effective text generation model
- **Context Window:** Up to 4K tokens
- **Use Case:** Simple text generation tasks
#### Amazon Titan Embeddings
**Model ID:** `amazon.titan-embed-text-v1`
- **Description:** High-quality text embeddings
- **Context Window:** 8K tokens
- **Output:** 1024-dimensional vector
**Payload Format:**
```json
{
"inputText": "Your text here"
}
```
**Response Format:**
```json
{
"embedding": [0.1, -0.2, 0.3, ...]
}
```
#### Amazon Titan Image Generator
**Model ID:** `amazon.titan-image-generator-v1`
- **Description:** High-quality image generation
- **Image Size:** 512x512, 1024x1024
- **Use Case:** Text-to-image generation
**Payload Format:**
```json
{
"taskType": "TEXT_IMAGE",
"textToImageParams": {
"text": "Your description"
},
"imageGenerationConfig": {
"numberOfImages": 1,
"quality": "standard",
"cfgScale": 8.0,
"height": 512,
"width": 512,
"seed": 12345
}
}
```
### Anthropic Models
#### Claude 3.5 Sonnet
**Model ID:** `anthropic.claude-3-5-sonnet-20241022-v2:0`
- **Description:** High-performance model for complex reasoning, analysis, and creative tasks
- **Context Window:** 200K tokens
- **Languages:** Multiple languages supported
- **Use Case:** Code generation, complex analysis, creative writing, research
- **Features:** Tool use, function calling, JSON mode
**Payload Format:**
```json
{
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 1000,
"messages": [{
"role": "user",
"content": "Your message"
}]
}
```
**Response Format:**
```json
{
"content": [{
"text": "Response content"
}],
"usage": {
"input_tokens": 10,
"output_tokens": 20
}
}
```
#### Claude 3.5 Haiku
**Model ID:** `anthropic.claude-3-5-haiku-20241022-v2:0`
- **Description:** Fast and affordable model for real-time applications
- **Context Window:** 200K tokens
- **Use Case:** Real-time applications, chatbots, quick responses
- **Features:** Tool use, function calling, JSON mode
#### Claude 3 Opus
**Model ID:** `anthropic.claude-3-opus-20240229-v1:0`
- **Description:** Most capable model
- **Context Window:** 200K tokens
- **Use Case:** Complex reasoning, analysis
#### Claude 3 Sonnet (Legacy)
**Model ID:** `anthropic.claude-3-sonnet-20240229-v1:0`
- **Description:** Previous generation model
- **Context Window:** 200K tokens
- **Use Case:** General purpose applications
### Meta Models
#### Llama 3.1 70B
**Model ID:** `meta.llama3-1-70b-instruct-v1:0`
- **Description:** Latest generation large open-source model
- **Context Window:** 128K tokens
- **Use Case:** General purpose instruction following, complex reasoning
- **Features:** Improved instruction following, larger context window
#### Llama 3.1 8B
**Model ID:** `meta.llama3-1-8b-instruct-v1:0`
- **Description:** Latest generation small fast model
- **Context Window:** 8K tokens
- **Use Case:** Fast inference, lightweight applications
#### Llama 3 70B
**Model ID:** `meta.llama3-70b-instruct-v1:0`
- **Description:** Previous generation large open-source model
- **Context Window:** 8K tokens
- **Use Case:** General purpose instruction following
**Payload Format:**
```json
{
"prompt": "[INST] Your prompt here [/INST]",
"max_gen_len": 512,
"temperature": 0.7,
"top_p": 0.9
}
```
**Response Format:**
```json
{
"generation": "Generated text"
}
```
#### Llama 3 8B
**Model ID:** `meta.llama3-8b-instruct-v1:0`
- **Description:** Smaller, faster version
- **Context Window:** 8K tokens
- **Use Case:** Fast inference, lightweight applications
### Stability AI Models
#### Stable Diffusion XL
**Model ID:** `stability.stable-diffusion-xl-v1`
- **Description:** High-quality image generation
- **Image Size:** Up to 1024x1024
- **Use Case:** Text-to-image generation, art creation
**Payload Format:**
```json
{
"text_prompts": [{
"text": "Your description"
}],
"style_preset": "photographic",
"seed": 12345,
"cfg_scale": 10,
"steps": 50
}
```
**Response Format:**
```json
{
"artifacts": [{
"base64": "base64-encoded-image-data",
"finishReason": "SUCCESS"
}]
}
```
### Other Models
#### Cohere Command
**Model ID:** `cohere.command-text-v14`
- **Description:** Text generation model
- **Context Window:** 128K tokens
- **Use Case:** Content generation, summarization
#### Mistral Models
**Model ID:** `mistral.mistral-7b-instruct-v0:2`
- **Description:** High-performing open-source model
- **Context Window:** 32K tokens
- **Use Case:** Instruction following, code generation
**Model ID:** `mistral.mixtral-8x7b-instruct-v0:1`
- **Description:** Mixture of experts model
- **Context Window:** 32K tokens
- **Use Case:** Complex reasoning tasks
## Model Selection Guide
### Use Case Recommendations
| Use Case | Recommended Models | Notes |
|----------|-------------------|-------|
| **General Chat/Chatbots** | Claude 3.5 Haiku, Llama 3 8B | Fast response times |
| **Content Creation** | Claude 3.5 Sonnet, Cohere | Creative, coherent outputs |
| **Code Generation** | Claude 3.5 Sonnet, Llama 3.1 70B | Excellent understanding |
| **Analysis & Reasoning** | Claude 3 Opus, Claude 3.5 Sonnet | Complex reasoning |
| **Real-time Applications** | Claude 3.5 Haiku, Titan Lite | Fast inference |
| **Cost-sensitive Apps** | Titan Lite, Claude 3.5 Haiku | Lower cost per token |
| **High Quality** | Claude 3 Opus, Claude 3.5 Sonnet | Premium quality |
### Performance Characteristics
| Model | Speed | Cost | Quality | Context Window |
|-------|-------|------|---------|----------------|
| Claude 3 Opus | Slow | High | Excellent | 200K |
| Claude 3.5 Sonnet | Medium | Medium | Excellent | 200K |
| Claude 3.5 Haiku | Fast | Low | Good | 200K |
| Claude 3 Sonnet (Legacy) | Medium | Medium | Good | 200K |
| Llama 3.1 70B | Medium | Medium | Good | 128K |
| Llama 3.1 8B | Fast | Low | Fair | 8K |
| Llama 3 70B | Medium | Medium | Good | 8K |
| Llama 3 8B | Fast | Low | Fair | 8K |
| Titan Express | Fast | Medium | Good | 8K |
| Titan Lite | Fast | Low | Fair | 4K |
## Model Comparison Matrix
| Feature | Claude 3 | Llama 3 | Titan | Stability |
|---------|----------|---------|-------|-----------|
| **Streaming** | ✅ | ✅ | ✅ | ❌ |
| **Tool Use** | ✅ | ❌ | ❌ | ❌ |
| **Image Generation** | ❌ | ❌ | ✅ | ✅ |
| **Embeddings** | ❌ | ❌ | ✅ | ❌ |
| **Multiple Languages** | ✅ | ✅ | ✅ | ✅ |
| **Context Window** | 200K | 8K | 8K | N/A |
| **Open Source** | ❌ | ✅ | ❌ | ✅ |
## Model Configuration Templates
### Text Generation Template
```java
private static JSONObject createTextGenerationPayload(String modelId, String prompt) {
JSONObject payload = new JSONObject();
if (modelId.startsWith("anthropic.claude")) {
payload.put("anthropic_version", "bedrock-2023-05-31");
payload.put("max_tokens", 1000);
payload.put("messages", new JSONObject[]{new JSONObject()
.put("role", "user")
.put("content", prompt)
});
} else if (modelId.startsWith("meta.llama")) {
payload.put("prompt", "[INST] " + prompt + " [/INST]");
payload.put("max_gen_len", 512);
} else if (modelId.startsWith("amazon.titan")) {
payload.put("inputText", prompt);
payload.put("textGenerationConfig", new JSONObject()
.put("maxTokenCount", 512)
.put("temperature", 0.7)
);
}
return payload;
}
```
### Image Generation Template
```java
private static JSONObject createImageGenerationPayload(String modelId, String prompt) {
JSONObject payload = new JSONObject();
if (modelId.equals("amazon.titan-image-generator-v1")) {
payload.put("taskType", "TEXT_IMAGE");
payload.put("textToImageParams", new JSONObject().put("text", prompt));
payload.put("imageGenerationConfig", new JSONObject()
.put("numberOfImages", 1)
.put("quality", "standard")
.put("height", 512)
.put("width", 512)
);
} else if (modelId.equals("stability.stable-diffusion-xl-v1")) {
payload.put("text_prompts", new JSONObject[]{new JSONObject().put("text", prompt)});
payload.put("style_preset", "photographic");
payload.put("steps", 50);
payload.put("cfg_scale", 10);
}
return payload;
}
```

View File

@@ -0,0 +1,121 @@
# Model ID Lookup Guide
This document provides quick lookup for the most commonly used model IDs in Amazon Bedrock.
## Text Generation Models
### Claude (Anthropic)
| Model | Model ID | Description | Use Case |
|-------|----------|-------------|----------|
| Claude 4.5 Sonnet | `anthropic.claude-sonnet-4-5-20250929-v1:0` | Latest high-performance model | Complex reasoning, coding, creative tasks |
| Claude 4.5 Haiku | `anthropic.claude-haiku-4-5-20251001-v1:0` | Latest fast model | Real-time applications, chatbots |
| Claude 3.7 Sonnet | `anthropic.claude-3-7-sonnet-20250219-v1:0` | Most advanced reasoning | High-stakes decisions, complex analysis |
| Claude Opus 4.1 | `anthropic.claude-opus-4-1-20250805-v1:0` | Most powerful creative | Advanced creative tasks |
| Claude 3.5 Sonnet v2 | `anthropic.claude-3-5-sonnet-20241022-v2:0` | High-performance model | General use, coding |
| Claude 3.5 Haiku | `anthropic.claude-3-5-haiku-20241022-v1:0` | Fast and affordable | Real-time applications |
### Llama (Meta)
| Model | Model ID | Description | Use Case |
|-------|----------|-------------|----------|
| Llama 3.3 70B | `meta.llama3-3-70b-instruct-v1:0` | Latest generation | Complex reasoning, general use |
| Llama 3.2 90B | `meta.llama3-2-90b-instruct-v1:0` | Large context | Long context tasks |
| Llama 3.2 11B | `meta.llama3-2-11b-instruct-v1:0` | Medium model | Balanced performance |
| Llama 3.2 3B | `meta.llama3-2-3b-instruct-v1:0` | Small model | Fast inference |
| Llama 3.2 1B | `meta.llama3-2-1b-instruct-v1:0` | Ultra-fast | Quick responses |
| Llama 3.1 70B | `meta.llama3-1-70b-instruct-v1:0` | Previous gen | General use |
| Llama 3.1 8B | `meta.llama3-1-8b-instruct-v1:0` | Fast small model | Lightweight applications |
### Mistral AI
| Model | Model ID | Description | Use Case |
|-------|----------|-------------|----------|
| Mistral Large 2407 | `mistral.mistral-large-2407-v1:0` | Latest large model | Complex reasoning |
| Mistral Large 2402 | `mistral.mistral-large-2402-v1:0` | Previous large model | General use |
| Mistral Pixtral 2502 | `mistral.pixtral-large-2502-v1:0` | Multimodal | Text + image understanding |
| Mistral 7B | `mistral.mistral-7b-instruct-v0:2` | Small fast model | Quick responses |
### Amazon
| Model | Model ID | Description | Use Case |
|-------|----------|-------------|----------|
| Titan Text Express | `amazon.titan-text-express-v1` | Fast text generation | Quick responses |
| Titan Text Lite | `amazon.titan-text-lite-v1` | Cost-effective | Budget-sensitive apps |
| Titan Embeddings | `amazon.titan-embed-text-v1` | Text embeddings | Semantic search |
### Cohere
| Model | Model ID | Description | Use Case |
|-------|----------|-------------|----------|
| Command R+ | `cohere.command-r-plus-v1:0` | High performance | Complex tasks |
| Command R | `cohere.command-r-v1:0` | General purpose | Standard use cases |
## Image Generation Models
### Stability AI
| Model | Model ID | Description | Use Case |
|-------|----------|-------------|----------|
| Stable Diffusion 3.5 Large | `stability.sd3-5-large-v1:0` | Latest image gen | High-quality images |
| Stable Diffusion XL | `stability.stable-diffusion-xl-v1` | Previous generation | General image generation |
### Amazon Nova
| Model | Model ID | Description | Use Case |
|-------|----------|-------------|----------|
| Nova Canvas | `amazon.nova-canvas-v1:0` | Image generation | Creative images |
| Nova Reel | `amazon.nova-reel-v1:1` | Video generation | Video content |
## Embedding Models
### Amazon
| Model | Model ID | Description | Use Case |
|-------|----------|-------------|----------|
| Titan Embeddings | `amazon.titan-embed-text-v1` | Text embeddings | Semantic search |
| Titan Embeddings V2 | `amazon.titan-embed-text-v2:0` | Improved embeddings | Better accuracy |
### Cohere
| Model | Model ID | Description | Use Case |
|-------|----------|-------------|----------|
| Embed English | `cohere.embed-english-v3` | English embeddings | English content |
| Embed Multilingual | `cohere.embed-multilingual-v3` | Multi-language | International use |
## Selection Guide
### By Speed
1. **Fastest**: Llama 3.2 1B, Claude 4.5 Haiku, Titan Lite
2. **Fast**: Mistral 7B, Llama 3.2 3B
3. **Medium**: Claude 3.5 Sonnet, Llama 3.2 11B
4. **Slow**: Claude 4.5 Sonnet, Llama 3.3 70B
### By Quality
1. **Highest**: Claude 4.5 Sonnet, Claude 3.7 Sonnet, Claude Opus 4.1
2. **High**: Claude 3.5 Sonnet, Llama 3.3 70B
3. **Medium**: Mistral Large, Llama 3.2 11B
4. **Basic**: Mistral 7B, Llama 3.2 3B
### By Cost
1. **Most Affordable**: Claude 4.5 Haiku, Llama 3.2 1B
2. **Affordable**: Mistral 7B, Titan Lite
3. **Medium**: Claude 3.5 Haiku, Llama 3.2 3B
4. **Expensive**: Claude 4.5 Sonnet, Llama 3.3 70B
## Common Patterns
### Default Model Selection
```java
// For most applications
String DEFAULT_MODEL = "anthropic.claude-sonnet-4-5-20250929-v1:0";
// For real-time applications
String FAST_MODEL = "anthropic.claude-haiku-4-5-20251001-v1:0";
// For budget-sensitive applications
String CHEAP_MODEL = "amazon.titan-text-lite-v1";
// For complex reasoning
String POWERFUL_MODEL = "anthropic.claude-3-7-sonnet-20250219-v1:0";
```
### Model Fallback Chain
```java
private static final String[] MODEL_CHAIN = {
"anthropic.claude-sonnet-4-5-20250929-v1:0", // Primary
"anthropic.claude-haiku-4-5-20251001-v1:0", // Fast fallback
"amazon.titan-text-lite-v1" // Cheap fallback
};
```

View File

@@ -0,0 +1,365 @@
# Testing Strategies
## Unit Testing
### Mocking Bedrock Clients
```java
@ExtendWith(MockitoExtension.class)
class BedrockServiceTest {
@Mock
private BedrockRuntimeClient bedrockRuntimeClient;
@InjectMocks
private BedrockAIService aiService;
@Test
void shouldGenerateTextWithClaude() {
// Arrange
String modelId = "anthropic.claude-3-sonnet-20240229-v1:0";
String prompt = "Hello, world!";
String expectedResponse = "Hello! How can I help you today?";
InvokeModelResponse mockResponse = InvokeModelResponse.builder()
.body(SdkBytes.fromUtf8String(
"{\"content\":[{\"text\":\"" + expectedResponse + "\"}]}"))
.build();
when(bedrockRuntimeClient.invokeModel(any(InvokeModelRequest.class)))
.thenReturn(mockResponse);
// Act
String result = aiService.generateText(prompt, modelId);
// Assert
assertThat(result).isEqualTo(expectedResponse);
verify(bedrockRuntimeClient).invokeModel(argThat(request ->
request.modelId().equals(modelId)));
}
@Test
void shouldHandleThrottling() {
// Arrange
when(bedrockRuntimeClient.invokeModel(any(InvokeModelRequest.class)))
.thenThrow(ThrottlingException.builder()
.message("Rate limit exceeded")
.build());
// Act & Assert
assertThatThrownBy(() -> aiService.generateText("test"))
.isInstanceOf(RuntimeException.class)
.hasMessageContaining("Rate limit exceeded");
}
}
```
### Testing Error Conditions
```java
@Test
void shouldHandleInvalidModelId() {
String invalidModelId = "invalid.model.id";
String prompt = "test";
when(bedrockRuntimeClient.invokeModel(any(InvokeModelRequest.class)))
.thenThrow(ValidationException.builder()
.message("Invalid model identifier")
.build());
assertThatThrownBy(() -> aiService.generateText(prompt, invalidModelId))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Invalid model identifier");
}
```
### Testing Multiple Models
```java
@ParameterizedTest
@EnumSource(ModelProvider.class)
void shouldSupportAllModels(ModelProvider modelProvider) {
String prompt = "Hello";
String modelId = modelProvider.getModelId();
String expectedResponse = "Response";
InvokeModelResponse mockResponse = InvokeModelResponse.builder()
.body(SdkBytes.fromUtf8String(createMockResponse(modelProvider, expectedResponse)))
.build();
when(bedrockRuntimeClient.invokeModel(any(InvokeModelRequest.class)))
.thenReturn(mockResponse);
String result = aiService.generateText(prompt, modelId);
assertThat(result).isEqualTo(expectedResponse);
}
private enum ModelProvider {
CLAUDE("anthropic.claude-3-sonnet-20240229-v1:0"),
LLAMA("meta.llama3-70b-instruct-v1:0"),
TITAN("amazon.titan-text-express-v1");
private final String modelId;
ModelProvider(String modelId) {
this.modelId = modelId;
}
public String getModelId() {
return modelId;
}
}
```
## Integration Testing
### Testcontainers Integration
```java
@Testcontainers
@SpringBootTest(classes = BedrockConfiguration.class)
@ActiveProfiles("test")
class BedrockIntegrationTest {
@Container
static LocalStackContainer localStack = new LocalStackContainer(
DockerImageName.parse("localstack/localstack:latest"))
.withServices(AWSService BEDROCK_RUNTIME)
.withEnv("DEFAULT_REGION", "us-east-1");
@Autowired
private BedrockRuntimeClient bedrockRuntimeClient;
@Test
void shouldConnectToLocalStack() {
assertThat(bedrockRuntimeClient).isNotNull();
}
@Test
void shouldListFoundationModels() {
ListFoundationModelsResponse response =
bedrockRuntimeClient.listFoundationModels();
assertThat(response.modelSummaries()).isNotEmpty();
}
}
```
### LocalStack Configuration
```java
@Configuration
public class LocalStackConfig {
@Value("${localstack.enabled:true}")
private boolean localStackEnabled;
@Bean
@ConditionalOnProperty(name = "localstack.enabled", havingValue = "true")
public AwsCredentialsProvider localStackCredentialsProvider() {
return StaticCredentialsProvider.create(
new AwsBasicCredentialsAccessKey("test", "test"));
}
@Bean
@ConditionalOnProperty(name = "localstack.enabled", havingValue = "true")
public BedrockRuntimeClient localStackBedrockRuntimeClient(
AwsCredentialsProvider credentialsProvider) {
return BedrockRuntimeClient.builder()
.credentialsProvider(credentialsProvider)
.endpointOverride(localStack.getEndpoint())
.region(Region.US_EAST_1)
.build();
}
}
```
### Performance Testing
```java
@Test
void shouldPerformWithinTimeLimit() {
String prompt = "Performance test prompt";
int iterationCount = 100;
long startTime = System.currentTimeMillis();
for (int i = 0; i < iterationCount; i++) {
InvokeModelResponse response = bedrockRuntimeClient.invokeModel(
request -> request
.modelId("anthropic.claude-3-sonnet-20240229-v1:0")
.body(SdkBytes.fromUtf8String(createPayload(prompt))));
}
long duration = System.currentTimeMillis() - startTime;
double avgTimePerRequest = (double) duration / iterationCount;
assertThat(avgTimePerRequest).isLessThan(5000); // Less than 5 seconds per request
System.out.println("Average response time: " + avgTimePerRequest + "ms");
}
```
## Testing Streaming Responses
### Streaming Handler Testing
```java
@Test
void shouldStreamResponse() throws InterruptedException {
String prompt = "Stream this response";
MockStreamHandler mockHandler = new MockStreamHandler();
InvokeModelWithResponseStreamRequest streamRequest =
InvokeModelWithResponseStreamRequest.builder()
.modelId("anthropic.claude-3-sonnet-20240229-v1:0")
.body(SdkBytes.fromUtf8String(createPayload(prompt)))
.build();
bedrockRuntimeClient.invokeModelWithResponseStream(streamRequest, mockHandler);
// Wait for streaming to complete
mockHandler.awaitCompletion(10, TimeUnit.SECONDS);
assertThat(mockHandler.getStreamedContent()).isNotEmpty();
assertThat(mockHandler.getStreamedContent()).contains(" streamed");
}
private static class MockStreamHandler extends
InvokeModelWithResponseStreamResponseHandler.Visitor {
private final StringBuilder contentBuilder = new StringBuilder();
private final CountDownLatch latch = new CountDownLatch(1);
@Override
public void visit(EventStream eventStream) {
eventStream.forEach(event -> {
if (event instanceof PayloadPart) {
PayloadPart payloadPart = (PayloadPart) event;
String chunk = payloadPart.bytes().asUtf8String();
contentBuilder.append(chunk);
}
});
latch.countDown();
}
public String getStreamedContent() {
return contentBuilder.toString();
}
public void awaitCompletion(long timeout, TimeUnit unit)
throws InterruptedException {
latch.await(timeout, unit);
}
}
```
## Testing Configuration
### Testing Different Regions
```java
@ParameterizedTest
@EnumSource(value = Region.class,
names = {"US_EAST_1", "US_WEST_2", "EU_WEST_1"})
void shouldWorkInAllRegions(Region region) {
BedrockRuntimeClient client = BedrockRuntimeClient.builder()
.region(region)
.build();
assertThat(client).isNotNull();
}
### Testing Authentication
```java
@Test
void shouldUseIamRoleForAuthentication() {
BedrockRuntimeClient client = BedrockRuntimeClient.builder()
.region(Region.US_EAST_1)
.build();
// Test that client can make basic calls
ListFoundationModelsResponse response = client.listFoundationModels();
assertThat(response).isNotNull();
}
```
## Test Data Management
### Test Response Fixtures
```java
public class BedrockTestFixtures {
public static String createClaudeResponse() {
return "{\"content\":[{\"text\":\"Hello! How can I help you today?\"}]}";
}
public static String createLlamaResponse() {
return "{\"generation\":\"Hello! How can I assist you?\"}";
}
public static String createTitanResponse() {
return "{\"results\":[{\"outputText\":\"Hello! How can I help?\"}]}";
}
public static String createPayload(String prompt) {
return new JSONObject()
.put("anthropic_version", "bedrock-2023-05-31")
.put("max_tokens", 1000)
.put("messages", new JSONObject[]{
new JSONObject()
.put("role", "user")
.put("content", prompt)
})
.toString();
}
}
```
### Integration Test Suite
```java
@Suite
@SelectClasses({
BedrockAIServiceTest.class,
BedrockConfigurationTest.class,
BedrockStreamingTest.class,
BedrockErrorHandlingTest.class
})
public class BedrockTestSuite {
// Integration test suite for all Bedrock functionality
}
```
## Testing Guidelines
### Unit Testing Best Practices
1. **Mock External Dependencies:** Always mock AWS SDK clients in unit tests
2. **Test Error Scenarios:** Include tests for throttling, validation errors, and network issues
3. **Parameterized Tests:** Test multiple models and configurations efficiently
4. **Performance Assertions:** Include basic performance benchmarks
5. **Test Data Fixtures:** Reuse test response data across tests
### Integration Testing Best Practices
1. **Use LocalStack:** Test against LocalStack for local development
2. **Test Multiple Regions:** Verify functionality across different AWS regions
3. **Test Edge Cases:** Include timeout, retry, and concurrent request scenarios
4. **Monitor Performance:** Track response times and error rates
5. **Clean Up Resources:** Ensure proper cleanup after integration tests
### Testing Configuration
```properties
# application-test.properties
localstack.enabled=true
aws.region=us-east-1
bedrock.timeout=5000
bedrock.retry.max-attempts=3
```