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); }
}
|
然后在使用的时候直接从容器中获取:
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() { String content = client.prompt() .user("中国的面积有多大?") .system("你是一个地理专家,能够回复用户的各种地理问题") .call() .content(); System.out.println(content); }
@Test void coreApi2() { String content = client.prompt("中国的面积有多大?") .call() .content(); System.out.println(content); }
@Test void coreApi3() { Message userMsg = new UserMessage("中国的面积有多大?"); Message sysMsg = new SystemMessage("你是一个地理专家,能够回复用户的各种地理问题;"); Prompt prompt = new Prompt(List.of(sysMsg, userMsg)); 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() { 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 { Flux<String> content = client.prompt() .user("中国的面积有多大?") .system("你是一个地理专家,能够回复用户的各种地理问题") .stream().content(); 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…):添加默认顾问(如记忆、检索增强)。