Spring AI Chat Client provides a fluent API for building AI-powered applications with LLMs, supporting advisors, streaming, structured outputs, and conversation memory
Fluent API for building AI-powered applications with Large Language Models. Provides chainable interface similar to Spring's WebClient with support for advisors, streaming, structured outputs, and conversation memory.
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-client-chat</artifactId>
<version>1.1.2</version>
</dependency>Repository Configuration (required - not in Maven Central):
<repositories>
<repository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>import org.springframework.ai.chat.client.ChatClient;
// Create client
ChatClient client = ChatClient.create(chatModel);
// Simple request
String response = client.prompt("What is Spring?").call().content();
// Structured output
record Answer(String topic, String summary) {}
Answer answer = client.prompt("Explain Spring").call().entity(Answer.class);
// Streaming
Flux<String> stream = client.prompt("Tell a story").stream().content();Main entry point for AI interactions. Create once, reuse for all requests.
// Factory methods
static ChatClient create(ChatModel chatModel);
static ChatClient.Builder builder(ChatModel chatModel);
// Request methods
ChatClientRequestSpec prompt();
ChatClientRequestSpec prompt(String text);Fluent API for building requests with messages, options, tools, and advisors.
interface ChatClientRequestSpec {
ChatClientRequestSpec user(String text);
ChatClientRequestSpec system(String text);
ChatClientRequestSpec advisors(Advisor... advisors);
ChatClientRequestSpec tools(Object... toolObjects);
ChatClientRequestSpec options(ChatOptions options);
CallResponseSpec call();
StreamResponseSpec stream();
}Access responses as text, typed entities, or full ChatResponse objects.
interface CallResponseSpec {
String content();
ChatResponse chatResponse();
<T> T entity(Class<T> type);
<T> ResponseEntity<ChatResponse, T> responseEntity(Class<T> type);
}
interface StreamResponseSpec {
Flux<String> content();
Flux<ChatResponse> chatResponse();
}Interceptors that modify requests/responses in a chain-of-responsibility pattern.
interface Advisor extends Ordered {
String getName();
int getOrder();
}
interface CallAdvisor extends Advisor {
ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain);
}
interface StreamAdvisor extends Advisor {
Flux<ChatClientResponse> adviseStream(ChatClientRequest request, StreamAdvisorChain chain);
}| Advisor | Purpose | Order |
|---|---|---|
SafeGuardAdvisor | Block sensitive content | 100 |
MessageChatMemoryAdvisor | Conversation history (messages) | 1001 |
PromptChatMemoryAdvisor | Conversation history (text) | 1001 |
ToolCallAdvisor | Function calling loop | 3000 |
StructuredOutputValidationAdvisor | Validate JSON output | 5000 |
SimpleLoggerAdvisor | Request/response logging | LOWEST |
Configured Client:
ChatClient client = ChatClient.builder(chatModel)
.defaultSystem("You are a helpful assistant")
.defaultAdvisors(memoryAdvisor, loggerAdvisor)
.defaultOptions(options)
.build();Streaming with Memory:
Flux<String> stream = client
.prompt("Continue our conversation")
.advisors(spec -> spec.param("conversationId", "user-123"))
.stream()
.content();Tool Calling:
WeatherResponse weather = client
.prompt("What's the weather in Paris?")
.toolCallbacks(weatherTool)
.advisors(ToolCallAdvisor.builder().build())
.call()
.entity(WeatherResponse.class);Structured Output with Validation:
Person person = client
.prompt("Generate person profile")
.advisors(StructuredOutputValidationAdvisor.builder()
.outputType(Person.class)
.maxRepeatAttempts(3)
.build())
.call()
.entity(Person.class);ChatClient (thread-safe, reusable)
↓
Request Configuration (fluent API)
↓
Advisor Chain (ordered interceptors)
↓
ChatModel (AI provider)
↓
Response Processing (text/entity/stream)Key Components:
Chainable interface for intuitive request building:
client.prompt().system("...").user("...").options(...).call().content()Extensible interceptor chain for:
Reactive streaming with Project Reactor:
Flux<String> stream = client.prompt("...").stream().content();Type-safe entity conversion:
MyType result = client.prompt("...").call().entity(MyType.class);Built-in Micrometer integration for production monitoring.
ChatClient instances are thread-safe and should be reused across requests.
This tile documents the Chat Client API. Related types from other packages:
ChatModel - AI model interface (from org.springframework.ai.chat.model)ChatOptions - Model configuration (from org.springframework.ai.chat.options)Message types - UserMessage, SystemMessage, etc.ToolCallback - Function calling (from org.springframework.ai.tool)ObservationRegistry - Micrometer observabilitySee respective Spring AI packages for complete documentation of these types.
Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-ai--spring-ai-client-chat