Spring AI Chat模型入门——理解 ChatModel、ChatClient、Prompt 和 ChatResponse
一、为什么需要 Spring AI直接在 Java 项目中调用大模型通常要处理 HTTP 请求、身份认证、请求参数、响应解析、流式传输以及不同模型厂商之间的协议差异。当应用从一个模型切换到另一个模型时这些差异还会进入业务代码。Spring AI 的作用是借鉴 Spring 生态一贯的抽象设计为 AI 应用提供相对统一的编程模型。开发者可以更多地面向 ChatModel、ChatClient、Prompt 等 Spring AI 抽象编程而不是让业务代码直接依赖某一家模型厂商的原始 SDK。Spring AI 并不是一个大模型也不会替我们训练模型。它更像连接 Java 应用与大模型服务之间的工程化适配层。二、本文学习目标学完本文你应该能够回答以下问题- Spring AI 的聊天模型 API 解决了什么问题- ChatModel 和 ChatClient 有什么区别- Message、Prompt、Generation 和 ChatResponse 分别表示什么- 为什么调用一次聊天接口并不等于实现了多轮对话- 同步调用和流式调用在接口层面有什么区别三、核心对象之间的关系3.1 Message带有角色的消息例如java SystemMessage systemMessage new SystemMessage(你是一名专业的 Java 教师); UserMessage userMessage new UserMessage(请解释什么是依赖注入);注意System Message 是对模型的指令和引导但不能代替权限校验、数据脱敏、输入检查和输出治理。3.2 Prompt一次模型请求的输入载体Prompt 用于组织一次模型调用所需的信息。它可以包含一条或多条消息也可以携带本次请求的模型参数。java Prompt prompt new Prompt( List.of(systemMessage, userMessage) );可以把 Prompt 理解为一次模型请求的完整上下文而不是简单的“提示词字符串”。3.3 Generation模型生成的一条候选结果模型可能返回一个或多个候选答案Spring AI 使用 Generation 表示其中一条生成结果。生成的文本通常位于输出消息中。Generation generation response.getResult(); String text generation ! null ? generation.getOutput().getText() : ;不同 Spring AI 版本中读取文本的方法可能是 getText() 或旧版的 getContent()。同一篇文章必须使用与项目依赖一致的 API不能混用不同版本的写法。3.4 ChatResponse完整的模型响应ChatResponse 不只包含最终文本还可能包含- 一个或多个生成结果- 模型响应元数据- Token 使用量- 结束原因- 模型供应商提供的其他信息。如果业务只需要字符串可以使用便捷方法如果需要统计 Token、记录模型信息或者分析结束原因就应保留完整的 ChatResponse。四、ChatModel底层聊天模型抽象ChatModel 是 Spring AI 聊天模型体系中的核心接口。它统一了同步调用和流式调用的入口让上层代码不必直接面向某个厂商的模型客户端。本文使用版本中的接口结构如下public interface ChatModel extends ModelPrompt, ChatResponse, StreamingChatModel { default String call(String message) { Prompt prompt new Prompt(new UserMessage(message)); Generation generation call(prompt).getResult(); return (generation ! null) ? generation.getOutput().getText() : ; } default String call(Message... messages) { Prompt prompt new Prompt(Arrays.asList(messages)); Generation generation call(prompt).getResult(); return (generation ! null) ? generation.getOutput().getText() : ; } Override ChatResponse call(Prompt prompt); default ChatOptions getDefaultOptions() { return ChatOptions.builder().build(); } default FluxChatResponse stream(Prompt prompt) { throw new UnsupportedOperationException( streaming is not supported ); } }4.1 call(String message) 做了什么该方法适合最简单的单轮调用String answer chatModel.call(请介绍一下 Spring AI);从源码可以看出它在内部完成了以下转换String → UserMessage → Prompt → call(Prompt) → ChatResponse → Generation → 文本因此call(String) 是便捷入口真正的核心同步方法仍然是 call(Prompt)。4.2 call(Message... messages) 有什么用这个重载可以一次传入多条不同角色的消息String answer chatModel.call( new SystemMessage(你是一名专业的 Java 教师), new UserMessage(请解释 Spring Bean 的生命周期) );它比单字符串调用更加灵活但最终仍只返回文本。如果需要完整元数据应使用 call(Prompt)。4.3 call(Prompt prompt) 为什么最重要ChatResponse response chatModel.call(prompt);具体模型实现必须实现这个方法。使用它可以- 发送多条消息- 设置本次调用的模型参数- 读取完整的 ChatResponse- 获取生成结果之外的元数据。4.4 声明流式能力不等于所有模型都支持流式输出ChatModel 同时继承 StreamingChatModel但接口中的默认 stream() 实现会直接抛出异常throw new UnsupportedOperationException( streaming is not supported );这说明 Spring AI 在接口层面统一了流式调用入口但具体实现仍需满足两个条件1. 对应的 ChatModel 实现重写了流式方法2. 底层模型服务本身支持流式响应。五、ChatClient面向业务的高层客户端ChatClient 构建在 ChatModel 之上提供类似 WebClient 或 RestClient 的链式调用体验。String answer chatClient.prompt() .user(请介绍一下 Spring AI) .call() .content();相比直接操作 ChatModelChatClient 更适合在业务代码中使用因为它可以更自然地组织- System Message 和 User Message- 提示词模板参数- 同步和流式调用- 结构化输出- Advisor 等增强能力。二者的层级关系是六、ChatClient 与 ChatModel 如何选择七、一次调用为什么不等于多轮聊天下面的代码每次只发送当前用户输入chatClient.prompt() .user(message) .call() .content();当第二次 HTTP 请求到来时模型并不知道第一次请求发生过什么。因此这只是单轮调用而不是真正具有上下文的多轮聊天。多轮对话需要显式保存和重新发送历史消息或者使用 Spring AI 的 Chat Memory、Advisor 等机制。后续会单独用一篇文章讲解。八、常见问题8.1 Spring AI 会自动训练模型吗不会。Spring AI 主要解决应用集成和工程化问题模型能力来自 DeepSeek、OpenAI、Ollama 等底层模型服务。8.2 换模型以后业务代码完全不用改吗基础调用通常可以保持相对稳定但不同模型支持的参数、多模态能力、工具调用能力和返回元数据并不完全相同。统一抽象降低了切换成本并不意味着所有模型功能完全一致。九、本文总结本文需要记住五点1. Spring AI 是 Java 应用与大模型服务之间的工程化抽象层。2. Message 表示带角色的消息Prompt 表示一次模型请求的完整输入。3. ChatModel 是底层模型抽象统一同步和流式调用入口。4. ChatClient 构建在 ChatModel 之上更适合大多数业务开发。5. 单次调用默认没有跨请求记忆多轮聊天需要额外维护会话上下文。下一篇将搭建一个完整的 Spring Boot 项目并通过 ChatClient 调用 DeepSeek。

相关新闻

Shimano 8170电变与CANYON公路车:技术解析与性价比评估

Shimano 8170电变与CANYON公路车:技术解析与性价比评估

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/30 3:11:33 阅读更多 →
ARM架构与英伟达GPU融合趋势下的开发环境适配与实战指南

ARM架构与英伟达GPU融合趋势下的开发环境适配与实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/24 8:01:08 阅读更多 →
MC模组配乐全流程:从sounds.json到Fabric自定义音乐

MC模组配乐全流程:从sounds.json到Fabric自定义音乐

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 18:38:53 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/31 0:19:11 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/30 9:20:34 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/30 10:19:21 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/31 0:59:28 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/30 10:19:39 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/30 9:21:37 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/30 17:32:24 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/30 10:28:40 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/31 0:09:01 阅读更多 →