Spring AI - Chat Model

ChatModel is the core model of the Spring AI project. It provides a simple and flexible way to create chatbots and conversational interfaces. The model is designed to be easy to use and extend, allowing developers to quickly build and deploy chatbots for a wide range of applications.

Maven Dependency

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<properties>
<java.version>17</java.version>
<spring-ai.version>2.0.0-M2</spring-ai.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>

Configuration

OpenAI Chat Properties are explained here https://docs.spring.io/spring-ai/reference/api/chat/openai-chat.html. use spring.ai.openai.api-key to define the OpenAI API key and spring.ai.openai.chat.options.model to define the model to use.

You can select between models such as: gpt-5, gpt-5-mini, gpt-5-nano, and more. See the OpenAI Models page for more information.

API access cost a small fee. You can get a API key by signing up at https://platform.openai.com/settings/organization/api-keys

Example of application.properties:

1
2
3
spring.ai.openai.api-key=${OPENAI_API_KEY}
spring.ai.openai.chat.options.model=gpt-5-mini
spring.ai.openai.chat.options.temperature=1

Usage

Spring will automatically create a ChatModel bean for you. You can inject this bean into your service or controller and use it to generate responses to user prompts.

You can use call method of ChatModel to call the OpenAI API and get the response.

call method is a simple wrapper around the OpenAI API that takes care of the details of making the API call and parsing the response. You can pass a simple string prompt to the call method, and it will return the response from the OpenAI API as a string.

Example of a controller that uses ChatModel‘s call method to get the weather information:

1
2
3
4
5
6
7
8
private final ChatModel chatModel;

// http://localhost:8080/weather
@GetMapping("/weather")
public String getWeather() {
String response = chatModel.call("What is the average temperature in Boston in March?");
return response;
}

It is recommended to use a service layer to call the ChatModel instead of calling it directly from the controller. This allows you to separate the concerns of handling HTTP requests and generating responses from the logic of calling the OpenAI API.

1
2
3
4
5
6
7
8
9
10
11
12
@Service
public class ChatService {
private final ChatModel chatModel;

public ChatService(ChatModel chatModel) {
this.chatModel = chatModel;
}

public String getResponse(String prompt) {
return chatModel.call(prompt);
}
}

You can override the default options defined in application.properties by passing an instance of OpenAiChatOptions to the call method. This allows you to customize the behavior of the OpenAI API for specific prompts.

1
2
3
4
5
6
ChatResponse response = chatModel.call(new Prompt(
prompt,
OpenAiChatOptions.builder()
.model("gpt-5")
.build()));
String callResponse = response.getResult().getOutput().getText();

see https://platform.openai.com/docs/api-reference/chat/create for more information on the OpenAI API.

PromptTemplate

You can use PromptTemplate to define a template for prompts. The template can include placeholders that will be replaced with values at run-time. This can be useful for generating prompts that are based on dynamic data.

1
2
3
4
5
public String callUsingPromptTemplate(String adjective, String topic) {
PromptTemplate promptTemplate = new PromptTemplate("Tell me a {adjective} joke about {topic}");
Prompt prompt = promptTemplate.create(Map.of("adjective", adjective, "topic", topic));
return chatModel.call(prompt).getResult().getOutput().getText();
}

Structured Output

The ability of LLMs to produce structured outputs is important for downstream applications that rely on reliably parsing output values.

List Output

Use ListOutputConverter to convert the output of a prompt into a list of strings. This is useful when you want to get a list of items from the OpenAI API, such as a list of ice cream flavors.

1
2
3
4
5
List<String> flavors = ChatClient.create(chatModel).prompt()
.user(u -> u.text("List five {subject}")
.param("subject", "ice cream flavors"))
.call()
.entity(new ListOutputConverter(new DefaultConversionService()));

Entity Output

Use entity method to convert the output of a prompt into a Java record or class. This is useful when you want to get a structured response from the OpenAI API, such as the filmography of an actor.

1
2
3
4
5
6
record ActorFilms(String actor, List<String> movies) {}

ActorFilms actorFilms = ChatClient.create(chatModel).prompt()
.user("Generate the filmography for a random actor.")
.call()
.entity(ActorFilms.class);

Reference