3-ChatClient

1 概述

  • 核心功能:提供与 AI 模型通信的流式 API,支持同步和流式编程模型。
  • 输入构建:通过流式 API 构建包含用户消息和系统消息的提示(Prompt),消息可包含运行时替换的占位符。
  • 输出处理:支持返回文本内容、结构化实体、带元数据的响应(如 token 使用量),以及流式响应。
对比 交互方式 功能扩展 结构化输出 适用场景
ChatModel 直接调用模型,需手动处理请求/响应 需手动解析响应文本 实现简单功能和场景
ChatClient 链式调用,自动封装提示词贺解析响应 强,内置Advisor机制(如对话历史管理、RAG) 支持自动映射为Java对象(如entity(Recipe.class)) 快速开发复杂功能的场景,如企业级智能客服、连接外部工具等

2 创建ChatClient对象

2.1 自动配置

SpringBoot自动配置会创建 ChatClent.Builder bean,可直接注入并构建实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RestController
public class Chat2Controller {

private ChatClient client;

public Chat2Controller(ChatClient.Builder clientBuilder ) {
this.client = clientBuilder.build();
}

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

2.2 手动创建方式

禁用自动配置后( spring.ai.chat.client.enabled=false),可手动创建多个实例:

1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
class ChatConfig {
@Bean
ChatClient openAiClient(OpenAiChatModel model) {
return ChatClient.create(model);
}

/* @Bean
ChatClient anthropicClient(AnthropicChatModel model) {
return ChatClient.create(model);
}*/
}

然后在使用的时候直接从容器中获取:

1
2
3
4
5
6
7
8
9
10
11
@RestController
public class Chat2Controller {

@Autowired
private ChatClient client;

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

3 流式API核心用法

构建提示的三种方式

1
2
3
prompt():空参,手动构建用户、系统消息。
prompt(Prompt prompt):传入已构建的 Prompt 实例。
prompt(String content):快速设置用户消息内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
	@Test
void coreApi1() {
// 核心API的使用
String content = client.prompt()
.user("中国的面积有多大?")
.system("你是一个地理专家,能够回复用户的各种地理问题")
.call()
.content();
System.out.println(content);
}

@Test
void coreApi2() {
// 核心API的使用
String content = client.prompt("中国的面积有多大?")
.call()
.content();
System.out.println(content);
}

@Test
void coreApi3() {
// 创建用户消息
Message userMsg = new UserMessage("中国的面积有多大?");
// 创建系统消息
Message sysMsg = new SystemMessage("你是一个地理专家,能够回复用户的各种地理问题;");
// 组装 Prompt
Prompt prompt = new Prompt(List.of(sysMsg, userMsg));
// 核心API的使用
String content = client.prompt(prompt)
.call()
.content();
System.out.println(content);
}

同步调用(call)返回值

1
2
3
content():返回字符串内容。
chatResponse():返回包含元数据(如 token 数)的 ChatResponse。
entity(Class<T> type):将响应映射为实体类,这个我们得创建对应的实体类来封装
1
2
3
4
5
6
7
8
9
@Test
void coreApiCall2() {
// 核心API的使用
ChatResponse chatResponse = client.prompt()
.user("中国的面积有多大?")
.system("你是一个地理专家,能够回复用户的各种地理问题")
.call().chatResponse();
System.out.println(chatResponse);
}

输出结果

1
ChatResponse [metadata={ id: chatcmplBwKrrhtbeNYcvZICeMJz5xdRRzuEQ, usage: DefaultUsage{promptTokens=33, completionTokens=37, totalTokens=70}, rateLimit: { @type: org.springframework.ai.openai.metadata.OpenAiRateLimit, requestsLimit: null, requestsRemaining: null, requestsReset: null, tokensLimit: null; tokensRemaining: null; tokensReset: null } }, generations=[Generation[assistantMessage=AssistantMessage [messageType=ASSISTANT, toolCalls=[], textContent=中国的总面积约为960万平方公里,是世界上面积第三大的国家,仅次于俄罗斯和加拿大。这个面积包括了中国的陆地和水域。, metadata={refusal=, finishReason=STOP, index=0, id=chatcmpl-BwKrrhtbeNYcvZICeMJz5xdRRzuEQ, role=ASSISTANT, messageType=ASSISTANT}], chatGenerationMetadata=DefaultChatGenerationMetadata[finishReason='STOP', filters=0, metadata=0]]]]

流式调用(stream)返回值

1
2
content():返回 Flux<String> 流式文本。
chatResponse():返回 Flux<ChatResponse> 流式响应(含元数据)。
1
2
3
4
5
6
7
8
9
10
11
@Test
void coreApiStream1() throws InterruptedException {
// 核心API的使用
Flux<String> content = client.prompt()
.user("中国的面积有多大?")
.system("你是一个地理专家,能够回复用户的各种地理问题")
.stream().content();
// 方式2:收集为字符串
String result = content.reduce("", String::concat).block();
System.out.println(result);
}

4 默认配置与动态覆盖

默认系统消息 在配置类中设置全局默认系统消息,避免每次调用重复设置:

1
2
3
4
5
6
7
@Configuration
class Config {
@Bean
ChatClient chatClient(ChatClient.Builder builder) {
return builder.defaultSystem("你是语言专家,精通英语").build();
}
}

带参数的动态默认值 系统消息中使用占位符,运行时通过 system(sp -> sp.param(“key”, value)) 动态赋值:

1
2
3
4
// 配置类中设置带参数的默认系统消息
builder.defaultSystem("你是语言专家,精通{language}");
// 运行时覆盖参数
chatClient.prompt().system(sp -> sp.param("language", "英语")).user("Tell a story").call().content();

其他默认配置

  • defaultOptions(ChatOptions):设置模型默认参数(如温度、模型类型)。
  • defaultFunctions(Function…):注册默认工具调用函数。
  • defaultAdvisors(Advisor…):添加默认顾问(如记忆、检索增强)。

3-ChatClient
http://www.zivjie.cn/2025/11/22/spring框架/springAI/SpringAi框架/3-ChatClient/
作者
Francis
发布于
2025年11月22日
许可协议