Initial commit
This commit is contained in:
@@ -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