Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Provides Amazon Bedrock patterns using AWS SDK for Java 2.x. Invokes foundation models (Claude, Llama, Titan), generates text and images, creates embeddings for RAG, streams real-time responses, and configures Spring Boot integration. Use when asking about Bedrock integration, Java SDK for AI models, AWS generative AI, Claude/Llama invocation, embeddings for RAG, or Spring Boot AI setup.
.claude/skills/giuseppe-trisciuoglio-aws-sdk-java-v2-bedrock/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 73% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 134% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 100% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 143% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 91% | 0% |
Invokes foundation models through AWS SDK for Java 2.x. Configures clients, builds model-specific JSON payloads, handles streaming responses with error recovery, creates embeddings for RAG, integrates generative AI into Spring Boot applications, and implements exponential backoff for resilience.
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>
javaimport 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();
Follow these steps for production-ready Bedrock integration:
BedrockClient and BedrockRuntimeClient instancesValidation Checkpoint: Always test with a simple prompt (e.g., "Hello") before production use to verify model access and response parsing.
javapublic String generateWithClaude(BedrockRuntimeClient client, String prompt) { JSONObject payload = 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) }); InvokeModelResponse response = client.invokeModel(InvokeModelRequest.builder() .modelId("anthropic.claude-sonnet-4-5-20250929-v1:0") .body(SdkBytes.fromUtf8String(payload.toString())) .build()); JSONObject responseBody = new JSONObject(response.body().asUtf8String()); return responseBody.getJSONArray("content") .getJSONObject(0) .getString("text"); }
javaimport software.amazon.awssdk.services.bedrock.model.*; public List<FoundationModelSummary> listFoundationModels(BedrockClient bedrockClient) { return bedrockClient.listFoundationModels().modelSummaries(); }
javapublic 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); }
javapublic String streamResponseWithRetry(BedrockRuntimeClient client, String modelId, String prompt, int maxRetries) { int attempt = 0; while (attempt < maxRetries) { try { JSONObject payload = createPayload(modelId, prompt); StringBuilder fullResponse = new StringBuilder(); InvokeModelWithResponseStreamRequest request = InvokeModelWithResponseStreamRequest.builder() .modelId(modelId) .body(SdkBytes.fromUtf8String(payload.toString())) .build(); client.invokeModelWithResponseStream(request, InvokeModelWithResponseStreamResponseHandler.builder() .onEventStream(stream -> stream.forEach(event -> { if (event instanceof PayloadPart) { String chunk = ((PayloadPart) event).bytes().asUtf8String(); fullResponse.append(chunk); } })) .onError(e -> System.err.println("Stream error: " + e.getMessage())) .build()); return fullResponse.toString(); } catch (Exception e) { attempt++; if (attempt >= maxRetries) { throw new RuntimeException("Stream failed after " + maxRetries + " attempts", e); } try { Thread.sleep((long) Math.pow(2, attempt) * 1000); // Exponential backoff } catch (InterruptedException ie) { Thread.currentThread().interrupt(); throw new RuntimeException("Interrupted during retry", ie); } } } throw new RuntimeException("Unexpected error in streaming"); }
javaimport software.amazon.awssdk.awscore.exception.AwsServiceException; public <T> T invokeWithRetry(Supplier<T> invocation, int maxRetries) { int attempt = 0; while (attempt < maxRetries) { try { return invocation.get(); } catch (AwsServiceException e) { if (e.statusCode() == 429 || e.statusCode() >= 500) { attempt++; if (attempt >= maxRetries) throw e; long delayMs = Math.min(1000 * (1L << attempt) + (long) (Math.random() * 1000), 30000); Thread.sleep(delayMs); } else { throw e; } } } throw new IllegalStateException("Should not reach here"); }
javapublic 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; }
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; private final ObjectMapper mapper; @Value("${bedrock.default-model-id:anthropic.claude-sonnet-4-5-20250929-v1:0}") private String defaultModelId; public BedrockAIService(BedrockRuntimeClient bedrockRuntimeClient, ObjectMapper mapper) { this.bedrockRuntimeClient = bedrockRuntimeClient; this.mapper = mapper; } public String generateText(String prompt) { Map<String, Object> payload = Map.of( "anthropic_version", "bedrock-2023-05-31", "max_tokens", 1000, "messages", List.of(Map.of("role", "user", "content", prompt)) ); InvokeModelResponse response = bedrockRuntimeClient.invokeModel( InvokeModelRequest.builder() .modelId(defaultModelId) .body(SdkBytes.fromUtf8String(mapper.writeValueAsString(payload))) .build()); return extractText(response.body().asUtf8String()); } }
See examples directory for comprehensive usage patterns.
anthropic.claude-sonnet-4-5-20250929-v1:0anthropic.claude-haiku-4-5-20251001-v1:0meta.llama3-1-70b-instruct-v1:0amazon.titan-embed-text-v1See Model Reference for complete list.
aws-sdk-java-v2-core - Core AWS SDK patternslangchain4j-ai-services-patterns - LangChain4j integrationspring-boot-dependency-injection - Spring DI patterns| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 17,515 | 14,737 | -16% | 1 | 1 | 0% | 3,622 | 6,256 | +73% | 0 | 0 | — |
case-02 | fail→pass | 9,096 | 5,567 | -39% | 1 | 1 | 0% | 1,798 | 4,208 | +134% | 0 | 0 | — |
case-08 | fail→fail | 15,367 | 19,222 | +25% | 1 | 1 | 0% | 2,997 | 5,783 | +93% | 0 | 0 | — |
case-18 | pass→pass | 9,032 | 7,193 | -20% | 1 | 1 | 0% | 1,789 | 4,743 | +165% | 0 | 0 | — |
case-03 | pass→pass | 13,864 | 13,323 | -4% | 1 | 1 | 0% | 2,975 | 5,958 | +100% | 0 | 0 | — |
case-04 | pass→pass | 12,565 | 8,336 | -34% | 1 | 1 | 0% | 2,588 | 4,922 | +90% | 0 | 0 | — |
case-05 | fail→fail | 13,063 | 12,863 | -2% | 1 | 1 | 0% | 2,704 | 5,747 | +113% | 0 | 0 | — |
case-06 | fail→fail | 13,158 | 9,834 | -25% | 1 | 1 | 0% | 2,672 | 5,109 | +91% | 0 | 0 | — |
case-07 | pass→pass | 8,056 | 7,491 | -7% | 1 | 1 | 0% | 1,599 | 4,647 | +191% | 0 | 0 | — |
case-09 | fail→pass | 15,973 | 15,435 | -3% | 1 | 1 | 0% | 3,084 | 6,162 | +100% | 0 | 0 | — |
case-10 | pass→pass | 17,145 | 14,267 | -17% | 1 | 1 | 0% | 3,545 | 6,146 | +73% | 0 | 0 | — |
case-11 | fail→pass | 7,632 | 2,780 | -64% | 1 | 1 | 0% | 1,485 | 3,604 | +143% | 0 | 0 | — |
case-12 | fail→pass | 10,617 | 3,539 | -67% | 1 | 1 | 0% | 2,005 | 3,828 | +91% | 0 | 0 | — |
case-13 | pass→pass | 6,157 | 2,075 | -66% | 1 | 1 | 0% | 1,253 | 3,427 | +174% | 0 | 0 | — |
case-14 | pass→fail | 16,442 | 18,348 | +12% | 1 | 1 | 0% | 3,187 | 6,940 | +118% | 0 | 0 | — |
case-15 | pass→pass | 13,075 | 14,785 | +13% | 1 | 1 | 0% | 2,300 | 6,024 | +162% | 0 | 0 | — |
case-16 | pass→pass | 15,576 | 10,947 | -30% | 1 | 1 | 0% | 2,742 | 4,986 | +82% | 0 | 0 | — |
case-17 | pass→pass | 13,022 | 11,515 | -12% | 1 | 1 | 0% | 2,413 | 5,362 | +122% | 0 | 0 | — |
case-19 | pass→pass | 23,828 | 6,851 | -71% | 1 | 1 | 0% | 2,012 | 4,255 | +111% | 0 | 0 | — |
case-20 | pass→pass | 21,847 | 19,585 | -10% | 1 | 1 | 0% | 3,603 | 7,045 | +96% | 0 | 0 | — |
case-21 | pass→pass | 10,662 | 8,030 | -25% | 1 | 1 | 0% | 1,986 | 4,719 | +138% | 0 | 0 | — |
case-22 | pass→pass | 9,523 | 8,800 | -8% | 1 | 1 | 0% | 1,891 | 4,974 | +163% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +18 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.