Spring AI 学习指南(二)ChatModel 全套底层组件精讲【Message/Prompt/Options/Stream实战】
前置环境:IDEA2026.1.1、JDK21、SpringBoot3.5.14、SpringAI1.1.6、智谱glm-4-flash免费模型
适合人群:零基础入门Spring AI,想要吃透底层完整调用链路、掌握原生API全套组件的Java开发者
一、前言
上一篇我们搭建好了完整的 Spring AI 开发环境,跑通了极简 AI 对话 Demo。本篇我们正式深入 Spring AI 底层核心根基 —— ChatModel。
ChatModel 是 Spring AI 所有AI对话能力的底层顶层接口,所有上层封装功能全部基于它实现。本篇摒弃极简简写,完整拆解官方原生底层写法,一次性吃透:Message消息体系、System角色设定、智谱模型参数配置、Prompt请求构建、Generation结果解析、Flux流式输出等全套核心组件,彻底搞懂AI调用完整链路。
二、ChatModel 核心概念
2.1 什么是 ChatModel?
ChatModel 是 Spring AI 顶层统一调用接口,是所有大模型对接的底层标准。
Spring AI 为了解决多模型适配混乱问题,统一定义了 ChatModel 规范。我们引入的智谱AI Starter 会自动实现该接口,开发者无需关心底层HTTP请求、鉴权、参数适配,直接注入即可使用。
简单理解:ChatModel 就是 Spring AI 对接大模型的底层入口。
2.2 本篇核心学习组件
本次实战代码将覆盖以下所有底层核心组件,逐个讲解、逐个实战:
-
Message、UserMessage、SystemMessage、AssistantMessage:AI完整对话消息体系
-
ZhiPuAiChatOptions:智谱模型专属参数配置
-
Prompt:AI统一请求载体
-
Generation:AI结果解析对象
-
Flux Stream:AI流式实时输出
三、全套底层组件详细释义
3.1 Message 消息体系(核心重点)
Spring AI 所有对话,都是由 Message 消息对象 组成,分为两种最常用类型:
-
UserMessage 用户消息:代表客户端、用户的提问内容,每一次用户输入都封装为 UserMessage
-
SystemMessage 系统消息:用于设定AI角色、身份、行为规范、回答风格,全局约束AI行为,优先级最高
-
AssistantMessage AI回复消息:代表大模型返回的回答内容,用于存储历史对话、拼接上下文,实现多轮连续对话
举例:设置系统消息为“医院挂号小助手”,AI后续所有回答都会严格按照该角色应答,是实现AI人设、业务场景定制的核心。
3.2 ZhiPuAiChatOptions 模型参数配置
这是智谱模型专属配置类,用于动态修改模型运行参数,覆盖默认全局配置,支持业务精细化控制:
-
setModel():指定调用的模型名称,如 glm-4-flash、glm-4 等
-
setTemperature():随机性系数 0~1,数值越高回答越发散创意,越低越严谨固定
-
setMaxTokens():限制AI最大输出字数,防止返回内容过长
3.3 Prompt 请求载体
Prompt 是 Spring AI 统一的请求封装对象。
所有的消息集合(UserMessage、SystemMessage)、模型参数(ChatOptions),最终都会组装进 Prompt 对象,统一交给 ChatModel 调用。可以理解为:Prompt 是发给大模型的完整请求报文。
3.4 Generation 结果解析对象
大模型返回的完整响应结果会封装为 Generation 对象,包含完整的返回元数据,我们通过该对象精准提取AI回复文本,是底层标准的结果解析方式。
3.5 AssistantMessage AI回复消息
AssistantMessage 是 Spring AI 消息体系中专门用来存放 大模型返回内容 的消息对象。
在多轮对话中,我们需要把上一轮 AI 的回复封装为 AssistantMessage,并存入消息集合,大模型才能识别上下文,实现连续对话。是实现记忆对话、多轮交互的核心组件。
3.6 Flux 流式 Stream 输出
常规接口是一次性返回全部内容,Stream 流式输出是分段、实时返回内容,实现网页常见的“打字机”效果,基于 Reactor 框架 Flux 实现,适合前端实时对话场景。
四、完整可运行实战代码
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.14</version>
<relativePath/>
</parent>
<groupId>demo.ai</groupId>
<artifactId>spring-ai-demo</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.ai.version>1.1.6</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>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-client-chat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-zhipuai</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
application.yml
spring:
ai:
zhipuai:
api-key: 4281feecxxxxxxxx # 从智谱AI获取的 api-key
base-url: https://open.bigmodel.cn/api/paas
chat:
options:
model: glm-4-flash
temperature: 0.7 # 随机性 0-1 越低越严谨
server:
servlet:
# 解决流式输出乱码
encoding:
charset: UTF-8 # UTF-8字符集
force: true # 强制使用UTF-8
enabled: true # 开启 Spring Boot 内置的编码过滤器
下面是 ChatModelController 完整代码
package demo.ai.controller;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.Generation;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.zhipuai.ZhiPuAiChatOptions;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/model")
public class ChatModelController {
@Resource
private ChatModel chatModel;
// 1. 最简调用方式
// http://localhost:8080/model/chat?msg=hi
@GetMapping("/chat")
public String chat(@RequestParam("msg") String msg) {
return chatModel.call(msg);
}
// 2. 带AI角色人设调用(SystemMessage + UserMessage)
// http://localhost:8080/model/role?msg=你是谁
@GetMapping ("/role")
public String role(@RequestParam("msg") String msg) {
Message userMessage = new UserMessage(msg);
Message systemMessage = new SystemMessage("你现在是一个医院挂号的小助手");
return chatModel.call(userMessage, systemMessage);
}
// 3. 完整底层链路:包含 System、User、Assistant 完整消息体系
// http://localhost:8080/model/prompt?msg=感冒发烧,应该挂什么科
@GetMapping ("/prompt")
public String prompt(@RequestParam("msg") String msg) {
// 1. 组装系统角色消息、用户提问消息
Message userMessage = new UserMessage(msg);
Message systemMessage = new SystemMessage("你现在是一个医院挂号的小助手");
// 2. 模拟上一轮AI回复,封装为 AssistantMessage(上下文记忆核心)
AssistantMessage assistantMessage = new AssistantMessage("我是医院智能挂号小助手,可以为你提供挂号咨询、医生出诊查询服务。");
List<Message> messages = new ArrayList<>();
messages.add(systemMessage);
// 拼接历史AI对话
messages.add(assistantMessage);
// 拼接当前用户最新提问
messages.add(userMessage);
// 3. 自定义智谱模型参数
ZhiPuAiChatOptions chatOptions = new ZhiPuAiChatOptions();
// chatOptions.setModel("glm-4.5");
chatOptions.setTemperature(0.9);
chatOptions.setMaxTokens(1024);
// 4. 组装完整Prompt请求体
Prompt prompt = new Prompt(messages, chatOptions);
// 5. 调用模型并解析结果
Generation generation = chatModel.call(prompt).getResult();
return generation.getOutput().getText();
}
// 4. 流式输出(打字机实时效果)
// http://localhost:8080/model/stream?msg=你好
@GetMapping ("/stream")
public Flux<String> stream(@RequestParam("msg") String msg) {
return chatModel.stream(msg);
}
}
五、四大接口逐段详解
5.1 最简基础调用 /model/chat
最精简的底层调用方式,无需手动组装消息,框架自动封装,适合简单问答场景。
5.2 角色人设对话 /model/role
引入 SystemMessage 角色设定,给AI固定业务身份。后续所有对话都会遵循「医院挂号小助手」的身份应答,是AI场景化开发的基础。
5.3 完整底层全链路 /model/prompt
这是最标准、最完整的 Spring AI 底层调用流程,新增AssistantMessage 实现上下文对话模拟,企业级多轮对话开发完全基于此原理:
-
组装 SystemMessage(角色)、AssistantMessage(历史AI回复)、UserMessage(当前用户提问) 完整消息链路
-
通过 ZhiPuAiChatOptions 自定义模型温度、最大输出Token等参数
-
将全部消息集合、模型参数统一组装为 Prompt 请求对象
-
ChatModel 调用 call() 方法,通过 Generation 解析最终回复文本
这是最标准、最完整的 Spring AI 底层调用流程,企业级自定义开发均基于此写法:
-
组装用户消息、系统消息,统一放入消息集合
-
通过 ZhiPuAiChatOptions 自定义模型温度、最大输出Token等参数
-
将消息集合、模型参数统一组装为 Prompt 请求对象
-
ChatModel 调用 call() 方法,通过 Generation 解析最终回复文本
5.4 流式实时输出 /model/stream
基于 reactor 响应式编程返回 Flux 数据流,接口会分段持续返回AI内容,浏览器访问可直接看到打字机实时输出效果,适配前端AI聊天页面。
六、接口测试方式
-
基础对话:
http://localhost:8080/model/chat?msg=介绍一下Spring AI -
角色对话:
http://localhost:8080/model/role?msg=你是谁 -
完整参数对话:
http://localhost:8080/model/prompt?msg=感冒发烧,应该挂什么科 -
流式输出:
http://localhost:8080/model/stream?msg=简单介绍医院挂号流程
七、本次学习踩坑记录
-
坑1:无法注入ChatModel:必须正确引入 spring-ai-zhipuai-spring-boot-starter 依赖,否则无自动实现类
-
坑2:参数不生效:ZhiPuAiChatOptions 必须和 Message 集合一起组装进 Prompt,单独配置无效
-
坑3:流式接口乱码/无效果:浏览器直接访问即可看到分段输出,Postman需切换流式视图查看
八、结语
本篇完整跑通了 Spring AI 最底层的完整调用链路,掌握了所有基础核心组件,知根知底才能用好上层封装。打好 ChatModel 底层基础,后续学习高阶功能将会事半功倍。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)