Spring AI ChatModel 与 ChatClient 完整核心解析
一、Spring AI 整体分层概览
Spring AI 是 Spring 官方推出的大模型集成框架,统一屏蔽 OpenAI、通义千问、文心一言、Claude、Ollama 等各类大模型厂商底层 API 差异,提供一套标准化 AI 开发编程模型。
整个对话能力核心分为两层:
- 底层抽象:ChatModel:大模型统一能力接口,定义所有对话模型通用行为;
- 上层门面:ChatClient:基于 ChatModel 封装的流式构建器,简化调用、提示词管理、参数配置、工具调用,业务开发首选。
二者关系:ChatClient 持有 ChatModel 实例,是 ChatModel 的高阶封装,不替代 ChatModel。
二、ChatModel 底层核心抽象
2.1 核心接口定义
org.springframework.ai.chat.model.ChatModelpublic interface ChatModel {
// 单次同步对话,返回完整响应
ChatResponse call(ChatPrompt prompt);
// 流式对话,分段返回结果(打字机效果)
Flux<ChatResponse> stream(ChatPrompt prompt);
}
所有厂商模型都实现该接口:
- OpenAiChatModel
- OllamaChatModel
- TongYiChatModel(阿里通义)
- BaiduErnieChatModel(文心一言)
- AnthropicChatModel(Claude)
2.2 配套核心数据模型
- ChatPrompt:对话提示词载体,承载多条消息
ChatPrompt prompt = new ChatPrompt( new SystemMessage("你是专业Java工程师"), new UserMessage("解释Spring AI ChatModel") ); - Message 消息体系
SystemMessage:系统角色设定,定义 AI 身份、规则UserMessage:用户输入提问AssistantMessage:AI 返回回答ToolMessage:工具调用返回结果(Function Calling)
- ChatResponse:大模型统一返回体
List<Generation> generations:AI 生成内容ChatMetadata metadata:token 消耗、模型名称、请求 ID 等元数据
- ChatOptions:模型参数统一配置(温度、topP、最大 token、流式开关、工具列表等)
各厂商提供对应实现:
OpenAiChatOptions、OllamaOptions
2.3 ChatModel 原生使用示例(底层原生写法)
适合底层自定义扩展、精细控制场景:
@Bean
public ChatModel ollamaChatModel(OllamaProperties properties) {
return new OllamaChatModel(OllamaApi.builder()
.baseUrl(properties.getBaseUrl())
.build(),
OllamaOptions.builder()
.model("qwen:7b")
.temperature(0.7)
.build()
);
}
// 业务调用
@Autowired
private ChatModel chatModel;
public String rawChat() {
// 构建提示词
ChatPrompt prompt = new ChatPrompt(
new SystemMessage("简洁回答问题"),
new UserMessage("什么是ChatModel")
);
// 同步调用
ChatResponse response = chatModel.call(prompt);
return response.getResult().getOutput().getText();
}
// 流式输出
public Flux<String> streamChat() {
return chatModel.stream(prompt)
.map(resp -> resp.getResult().getOutput().getText());
}
2.4 ChatModel 优缺点
优势
- 极致底层可控,可手动组装所有消息、参数、工具;
- 无额外封装损耗,适合框架二次开发、自定义拦截逻辑;
- 完全统一 API,切换模型仅替换实现类,业务代码无需大幅改动。
劣势
- 模板代码冗余,每次调用都要手动构建
ChatPrompt、Message; - 提示词模板、变量替换、记忆管理、工具注册需要自己封装;
- 链式调用可读性差,复杂对话逻辑代码臃肿。
三、ChatClient 上层门面工具
3.1 定位与设计目的
ChatClient 是 Spring AI 为业务开发提供的流畅构建器 API,基于 ChatModel 封装,解决原生 ChatModel 代码繁琐问题,内置能力:- 流式链式构建语法;
- 内置提示词模板、变量渲染;
- 一键配置系统提示词、模型参数;
- 统一对话记忆(ChatMemory)集成;
- 工具函数(Function Calling)快速注册;
- 拦截器(Advisor)全局切面管理;
- 同步 / 流式 / 实体类型返回一键切换。
3.2 ChatClient 创建方式
方式 1:自动注入(推荐,自动装配)
@Autowired private ChatClient chatClient;
自动装配条件:容器中存在
ChatModel Bean,Spring AI 自动生成 ChatClient。方式 2:手动构建自定义 ChatClient
@Bean
public ChatClient customChatClient(ChatModel chatModel) {
return ChatClient.builder(chatModel)
// 全局默认系统提示词
.defaultSystem("你是资深后端开发,回答简洁")
// 全局默认参数
.defaultOptions(OllamaOptions.builder().temperature(0.5).build())
// 全局拦截器
.defaultAdvisors(new SimpleLoggerAdvisor())
.build();
}
3.3 ChatClient 完整核心用法示例
3.3.1 基础同步问答
String res = chatClient.prompt()
.system("你是Java技术博主")
.user("讲解Spring AI ChatClient")
.call()
.content();
3.3.2 提示词模板 + 变量占位
String res = chatClient.prompt()
.system("根据{language}讲解{topic},简短输出")
.user(u -> u.param("language", "Java").param("topic", "ChatModel"))
.call()
.content();
3.3.3 流式打字机输出(Web 实时对话)
public Flux<String> streamReply(String question) {
return chatClient.prompt()
.user(question)
.stream()
.content();
}
3.3.4 强类型实体返回(结构化输出,无需手动解析 JSON)
// 定义接收实体
record CodeResp(String title, String code, String explain) {}
CodeResp resp = chatClient.prompt()
.user("写一段Spring AI调用代码")
.call()
.entity(CodeResp.class);
3.3.5 集成对话记忆(多轮上下文)
// 内存记忆,支持会话隔离
ChatMemory memory = new InMemoryChatMemory();
String reply1 = chatClient.prompt()
.advisors(new MessageChatMemoryAdvisor(memory))
.user("什么是ChatModel")
.call()
.content();
String reply2 = chatClient.prompt()
.advisors(new MessageChatMemoryAdvisor(memory))
.user("它和ChatClient区别")
.call()
.content();
3.3.6 Function Calling 工具调用
// 自定义工具
@Tool
public String getWeather(String city) {
return city + "今日25℃,晴天";
}
// 注册工具调用
String res = chatClient.prompt()
.tools(this)
.user("北京今天天气")
.call()
.content();
3.4 ChatClient 核心内置能力:Advisor 拦截器
Advisor 是 ChatClient 的切面扩展点,执行链路:
官方内置常用 Advisor:
请求前置处理 → 调用ChatModel → 响应后置处理
MessageChatMemoryAdvisor:对话上下文记忆;SimpleLoggerAdvisor:打印请求 / 响应日志;PromptTemplateAdvisor:统一处理提示词模板;RetrievalAugmentationAdvisor:RAG 检索增强接入。
支持自定义 Advisor 实现鉴权、限流、敏感词过滤、日志埋点。
3.5 ChatClient 优缺点
优势
- 流畅链式 API,业务代码极简,可读性极强;
- 内置模板、记忆、工具、结构化输出,开箱即用;
- 全局默认配置统一管理,不用每个请求重复设置参数;
- Advisor 切面统一拦截,集中处理日志、RAG、上下文;
- 支持强类型返回,省去 JSON 手动解析。
劣势
- 重度封装,底层细节隐藏,极端自定义场景不如原生 ChatModel 灵活;
- 多层封装轻微增加调用链路,极致性能场景可选用原生 ChatModel。
四、ChatModel vs ChatClient 核心对比表
表格
| 对比维度 | ChatModel | ChatClient |
|---|---|---|
| 定位 | 底层标准接口,统一大模型抽象 | 上层业务门面,简化开发工具 |
| 依赖关系 | 无依赖,最底层 | 持有 ChatModel,封装其能力 |
| 编码风格 | 命令式,手动组装 ChatPrompt、Message | 流式链式 Builder,极简代码 |
| 提示词模板 | 需手动实现 | 原生内置变量渲染 |
| 多轮记忆 | 手动拼接历史消息 | 内置 ChatMemory Advisor 一键接入 |
| 结构化输出 | 手动解析 ChatResponse | .entity(Class) 自动映射实体 |
| 工具调用 | 手动组装 ToolDefinition | tools() 快速注册 @Tool 方法 |
| 扩展方式 | 自行封装工具类 | Advisor 切面统一拦截处理 |
| 适用场景 | 框架封装、底层中间件、精细控制 | 业务接口、Web 对话、快速开发 |
五、两者配合最佳实践方案
企业级项目标准分层使用规范:
- 配置层:注入对应厂商
ChatModelBean,统一管理模型地址、密钥、基础参数; - 全局门面层:基于 ChatModel 构建全局
ChatClient,统一配置系统提示词、日志 Advisor、全局工具; - 业务层(90% 场景):直接使用自动注入的 ChatClient 完成问答、流式、RAG、多轮对话;
- 底层扩展场景(10%):自定义拦截、特殊模型参数、自研记忆逻辑时,直接操作原生 ChatModel。
标准完整配置示例
@Configuration
public class SpringAiConfig {
// 1. 底层ChatModel
@Bean
public ChatModel ollamaChatModel(OllamaProperties props) {
OllamaApi api = OllamaApi.builder()
.baseUrl(props.getBaseUrl())
.build();
OllamaOptions options = OllamaOptions.builder()
.model("qwen:7b")
.temperature(0.6)
.build();
return new OllamaChatModel(api, options);
}
// 2. 全局ChatClient,基于ChatModel封装
@Bean
public ChatClient chatClient(ChatModel chatModel) {
return ChatClient.builder(chatModel)
.defaultSystem("你是专业后端开发,回答精简专业")
.defaultAdvisors(new SimpleLoggerAdvisor())
.build();
}
// 3. 对话记忆Bean,供业务注入
@Bean
public ChatMemory chatMemory() {
return new InMemoryChatMemory();
}
}
六、常见开发误区总结
- 只使用 ChatModel 写业务:大量重复构建消息、模板代码,维护成本高;
- 误以为 ChatClient 可以脱离 ChatModel:ChatClient 只是封装,底层必须依赖 ChatModel;
- 全局配置重复定义:不要每次 prompt 都重复设置 system、temperature,统一在 ChatClient builder 全局配置;
- 多轮对话手动拼接历史消息:优先使用 MessageChatMemoryAdvisor,避免手动维护上下文;
- 流式输出自行拼接字符串:ChatClient
.stream().content()已分段返回,直接返回给前端 SSE 即可。
七、全文总结
- ChatModel 是标准底座:Spring AI 所有对话模型的统一抽象,抹平各大厂商 API 差异,提供同步 / 流式基础调用能力,面向底层扩展开发;
- ChatClient 是业务工具:基于 ChatModel 的高层封装,流畅 Builder API,内置模板、记忆、工具、结构化返回、切面拦截,日常业务开发首选;
- 二者互补而非替代:底层能力靠 ChatModel,业务简化靠 ChatClient;企业项目标准架构为「ChatModel 配置 + ChatClient 全局门面 + 业务层调用 ChatClient」;
- 开发选型建议:普通问答、流式对话、RAG、多轮聊天全部使用 ChatClient;自研中间件、深度自定义模型请求逻辑、极致性能优化场景直接操作 ChatModel。

浙公网安备 33010602011771号