Skip to content

Commit bf0f1b4

Browse files
tzolovmaxjiang153
andcommitted
Add docs and fix configs
- Move timeout configuration from chat properties to connection properties - Add comprehensive documentation for Bedrock Converse API usage and configuration - Update tests to reflect configuration changes Co-authored-by: maxjiang153 <[email protected]>
1 parent 4a5925a commit bf0f1b4

File tree

10 files changed

+201
-62
lines changed

10 files changed

+201
-62
lines changed

models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockConverseChatClientIT.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,6 @@ void beanStreamOutputConverterRecords() {
180180
Flux<ChatResponse> chatResponse = ChatClient.create(this.chatModel)
181181
.prompt()
182182
.advisors(new SimpleLoggerAdvisor())
183-
// .options(FunctionCallingOptions.builder().withModel("meta.llama2-13b-chat-v1").build())
184-
// .options(FunctionCallingOptions.builder().withModel("mistral.mistral-large-2402-v1:0").build())
185183
.user(u -> u
186184
.text("Generate the filmography of 5 movies for Tom Hanks. " + System.lineSeparator()
187185
+ "{format}")
@@ -212,9 +210,8 @@ void beanStreamOutputConverterRecords() {
212210
void functionCallTest() {
213211

214212
// @formatter:off
215-
String response = ChatClient.create(this.chatModel).prompt()
216-
// .user(u -> u.text("What's the weather like in San Francisco? Return the temperature in Celsius."))
217-
.user(u -> u.text("What's the weather like in San Francisco, Tokyo, and Paris? Return the temperature in Celsius."))
213+
String response = ChatClient.create(this.chatModel)
214+
.prompt("What's the weather like in San Francisco, Tokyo, and Paris? Return the temperature in Celsius.")
218215
.function("getCurrentWeather", "Get the weather in location", new MockWeatherService())
219216
.call()
220217
.content();
@@ -230,10 +227,12 @@ void defaultFunctionCallTest() {
230227

231228
// @formatter:off
232229
String response = ChatClient.builder(this.chatModel)
233-
.defaultFunction("getCurrentWeather", "Get the weather in location", new MockWeatherService())
234-
.defaultUser(u -> u.text("What's the weather like in San Francisco, Tokyo, and Paris? Return the temperature in Celsius."))
235-
.build()
236-
.prompt().call().content();
230+
.defaultFunction("getCurrentWeather", "Get the weather in location", new MockWeatherService())
231+
.defaultUser(u -> u.text("What's the weather like in San Francisco, Tokyo, and Paris? Return the temperature in Celsius."))
232+
.build()
233+
.prompt()
234+
.call()
235+
.content();
237236
// @formatter:on
238237

239238
logger.info("Response: {}", response);

spring-ai-docs/src/main/antora/modules/ROOT/nav.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* xref:api/index.adoc[AI Models]
77
** xref:api/chatmodel.adoc[Chat Models]
88
*** xref:api/chat/comparison.adoc[Chat Models Comparison]
9+
*** xref:api/bedrock-converse.adoc[Amazon Bedrock Converse]
910
*** xref:api/bedrock-chat.adoc[Amazon Bedrock]
1011
**** xref:api/chat/bedrock/bedrock-anthropic3.adoc[Anthropic3]
1112
**** xref:api/chat/bedrock/bedrock-anthropic.adoc[Anthropic2]
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
= Bedrock Converse API
2+
3+
link:https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html[Amazon Bedrock] Converse API provides a unified interface for conversational AI models with enhanced capabilities including function/tool calling, multimodal inputs, and streaming responses.
4+
5+
The Bedrock Converse API has the following high-level features:
6+
7+
* Tool/Function Calling: Support for function definitions and tool use during conversations
8+
* Multimodal Input: Ability to process both text and image inputs in conversations
9+
* Streaming Support: Real-time streaming of model responses
10+
* System Messages: Support for system-level instructions and context setting
11+
* Metrics Integration: Built-in support for observation and metrics tracking
12+
13+
The https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html[Amazon Bedrock User Guide] contains detailed information on how to use the AWS hosted service.
14+
15+
TIP: The Bedrock Converse API provides a unified interface across multiple model providers while handling AWS-specific authentication and infrastructure concerns.
16+
17+
== Prerequisites
18+
19+
Refer to the xref:api/bedrock.adoc[Spring AI documentation on Amazon Bedrock] for setting up API access.
20+
21+
* Obtain AWS credentials: If you don't have an AWS account and AWS CLI configured yet, this video guide can help you configure it: link:https://youtu.be/gswVHTrRX8I?si=buaY7aeI0l3-bBVb[AWS CLI & SDK Setup in Less Than 4 Minutes!]. You should be able to obtain your access and security keys.
22+
23+
* Enable the Models to use: Go to link:https://us-east-1.console.aws.amazon.com/bedrock/home[Amazon Bedrock] and from the link:https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/modelaccess[Model Access] menu on the left, configure access to the models you are going to use.
24+
25+
26+
== Auto-configuration
27+
28+
Add the `spring-ai-bedrock-converse-spring-boot-starter` dependency to your project's Maven `pom.xml` or Gradle `build.gradle` build files:
29+
30+
[tabs]
31+
======
32+
Maven::
33+
+
34+
[source,xml]
35+
----
36+
<dependency>
37+
<groupId>org.springframework.ai</groupId>
38+
<artifactId>spring-ai-bedrock-converse-spring-boot-starter</artifactId>
39+
</dependency>
40+
----
41+
42+
Gradle::
43+
+
44+
[source,gradle]
45+
----
46+
dependencies {
47+
implementation 'org.springframework.ai:spring-ai-bedrock-converse-spring-boot-starter'
48+
}
49+
----
50+
======
51+
52+
TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.
53+
54+
55+
=== Chat Properties
56+
57+
The prefix `spring.ai.bedrock.aws` is the property prefix to configure the connection to AWS Bedrock.
58+
59+
[cols="3,3,1", stripes=even]
60+
|====
61+
| Property | Description | Default
62+
63+
| spring.ai.bedrock.aws.region | AWS region to use. | us-east-1
64+
| spring.ai.bedrock.aws.timeout | AWS timeout to use. | 5m
65+
| spring.ai.bedrock.aws.access-key | AWS access key. | -
66+
| spring.ai.bedrock.aws.secret-key | AWS secret key. | -
67+
| spring.ai.bedrock.aws.session-token | AWS session token for temporary credentials. | -
68+
|====
69+
70+
The prefix `spring.ai.bedrock.converse.chat` is the property prefix that configures the chat model implementation for the Converse API.
71+
72+
[cols="3,5,1", stripes=even]
73+
|====
74+
| Property | Description | Default
75+
76+
| spring.ai.bedrock.converse.chat.enabled | Enable Bedrock Converse chat model. | true
77+
| spring.ai.bedrock.converse.chat.options.model | The model ID to use. You can use the https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference-supported-models-features.html[Supported models and model features] | anthropic.claude-3-sonnet-20240229-v1:0
78+
| spring.ai.bedrock.converse.chat.options.temperature | Controls the randomness of the output. Values can range over [0.0,1.0] | 0.8
79+
| spring.ai.bedrock.converse.chat.options.top-p | The maximum cumulative probability of tokens to consider when sampling. | AWS Bedrock default
80+
| spring.ai.bedrock.converse.chat.options.top-k | Number of token choices for generating the next token. | AWS Bedrock default
81+
| spring.ai.bedrock.converse.chat.options.max-tokens | Maximum number of tokens in the generated response. | 500
82+
|====
83+
84+
== Runtime Options [[chat-options]]
85+
86+
Use the portable `ChatOptions` or `FunctionCallingOptions` portable builders to create model configurations, such as temperature, maxToken, topP, etc.
87+
88+
On start-up, the default options can be configured with the `BedrockConverseProxyChatModel(api, options)` constructor or the `spring.ai.bedrock.converse.chat.options.*` properties.
89+
90+
At run-time you can override the default options by adding new, request specific, options to the `Prompt` call:
91+
92+
[source,java]
93+
----
94+
var options = FunctionCallingOptions.builder()
95+
.withModel("anthropic.claude-3-5-sonnet-20240620-v1:0")
96+
.withTemperature(0.6)
97+
.withMaxTokens(300)
98+
.withFunctionCallbacks(List.of(FunctionCallbackWrapper.builder(new WeatherService())
99+
.withName("getCurrentWeather")
100+
.withDescription("Get the weather in location. Return temperature in 36°F or 36°C format. Use multi-turn if needed.")
101+
.build()))
102+
.build();
103+
104+
ChatResponse response = chatModel.call(new Prompt("What is current weather in Amsterdam?", options));
105+
----
106+
107+
== Tool/Function Calling
108+
109+
The Bedrock Converse API supports function calling capabilities, allowing models to use tools during conversations. Here's an example of how to define and use functions:
110+
111+
[source,java]
112+
----
113+
@Bean
114+
@Description("Get the weather in location. Return temperature in 36°F or 36°C format.")
115+
public Function<Request, Response> weatherFunction() {
116+
return new MockWeatherService();
117+
}
118+
119+
String response = ChatClient.create(this.chatModel)
120+
.prompt("What's the weather like in Boston?")
121+
.function("weatherFunction")
122+
.call()
123+
.content();
124+
----
125+
126+
== Sample Controller
127+
128+
Create a new Spring Boot project and add the `spring-ai-bedrock-converse-spring-boot-starter` to your dependencies.
129+
130+
Add an `application.properties` file under `src/main/resources`:
131+
132+
[source,properties]
133+
----
134+
spring.ai.bedrock.aws.region=eu-central-1
135+
spring.ai.bedrock.aws.timeout=10m
136+
spring.ai.bedrock.aws.access-key=${AWS_ACCESS_KEY_ID}
137+
spring.ai.bedrock.aws.secret-key=${AWS_SECRET_ACCESS_KEY}
138+
139+
spring.ai.bedrock.converse.chat.options.temperature=0.8
140+
spring.ai.bedrock.converse.chat.options.top-k=15
141+
----
142+
143+
Here's an example controller using the chat model:
144+
145+
[source,java]
146+
----
147+
@RestController
148+
public class ChatController {
149+
150+
private final ChatClient chatClient;
151+
152+
@Autowired
153+
public ChatController(ChatClient.Builder builder) {
154+
this.chatClient = builder.build();
155+
}
156+
157+
@GetMapping("/ai/generate")
158+
public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
159+
return Map.of("generation", this.chatClient.prompt(message).call().content());
160+
}
161+
162+
@GetMapping("/ai/generateStream")
163+
public Flux<ChatResponse> generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
164+
return this.chatClient.prompt(message).stream().content();
165+
}
166+
}
167+
----
168+

spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/converse/BedrockConverseProxyChatAutoConfiguration.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,14 @@
1818

1919
import java.util.List;
2020

21+
import io.micrometer.observation.ObservationRegistry;
22+
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
23+
import software.amazon.awssdk.regions.providers.AwsRegionProvider;
24+
import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeAsyncClient;
25+
import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient;
26+
2127
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionConfiguration;
28+
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionProperties;
2229
import org.springframework.ai.bedrock.converse.BedrockProxyChatModel;
2330
import org.springframework.ai.chat.observation.ChatModelObservationConvention;
2431
import org.springframework.ai.model.function.FunctionCallback;
@@ -34,12 +41,6 @@
3441
import org.springframework.context.annotation.Bean;
3542
import org.springframework.context.annotation.Import;
3643

37-
import io.micrometer.observation.ObservationRegistry;
38-
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
39-
import software.amazon.awssdk.regions.providers.AwsRegionProvider;
40-
import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeAsyncClient;
41-
import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient;
42-
4344
/**
4445
* {@link AutoConfiguration Auto-configuration} for Bedrock Converse Proxy Chat Client.
4546
*
@@ -60,7 +61,7 @@ public class BedrockConverseProxyChatAutoConfiguration {
6061
@ConditionalOnMissingBean
6162
@ConditionalOnBean({ AwsCredentialsProvider.class, AwsRegionProvider.class })
6263
public BedrockProxyChatModel bedrockProxyChatModel(AwsCredentialsProvider credentialsProvider,
63-
AwsRegionProvider regionProvider, BedrockAwsConnectionConfiguration connectionProperties,
64+
AwsRegionProvider regionProvider, BedrockAwsConnectionProperties connectionProperties,
6465
BedrockConverseProxyChatProperties chatProperties, FunctionCallbackContext functionCallbackContext,
6566
List<FunctionCallback> toolFunctionCallbacks, ObjectProvider<ObservationRegistry> observationRegistry,
6667
ObjectProvider<ChatModelObservationConvention> observationConvention,
@@ -70,7 +71,7 @@ public BedrockProxyChatModel bedrockProxyChatModel(AwsCredentialsProvider creden
7071
var chatModel = BedrockProxyChatModel.builder()
7172
.withCredentialsProvider(credentialsProvider)
7273
.withRegion(regionProvider.getRegion())
73-
.withTimeout(chatProperties.getTimeout())
74+
.withTimeout(connectionProperties.getTimeout())
7475
.withDefaultOptions(chatProperties.getOptions())
7576
.withObservationRegistry(observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP))
7677
.withFunctionCallbackContext(functionCallbackContext)

spring-ai-spring-boot-autoconfigure/src/main/java/org/springframework/ai/autoconfigure/bedrock/converse/BedrockConverseProxyChatProperties.java

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
package org.springframework.ai.autoconfigure.bedrock.converse;
1818

19-
import java.time.Duration;
20-
2119
import org.springframework.ai.bedrock.converse.BedrockProxyChatModel;
2220
import org.springframework.ai.model.function.FunctionCallingOptionsBuilder.PortableFunctionCallingOptions;
2321
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -35,11 +33,6 @@ public class BedrockConverseProxyChatProperties {
3533

3634
public static final String CONFIG_PREFIX = "spring.ai.bedrock.converse.chat";
3735

38-
/**
39-
* Set model timeout, Defaults 10 min.
40-
*/
41-
private Duration timeout = Duration.ofMinutes(5L);
42-
4336
/**
4437
* Enable Bedrock Converse chat model.
4538
*/
@@ -83,12 +76,4 @@ public void setOptions(PortableFunctionCallingOptions options) {
8376
this.options = options;
8477
}
8578

86-
public Duration getTimeout() {
87-
return this.timeout;
88-
}
89-
90-
public void setTimeout(Duration timeout) {
91-
this.timeout = timeout;
92-
}
93-
9479
}

spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/anthropic3/BedrockAnthropic3ChatAutoConfigurationIT.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Map;
2121
import java.util.stream.Collectors;
2222

23+
import com.fasterxml.jackson.databind.ObjectMapper;
2324
import org.junit.jupiter.api.Disabled;
2425
import org.junit.jupiter.api.Test;
2526
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
@@ -41,8 +42,6 @@
4142
import org.springframework.context.annotation.Bean;
4243
import org.springframework.context.annotation.Configuration;
4344

44-
import com.fasterxml.jackson.databind.ObjectMapper;
45-
4645
import static org.assertj.core.api.Assertions.assertThat;
4746

4847
/**

spring-ai-spring-boot-autoconfigure/src/test/java/org/springframework/ai/autoconfigure/bedrock/converse/BedrockConverseProxyChatAutoConfigurationIT.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@
1616

1717
package org.springframework.ai.autoconfigure.bedrock.converse;
1818

19-
import static org.assertj.core.api.Assertions.assertThat;
20-
2119
import java.util.List;
2220
import java.util.stream.Collectors;
2321

2422
import org.apache.commons.logging.Log;
2523
import org.apache.commons.logging.LogFactory;
2624
import org.junit.jupiter.api.Test;
2725
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
26+
import reactor.core.publisher.Flux;
27+
import software.amazon.awssdk.regions.Region;
28+
2829
import org.springframework.ai.bedrock.converse.BedrockProxyChatModel;
2930
import org.springframework.ai.chat.messages.AssistantMessage;
3031
import org.springframework.ai.chat.messages.UserMessage;
@@ -34,8 +35,7 @@
3435
import org.springframework.boot.autoconfigure.AutoConfigurations;
3536
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
3637

37-
import reactor.core.publisher.Flux;
38-
import software.amazon.awssdk.regions.Region;
38+
import static org.assertj.core.api.Assertions.assertThat;
3939

4040
@EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*")
4141
@EnabledIfEnvironmentVariable(named = "AWS_SECRET_ACCESS_KEY", matches = ".*")

0 commit comments

Comments
 (0)