Initial commit
This commit is contained in:
377
skills/aws-java/aws-sdk-java-v2-bedrock/SKILL.md
Normal file
377
skills/aws-java/aws-sdk-java-v2-bedrock/SKILL.md
Normal 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)
|
||||
249
skills/aws-java/aws-sdk-java-v2-bedrock/bedrock_code_examples.md
Normal file
249
skills/aws-java/aws-sdk-java-v2-bedrock/bedrock_code_examples.md
Normal 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.
|
||||
1323
skills/aws-java/aws-sdk-java-v2-bedrock/bedrock_models_supported.md
Normal file
1323
skills/aws-java/aws-sdk-java-v2-bedrock/bedrock_models_supported.md
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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) {}
|
||||
}
|
||||
```
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -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>
|
||||
@@ -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
@@ -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"> </span><span class="nav-bar-toggle-icon"> </span><span class="nav-bar-toggle-icon"> </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 </span>❮</button><button class="show-sidebar">❯<span> 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"> </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"> </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"> </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"> </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"> </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><B extends <a href="BedrockBaseClientBuilder.html" title="interface in software.amazon.awssdk.services.bedrock">BedrockBaseClientBuilder</a><B,<wbr>C>,<wbr>C></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>
|
||||
@@ -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;
|
||||
}
|
||||
```
|
||||
@@ -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
|
||||
};
|
||||
```
|
||||
@@ -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
|
||||
```
|
||||
Reference in New Issue
Block a user