关于 aws-sdk-java-v2-bedrock
面向 Java 开发者的技能指南,介绍如何通过 AWS SDK for Java 2.x 调用 Amazon Bedrock 基础模型,并涵盖流式响应、嵌入和 Spring Boot 集成。
主要功能
- 01调用多种 Bedrock 模型
- 02构建并解析模型专属载荷
- 03处理流式响应与错误恢复
- 04生成 RAG 文本嵌入
- 05配置 Spring Boot 集成
- 06使用指数退避处理限流
适用场景
- 01在 Java 应用中生成文本或图像
- 02为 RAG 流程创建嵌入
- 03将 Bedrock 接入 Spring Boot 微服务
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ giuseppe-trisciuoglio/ developer-kit --skill aws-sdk-java-v2-bedrock安装后在 Claude Code 中输入/aws-sdk-java-v2-bedrock确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/advanced-model-patterns.mdadvanced-topics.mdaws-bedrock-api-reference.mdaws-bedrock-user-guide.mdaws-sdk-examples.mdaws-sdk-java-bedrock-api.mdbedrock-code-examples.mdbedrock-models-supported.mdbedrock-runtime-code-examples.mdmodel-reference.mdmodels-lookup.mdtesting-strategies.md详细介绍
AWS SDK for Java 2.x - Amazon Bedrock
概述
通过 AWS SDK for Java 2.x 调用基础模型。配置客户端、构建特定于模型的 JSON 负载、处理带错误恢复的流式响应、为 RAG 创建嵌入,将生成式 AI 集成到 Spring Boot 应用中,并实现指数退避以增强韧性。
适用场景
- 调用 Claude、Llama、Titan 或 Stable Diffusion 生成文本/图像
- 配置 BedrockClient 和 BedrockRuntimeClient 实例
- 构建和解析特定于模型的负载(Claude、Titan、Llama 格式)
- 使用异步处理器和错误恢复机制流式传输实时 AI 响应
- 创建用于检索增强生成的嵌入
- 将生成式 AI 集成到 Spring Boot 微服务中
- 使用指数退避重试逻辑处理限流
快速开始
依赖项
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bedrock</artifactId>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bedrockruntime</artifactId>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
</dependency>
客户端设置
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();
使用说明
按照以下步骤进行适用于生产环境的 Bedrock 集成:
- 配置 AWS 凭证 - 设置具有 Bedrock 权限的 IAM 角色(避免使用访问密钥)
- 启用模型访问权限 - 在 AWS Console 中申请访问特定基础模型
- 初始化客户端 - 创建可复用的
BedrockClient和BedrockRuntimeClient实例 - 验证模型可用性 - 在生产环境使用前,通过简单调用进行测试
- 构建负载 - 按照正确格式创建特定于模型的 JSON 负载
- 处理响应 - 解析响应结构并提取内容
- 实现流式传输 - 使用响应流处理器实时生成内容
- 添加错误处理 - 使用指数退避实现重试逻辑
验证检查点:在生产环境使用前,务必使用简单提示词(例如,“Hello”)进行测试,以验证模型访问权限和响应解析。
示例
使用 Claude 生成文本
public 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");
}
模型发现
import software.amazon.awssdk.services.bedrock.model.*;
public List<FoundationModelSummary> listFoundationModels(BedrockClient bedrockClient) {
return bedrockClient.listFoundationModels().modelSummaries();
}
多模型调用
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);
}
带错误处理的流式响应
public 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");
}
用于处理限流的指数退避
import 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");
}
文本嵌入
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 集成
@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());
}
}
参阅示例目录,了解全面的用法模式。
最佳实践
模型选择
- Claude 4.5 Sonnet:适用于复杂推理、分析和创意任务
- Claude 4.5 Haiku:适用于实时应用,速度快且价格实惠
- Llama 3.1:适用于一般任务的开源替代方案
- Titan:AWS 原生模型,适用于简单文本生成,成本效益高
性能
- 复用客户端实例(避免为每个请求创建新客户端)
- 对 I/O 操作使用异步客户端
- 对较长响应使用流式传输
- 缓存基础模型列表
安全
- 切勿记录敏感提示词数据
- 使用 IAM 角色进行身份验证
- 清理用户输入,防止提示词注入
- 为公共应用实施速率限制
限制和警告
- 成本管理:Bedrock API 调用按 Token 收费;请实施用量监控和预算提醒。
- 模型访问权限:必须在 AWS Console 中启用基础模型;请确认区域可用性。
- 速率限制:实施指数退避以处理限流;检查各模型的限制。
- 负载大小:最大负载大小因模型而异;大型文档请使用分块处理。
- 流式传输的复杂性:谨慎处理部分内容和错误恢复。
- 数据隐私:AWS 可能会记录提示词和响应;请查看数据政策。
- 凭证:切勿将凭证写入代码;EC2/Lambda 请使用 IAM 角色。
常见模型 ID
- Claude Sonnet 4.5:
anthropic.claude-sonnet-4-5-20250929-v1:0 - Claude Haiku 4.5:
anthropic.claude-haiku-4-5-20251001-v1:0 - Llama 3.1 70B:
meta.llama3-1-70b-instruct-v1:0 - Titan Embeddings:
amazon.titan-embed-text-v1
完整列表请参阅模型参考。
参考资料
- 高级主题 - 多模型模式、高级错误处理
- 模型参考 - 详细规格、载荷格式
- 测试策略 - 单元测试、LocalStack 集成
- AWS Bedrock 用户指南
- AWS SDK 示例
- 支持的模型
相关技能
aws-sdk-java-v2-core- AWS SDK 核心模式langchain4j-ai-services-patterns- LangChain4j 集成spring-boot-dependency-injection- Spring DI 模式
评论
支持 Markdown