Bedrock Converse API

Amazon Bedrock Converse API 为对话式 AI 模型提供统一接口,并增强了功能,包括函数/工具调用、多模态输入和流式响应。

Bedrock Converse API 具有以下高级功能:

  • 工具/函数调用:支持在对话期间进行函数定义和工具使用

  • 多模态输入:能够处理对话中的文本和图像输入

  • 流式支持:实时流式传输模型响应

  • 系统消息:支持系统级指令和上下文设置

Bedrock Converse API 为多个模型提供商提供统一接口,同时处理 AWS 特定的身份验证和基础设施问题。目前,Converse API 支持的模型 包括:Amazon TitanAmazon NovaAI21 LabsAnthropic ClaudeCohere CommandMeta LlamaMistral AI

根据 Bedrock 的建议,Spring AI 正在过渡到使用 Amazon Bedrock 的 Converse API 来实现 Spring AI 中的所有聊天对话。虽然现有的 InvokeModel API 支持对话应用程序,但我们强烈建议所有聊天对话模型都采用 Converse API。

Converse API 不支持嵌入操作,因此这些操作将保留在当前 API 中,并且现有 InvokeModel API 中的嵌入模型功能将得到维护

先决条件

请参阅 Amazon Bedrock 入门 以设置 API 访问

  • 获取 AWS 凭证:如果您还没有 AWS 账户和 AWS CLI 配置,此视频指南可以帮助您进行配置:在不到 4 分钟内设置 AWS CLI 和 SDK!您应该能够获取您的访问密钥和安全密钥。

  • 启用要使用的模型:转到 Amazon Bedrock,然后从左侧的模型访问菜单中,配置对您将要使用的模型的访问权限。

自动配置

Spring AI 自动配置、启动模块的工件名称发生了重大变化。请参阅 升级说明 以获取更多信息。

spring-ai-starter-model-bedrock-converse 依赖项添加到您的项目的 Maven pom.xml 或 Gradle build.gradle 构建文件中

  • Maven

  • Gradle

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-bedrock-converse</artifactId>
</dependency>
dependencies {
    implementation 'org.springframework.ai:spring-ai-starter-model-bedrock-converse'
}
请参阅 依赖项管理 部分,将 Spring AI BOM 添加到您的构建文件中。

聊天属性

前缀 spring.ai.bedrock.aws 是配置与 AWS Bedrock 连接的属性前缀。

财产 描述 默认值

spring.ai.bedrock.aws.region

要使用的 AWS 区域

us-east-1

spring.ai.bedrock.aws.timeout

整个 API 调用的 AWS 最大持续时间

5m

spring.ai.bedrock.aws.connectionTimeout

建立连接时的最大等待持续时间

5秒

spring.ai.bedrock.aws.connectionAcquisitionTimeout

从连接池获取新连接的最大等待持续时间

30s

spring.ai.bedrock.aws.asyncReadTimeout

读取异步响应的最大持续时间

30s

spring.ai.bedrock.aws.access-key

AWS 访问密钥

-

spring.ai.bedrock.aws.secret-key

AWS 密钥

-

spring.ai.bedrock.aws.session-token

用于临时凭证的 AWS 会话令牌

-

聊天自动配置的启用和禁用现在通过以spring.ai.model.chat为前缀的顶级属性进行配置。

要启用,请设置 spring.ai.model.chat=bedrock-converse (默认启用)

要禁用,请设置 spring.ai.model.chat=none (或任何与 bedrock-converse 不匹配的值)

此更改是为了允许配置多个模型。

前缀 spring.ai.bedrock.converse.chat 是配置 Converse API 聊天模型实现的属性前缀。

财产 描述 默认值

spring.ai.bedrock.converse.chat.enabled (已删除且不再有效)

启用 Bedrock Converse 聊天模型。

true

spring.ai.model.chat

启用 Bedrock Converse 聊天模型。

bedrock-converse

spring.ai.bedrock.converse.chat.options.model

要使用的模型 ID。您可以使用 支持的模型和模型功能

无。从 AWS Bedrock 控制台选择您的 模型 ID

spring.ai.bedrock.converse.chat.options.temperature

控制输出的随机性。值范围为 [0.0,1.0]

0.8

spring.ai.bedrock.converse.chat.options.top-p

采样时要考虑的令牌的最大累积概率。

AWS Bedrock 默认

spring.ai.bedrock.converse.chat.options.top-k

生成下一个令牌的令牌选择数量。

AWS Bedrock 默认

spring.ai.bedrock.converse.chat.options.max-tokens

生成响应中的最大令牌数。

500

运行时选项

使用可移植的 ChatOptionsBedrockChatOptions 可移植构建器来创建模型配置,例如温度、maxToken、topP 等。

在启动时,可以使用 BedrockConverseProxyChatModel(api, options) 构造函数或 spring.ai.bedrock.converse.chat.options.* 属性配置默认选项。

在运行时,可以通过向 Prompt 调用添加新的、特定于请求的选项来覆盖默认选项

var options = BedrockChatOptions.builder()
        .model("anthropic.claude-3-5-sonnet-20240620-v1:0")
        .temperature(0.6)
        .maxTokens(300)
        .toolCallbacks(List.of(FunctionToolCallback.builder("getCurrentWeather", new WeatherService())
            .description("Get the weather in location. Return temperature in 36°F or 36°C format. Use multi-turn if needed.")
            .inputType(WeatherService.Request.class)
            .build()))
        .build();

String response = ChatClient.create(this.chatModel)
    .prompt("What is current weather in Amsterdam?")
    .options(options)
    .call()
    .content();

提示缓存

AWS Bedrock 的 提示缓存功能 允许您缓存常用提示,以降低成本并改善重复交互的响应时间。当您缓存提示时,后续相同的请求可以重用缓存内容,从而显著减少处理的输入令牌数量。

支持的模型

Claude 3.x、Claude 4.x 和通过 AWS Bedrock 提供的 Amazon Nova 模型支持提示缓存。

令牌要求

不同的模型对缓存效率有不同的最低令牌阈值:- Claude Sonnet 4 和大多数模型:1024+ 令牌 - 模型特定要求可能有所不同 - 请查阅 AWS Bedrock 文档

缓存策略

Spring AI 通过 BedrockCacheStrategy 枚举提供战略性缓存放置

  • NONE:完全禁用提示缓存(默认)

  • SYSTEM_ONLY:仅缓存系统消息内容

  • TOOLS_ONLY:仅缓存工具定义(仅限 Claude 模型)

  • SYSTEM_AND_TOOLS:缓存系统消息和工具定义(仅限 Claude 模型)

  • CONVERSATION_HISTORY:在聊天记忆场景中缓存整个对话历史记录

这种战略方法确保了最佳缓存断点放置,同时保持在 AWS Bedrock 的 4 个断点限制内。

Amazon Nova 限制

Amazon Nova 模型(Nova Micro、Lite、Pro、Premier)仅支持对 systemmessages 内容进行缓存。它们支持对 tools 进行缓存。

如果您尝试将 TOOLS_ONLYSYSTEM_AND_TOOLS 策略与 Nova 模型一起使用,AWS 将返回 ValidationException。对于 Amazon Nova 模型,请使用 SYSTEM_ONLY 策略。

启用提示缓存

通过在 BedrockChatOptions 上设置 cacheOptions 并选择 strategy 来启用提示缓存。

仅限系统缓存

最常见的用例 - 在多个请求中缓存系统指令

// Cache system message content
ChatResponse response = chatModel.call(
    new Prompt(
        List.of(
            new SystemMessage("You are a helpful AI assistant with extensive knowledge..."),
            new UserMessage("What is machine learning?")
        ),
        BedrockChatOptions.builder()
            .model("us.anthropic.claude-3-7-sonnet-20250219-v1:0")
            .cacheOptions(BedrockCacheOptions.builder()
                .strategy(BedrockCacheStrategy.SYSTEM_ONLY)
                .build())
            .maxTokens(500)
            .build()
    )
);

仅限工具缓存

缓存大型工具定义,同时保持系统提示动态(仅限 Claude 模型)

// Cache tool definitions only
ChatResponse response = chatModel.call(
    new Prompt(
        "What's the weather in San Francisco?",
        BedrockChatOptions.builder()
            .model("us.anthropic.claude-3-7-sonnet-20250219-v1:0")
            .cacheOptions(BedrockCacheOptions.builder()
                .strategy(BedrockCacheStrategy.TOOLS_ONLY)
                .build())
            .toolCallbacks(weatherToolCallbacks)  // Large tool definitions
            .maxTokens(500)
            .build()
    )
);
此策略仅在 Claude 模型上受支持。Amazon Nova 模型将返回 ValidationException

系统和工具缓存

缓存系统指令和工具定义以实现最大程度的重用(仅限 Claude 模型)

// Cache system message and tool definitions
ChatResponse response = chatModel.call(
    new Prompt(
        List.of(
            new SystemMessage("You are a weather analysis assistant..."),
            new UserMessage("What's the weather like in Tokyo?")
        ),
        BedrockChatOptions.builder()
            .model("us.anthropic.claude-3-7-sonnet-20250219-v1:0")
            .cacheOptions(BedrockCacheOptions.builder()
                .strategy(BedrockCacheStrategy.SYSTEM_AND_TOOLS)
                .build())
            .toolCallbacks(weatherToolCallbacks)
            .maxTokens(500)
            .build()
    )
);
此策略使用 2 个缓存断点(一个用于工具,一个用于系统)。仅在 Claude 模型上受支持。

对话历史缓存

缓存多轮聊天机器人和助手的不断增长的对话历史记录

// Cache conversation history with ChatClient and memory
ChatClient chatClient = ChatClient.builder(chatModel)
    .defaultSystem("You are a personalized career counselor...")
    .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory)
        .conversationId(conversationId)
        .build())
    .build();

String response = chatClient.prompt()
    .user("What career advice would you give me?")
    .options(BedrockChatOptions.builder()
        .model("us.anthropic.claude-3-7-sonnet-20250219-v1:0")
        .cacheOptions(BedrockCacheOptions.builder()
            .strategy(BedrockCacheStrategy.CONVERSATION_HISTORY)
            .build())
        .maxTokens(500)
        .build())
    .call()
    .content();

使用 ChatClient 流式 API

String response = ChatClient.create(chatModel)
    .prompt()
    .system("You are an expert document analyst...")
    .user("Analyze this large document: " + document)
    .options(BedrockChatOptions.builder()
        .model("us.anthropic.claude-3-7-sonnet-20250219-v1:0")
        .cacheOptions(BedrockCacheOptions.builder()
            .strategy(BedrockCacheStrategy.SYSTEM_ONLY)
            .build())
        .build())
    .call()
    .content();

使用示例

这是一个演示带有成本跟踪的提示缓存的完整示例

// Create system content that will be reused multiple times
String largeSystemPrompt = "You are an expert software architect specializing in distributed systems...";
// (Ensure this is 1024+ tokens for cache effectiveness)

// First request - creates cache
ChatResponse firstResponse = chatModel.call(
    new Prompt(
        List.of(
            new SystemMessage(largeSystemPrompt),
            new UserMessage("What is microservices architecture?")
        ),
        BedrockChatOptions.builder()
            .model("us.anthropic.claude-3-7-sonnet-20250219-v1:0")
            .cacheOptions(BedrockCacheOptions.builder()
                .strategy(BedrockCacheStrategy.SYSTEM_ONLY)
                .build())
            .maxTokens(500)
            .build()
    )
);

// Access cache-related token usage from metadata
Integer cacheWrite1 = (Integer) firstResponse.getMetadata()
    .getMetadata()
    .get("cacheWriteInputTokens");
Integer cacheRead1 = (Integer) firstResponse.getMetadata()
    .getMetadata()
    .get("cacheReadInputTokens");

System.out.println("Cache creation tokens: " + cacheWrite1);
System.out.println("Cache read tokens: " + cacheRead1);

// Second request with same system prompt - reads from cache
ChatResponse secondResponse = chatModel.call(
    new Prompt(
        List.of(
            new SystemMessage(largeSystemPrompt),  // Same prompt - cache hit
            new UserMessage("What are the benefits of event sourcing?")
        ),
        BedrockChatOptions.builder()
            .model("us.anthropic.claude-3-7-sonnet-20250219-v1:0")
            .cacheOptions(BedrockCacheOptions.builder()
                .strategy(BedrockCacheStrategy.SYSTEM_ONLY)
                .build())
            .maxTokens(500)
            .build()
    )
);

Integer cacheWrite2 = (Integer) secondResponse.getMetadata()
    .getMetadata()
    .get("cacheWriteInputTokens");
Integer cacheRead2 = (Integer) secondResponse.getMetadata()
    .getMetadata()
    .get("cacheReadInputTokens");

System.out.println("Cache creation tokens: " + cacheWrite2); // Should be 0
System.out.println("Cache read tokens: " + cacheRead2);      // Should be > 0

令牌使用跟踪

AWS Bedrock 通过响应元数据提供特定于缓存的指标。缓存指标可通过元数据 Map 访问

ChatResponse response = chatModel.call(/* ... */);

// Access cache metrics from metadata Map
Integer cacheWrite = (Integer) response.getMetadata()
    .getMetadata()
    .get("cacheWriteInputTokens");
Integer cacheRead = (Integer) response.getMetadata()
    .getMetadata()
    .get("cacheReadInputTokens");

特定于缓存的指标包括

  • cacheWriteInputTokens:返回创建缓存条目时使用的令牌数

  • cacheReadInputTokens:返回从现有缓存条目读取的令牌数

当您第一次发送缓存的提示时: - cacheWriteInputTokens 将大于 0 - cacheReadInputTokens 将为 0

当您再次发送相同的缓存提示时(在 5 分钟 TTL 内): - cacheWriteInputTokens 将为 0 - cacheReadInputTokens 将大于 0

实际用例

通过在多个问题中缓存文档内容,高效分析大型法律合同或合规文档

// Load a legal contract (PDF or text)
String legalContract = loadDocument("merger-agreement.pdf"); // ~3000 tokens

// System prompt with legal expertise
String legalSystemPrompt = "You are an expert legal analyst specializing in corporate law. " +
    "Analyze the following contract and provide precise answers about terms, obligations, and risks: " +
    legalContract;

// First analysis - creates cache
ChatResponse riskAnalysis = chatModel.call(
    new Prompt(
        List.of(
            new SystemMessage(legalSystemPrompt),
            new UserMessage("What are the key termination clauses and associated penalties?")
        ),
        BedrockChatOptions.builder()
            .model("us.anthropic.claude-3-7-sonnet-20250219-v1:0")
            .cacheOptions(BedrockCacheOptions.builder()
                .strategy(BedrockCacheStrategy.SYSTEM_ONLY)
                .build())
            .maxTokens(1000)
            .build()
    )
);

// Subsequent questions reuse cached document - 90% cost savings
ChatResponse obligationAnalysis = chatModel.call(
    new Prompt(
        List.of(
            new SystemMessage(legalSystemPrompt), // Same content - cache hit
            new UserMessage("List all financial obligations and payment schedules.")
        ),
        BedrockChatOptions.builder()
            .model("us.anthropic.claude-3-7-sonnet-20250219-v1:0")
            .cacheOptions(BedrockCacheOptions.builder()
                .strategy(BedrockCacheStrategy.SYSTEM_ONLY)
                .build())
            .maxTokens(1000)
            .build()
    )
);

批处理代码审查

使用一致的审查标准处理多个代码文件,同时缓存审查指南

// Define comprehensive code review guidelines
String reviewGuidelines = """
    You are a senior software engineer conducting code reviews. Apply these criteria:
    - Security vulnerabilities and best practices
    - Performance optimizations and memory usage
    - Code maintainability and readability
    - Testing coverage and edge cases
    - Design patterns and architecture compliance
    """;

List<String> codeFiles = Arrays.asList(
    "UserService.java", "PaymentController.java", "SecurityConfig.java"
);

List<String> reviews = new ArrayList<>();

for (String filename : codeFiles) {
    String sourceCode = loadSourceFile(filename);

    ChatResponse review = chatModel.call(
        new Prompt(
            List.of(
                new SystemMessage(reviewGuidelines), // Cached across all reviews
                new UserMessage("Review this " + filename + " code:\n\n" + sourceCode)
            ),
            BedrockChatOptions.builder()
                .model("us.anthropic.claude-3-7-sonnet-20250219-v1:0")
                .cacheOptions(BedrockCacheOptions.builder()
                    .strategy(BedrockCacheStrategy.SYSTEM_ONLY)
                    .build())
                .maxTokens(800)
                .build()
        )
    );

    reviews.add(review.getResult().getOutput().getText());
}

// Guidelines cached after first request, subsequent reviews are faster and cheaper

具有知识库的客户支持

创建客户支持系统,缓存您的产品知识库以提供一致、准确的响应

// Load comprehensive product knowledge
String knowledgeBase = """
    PRODUCT DOCUMENTATION:
    - API endpoints and authentication methods
    - Common troubleshooting procedures
    - Billing and subscription details
    - Integration guides and examples
    - Known issues and workarounds
    """ + loadProductDocs(); // ~2500 tokens

@Service
public class CustomerSupportService {

    public String handleCustomerQuery(String customerQuery, String customerId) {
        ChatResponse response = chatModel.call(
            new Prompt(
                List.of(
                    new SystemMessage("You are a helpful customer support agent. " +
                        "Use this knowledge base to provide accurate solutions: " + knowledgeBase),
                    new UserMessage("Customer " + customerId + " asks: " + customerQuery)
                ),
                BedrockChatOptions.builder()
                    .model("us.anthropic.claude-3-7-sonnet-20250219-v1:0")
                    .cacheOptions(BedrockCacheOptions.builder()
                        .strategy(BedrockCacheStrategy.SYSTEM_ONLY)
                        .build())
                    .maxTokens(600)
                    .build()
            )
        );

        return response.getResult().getOutput().getText();
    }
}

// Knowledge base is cached across all customer queries
// Multiple support agents can benefit from the same cached content

多租户 SaaS 应用程序

在不同租户之间缓存共享工具定义,同时为每个租户定制系统提示

// Shared tool definitions (cached once, used across all tenants)
List<FunctionToolCallback> sharedTools = createLargeToolRegistry(); // ~2000 tokens

// Tenant-specific configuration
@Service
public class MultiTenantAIService {

    public String processRequest(String tenantId, String userQuery) {
        // Load tenant-specific system prompt (changes per tenant)
        String tenantPrompt = loadTenantSystemPrompt(tenantId);

        ChatResponse response = chatModel.call(
            new Prompt(
                List.of(
                    new SystemMessage(tenantPrompt), // Tenant-specific, not cached
                    new UserMessage(userQuery)
                ),
                BedrockChatOptions.builder()
                    .model("us.anthropic.claude-3-7-sonnet-20250219-v1:0")
                    .cacheOptions(BedrockCacheOptions.builder()
                        .strategy(BedrockCacheStrategy.TOOLS_ONLY)
                        .build())
                    .toolCallbacks(sharedTools) // Shared tools - cached
                    .maxTokens(500)
                    .build()
            )
        );

        return response.getResult().getOutput().getText();
    }
}

// Tools cached once, each tenant gets customized system prompt

最佳实践

  1. 选择正确的策略:

    • 对可重用系统提示和指令使用 SYSTEM_ONLY(适用于所有模型)

    • 当您有大型稳定工具但动态系统提示时使用 TOOLS_ONLY(仅限 Claude)

    • 当系统和工具都庞大且稳定时使用 SYSTEM_AND_TOOLS(仅限 Claude)

    • 在多轮对话中与 ChatClient 内存一起使用 CONVERSATION_HISTORY

    • 使用 NONE 显式禁用缓存

  2. 满足令牌要求:重点缓存满足最低令牌要求(大多数模型为 1024+ 令牌)的内容。

  3. 重用相同内容:缓存最适用于提示内容的精确匹配。即使是很小的更改也需要新的缓存条目。

  4. 监控令牌使用情况:使用元数据指标跟踪缓存效率

    Integer cacheWrite = (Integer) response.getMetadata().getMetadata().get("cacheWriteInputTokens");
    Integer cacheRead = (Integer) response.getMetadata().getMetadata().get("cacheReadInputTokens");
    if (cacheRead != null && cacheRead > 0) {
        System.out.println("Cache hit: " + cacheRead + " tokens saved");
    }
  5. 战略性缓存放置:实施会根据您选择的策略自动将缓存断点放置在最佳位置,确保符合 AWS Bedrock 的 4 个断点限制。

  6. 缓存生命周期:AWS Bedrock 缓存具有固定的 5 分钟 TTL(生存时间)。每次缓存访问都会重置计时器。

  7. 模型兼容性:请注意模型特定的限制

    • Claude 模型:支持所有缓存策略

    • Amazon Nova 模型:仅支持 SYSTEM_ONLYCONVERSATION_HISTORY(不支持工具缓存)

  8. 工具稳定性:当使用 TOOLS_ONLYSYSTEM_AND_TOOLSCONVERSATION_HISTORY 策略时,请确保工具保持稳定。更改工具定义将使所有下游缓存断点失效,因为会发生级联失效。

缓存失效和级联行为

AWS Bedrock 遵循具有级联失效的分层缓存模型

缓存层次结构工具 → 系统 → 消息

每个级别的更改都会使该级别和所有后续级别失效

哪些变化 工具缓存 系统缓存 消息缓存

工具

❌ 无效

❌ 无效

❌ 无效

系统

✅ 有效

❌ 无效

❌ 无效

消息

✅ 有效

✅ 有效

❌ 无效

使用 SYSTEM_AND_TOOLS 策略的示例:

// Request 1: Cache both tools and system
ChatResponse r1 = chatModel.call(
    new Prompt(
        List.of(new SystemMessage("System prompt"), new UserMessage("Question")),
        BedrockChatOptions.builder()
            .cacheOptions(BedrockCacheOptions.builder()
                .strategy(BedrockCacheStrategy.SYSTEM_AND_TOOLS)
                .build())
            .toolCallbacks(tools)
            .build()
    )
);
// Result: Both caches created

// Request 2: Change only system prompt (tools same)
ChatResponse r2 = chatModel.call(
    new Prompt(
        List.of(new SystemMessage("DIFFERENT system prompt"), new UserMessage("Question")),
        BedrockChatOptions.builder()
            .cacheOptions(BedrockCacheOptions.builder()
                .strategy(BedrockCacheStrategy.SYSTEM_AND_TOOLS)
                .build())
            .toolCallbacks(tools) // SAME tools
            .build()
    )
);
// Result: Tools cache HIT (reused), system cache MISS (recreated)

// Request 3: Change tools (system same as Request 2)
ChatResponse r3 = chatModel.call(
    new Prompt(
        List.of(new SystemMessage("DIFFERENT system prompt"), new UserMessage("Question")),
        BedrockChatOptions.builder()
            .cacheOptions(BedrockCacheOptions.builder()
                .strategy(BedrockCacheStrategy.SYSTEM_AND_TOOLS)
                .build())
            .toolCallbacks(newTools) // DIFFERENT tools
            .build()
    )
);
// Result: BOTH caches MISS (tools change invalidates everything downstream)

实现细节

Spring AI 中的提示缓存实现遵循以下关键设计原则

  1. 战略性缓存放置:缓存断点会根据所选策略自动放置在最佳位置,确保符合 AWS Bedrock 的 4 个断点限制。

  2. 提供商可移植性:缓存配置通过 BedrockChatOptions 而不是单个消息完成,从而在不同 AI 提供商之间切换时保持兼容性。

  3. 线程安全:缓存断点跟踪使用线程安全机制实现,以正确处理并发请求。

  4. UNION 类型模式:AWS SDK 使用 UNION 类型,其中缓存点作为单独的块而不是属性添加。这与直接 API 方法不同,但确保了类型安全和 API 合规性。

  5. 增量缓存CONVERSATION_HISTORY 策略将缓存断点放置在最后一个用户消息上,从而实现增量缓存,其中每个对话轮次都基于先前的缓存前缀。

成本考虑

AWS Bedrock 提示缓存定价(近似值,因模型而异)

  • 缓存写入:比基本输入令牌贵约 25%

  • 缓存读取:便宜约 90%(仅为基本输入令牌价格的 10%)

  • 盈亏平衡点:只需 1 次缓存读取后,您就省钱了

成本计算示例:

// System prompt: 2000 tokens
// User question: 50 tokens

// Without caching (5 requests):
// Cost: 5 × (2000 + 50) = 10,250 tokens at base rate

// With caching (5 requests):
// Request 1: 2000 tokens × 1.25 (cache write) + 50 = 2,550 tokens
// Requests 2-5: 4 × (2000 × 0.10 (cache read) + 50) = 4 × 250 = 1,000 tokens
// Total: 2,550 + 1,000 = 3,550 tokens equivalent

// Savings: (10,250 - 3,550) / 10,250 = 65% cost reduction

工具调用

Bedrock Converse API 支持工具调用功能,允许模型在对话期间使用工具。以下是定义和使用基于 @Tool 的工具的示例

public class WeatherService {

    @Tool(description = "Get the weather in location")
    public String weatherByLocation(@ToolParam(description= "City or state name") String location) {
        ...
    }
}

String response = ChatClient.create(this.chatModel)
        .prompt("What's the weather like in Boston?")
        .tools(new WeatherService())
        .call()
        .content();

您也可以将 java.util.function bean 用作工具

@Bean
@Description("Get the weather in location. Return temperature in 36°F or 36°C format.")
public Function<Request, Response> weatherFunction() {
    return new MockWeatherService();
}

String response = ChatClient.create(this.chatModel)
        .prompt("What's the weather like in Boston?")
        .toolNames("weatherFunction")
        .inputType(Request.class)
        .call()
        .content();

工具 文档中查找更多信息。

多模态

多模态是指模型同时理解和处理来自各种来源(包括文本、图像、视频、pdf、doc、html、md 和更多数据格式)信息的能力。

Bedrock Converse API 支持多模态输入,包括文本和图像输入,并且可以根据组合输入生成文本响应。

您需要一个支持多模态输入的模型,例如 Anthropic Claude 或 Amazon Nova 模型。

图像

对于支持视觉多模态的 模型,例如 Amazon Nova、Anthropic Claude、Llama 3.2,Bedrock Converse API Amazon 允许您在有效负载中包含多个图像。这些模型可以分析传入的图像并回答问题、对图像进行分类以及根据提供的指令总结图像。

目前,Bedrock Converse 支持 base64 编码的 image/jpegimage/pngimage/gifimage/webp MIME 类型的图像。

Spring AI 的 Message 接口通过引入 Media 类型支持多模态 AI 模型。它包含消息中媒体附件的数据和信息,使用 Spring 的 org.springframework.util.MimeTypejava.lang.Object 作为原始媒体数据。

下面是一个简单的代码示例,演示了用户文本与图像的组合。

String response = ChatClient.create(chatModel)
    .prompt()
    .user(u -> u.text("Explain what do you see on this picture?")
        .media(Media.Format.IMAGE_PNG, new ClassPathResource("/test.png")))
    .call()
    .content();

logger.info(response);

它以 test.png 图像作为输入

Multimodal Test Image

以及文本消息“解释你在这张图片上看到了什么?”,并生成类似以下的响应

The image shows a close-up view of a wire fruit basket containing several pieces of fruit.
...

视频

Amazon Nova 模型 允许您在有效负载中包含单个视频,可以以 base64 格式或通过 Amazon S3 URI 提供。

目前,Bedrock Nova 支持 video/x-matroskavideo/quicktimevideo/mp4video/webmvideo/x-flvvideo/mpegvideo/x-ms-wmvvideo/3gpp MIME 类型的视频。

Spring AI 的 Message 接口通过引入 Media 类型支持多模态 AI 模型。它包含消息中媒体附件的数据和信息,使用 Spring 的 org.springframework.util.MimeTypejava.lang.Object 作为原始媒体数据。

下面是一个简单的代码示例,演示了用户文本与视频的组合。

String response = ChatClient.create(chatModel)
    .prompt()
    .user(u -> u.text("Explain what do you see in this video?")
        .media(Media.Format.VIDEO_MP4, new ClassPathResource("/test.video.mp4")))
    .call()
    .content();

logger.info(response);

它以 test.video.mp4 图像作为输入

Multimodal Test Video

以及文本消息“解释你在这个视频中看到了什么?”,并生成类似以下的响应

The video shows a group of baby chickens, also known as chicks, huddled together on a surface
...

文档

对于某些模型,Bedrock 允许您通过 Converse API 文档支持在有效负载中包含文档,这些文档可以以字节形式提供。文档支持有两种不同的变体,如下所述

  • 文本文档类型(txt、csv、html、md 等),重点在于文本理解。这些用例包括基于文档文本元素进行回答。

  • 媒体文档类型(pdf、docx、xlsx),重点在于基于视觉的理解来回答问题。这些用例包括基于图表、图形等回答问题。

目前,Anthropic PDF 支持(测试版) 和 Amazon Bedrock Nova 模型支持文档多模态。

下面是一个简单的代码示例,演示了用户文本与媒体文档的组合。

String response = ChatClient.create(chatModel)
    .prompt()
    .user(u -> u.text(
            "You are a very professional document summarization specialist. Please summarize the given document.")
        .media(Media.Format.DOC_PDF, new ClassPathResource("/spring-ai-reference-overview.pdf")))
    .call()
    .content();

logger.info(response);

它以 spring-ai-reference-overview.pdf 文档作为输入

Multimodal Test PNG

以及文本消息“你是一位非常专业的文档摘要专家。请总结给定的文档。”,并生成类似以下的响应

**Introduction:**
- Spring AI is designed to simplify the development of applications with artificial intelligence (AI) capabilities, aiming to avoid unnecessary complexity.
...

示例控制器

创建一个新的 Spring Boot 项目,并将 spring-ai-starter-model-bedrock-converse 添加到您的依赖项中。

src/main/resources 下添加一个 application.properties 文件

spring.ai.bedrock.aws.region=eu-central-1
spring.ai.bedrock.aws.timeout=10m
spring.ai.bedrock.aws.access-key=${AWS_ACCESS_KEY_ID}
spring.ai.bedrock.aws.secret-key=${AWS_SECRET_ACCESS_KEY}
# session token is only required for temporary credentials
spring.ai.bedrock.aws.session-token=${AWS_SESSION_TOKEN}

spring.ai.bedrock.converse.chat.options.temperature=0.8
spring.ai.bedrock.converse.chat.options.top-k=15

以下是使用聊天模型的控制器示例

@RestController
public class ChatController {

    private final ChatClient chatClient;

    @Autowired
    public ChatController(ChatClient.Builder builder) {
        this.chatClient = builder.build();
    }

    @GetMapping("/ai/generate")
    public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
        return Map.of("generation", this.chatClient.prompt(message).call().content());
    }

    @GetMapping("/ai/generateStream")
    public Flux<ChatResponse> generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
        return this.chatClient.prompt(message).stream().content();
    }
}
© . This site is unofficial and not affiliated with VMware.