当前位置: 首页 > article >正文

Spring AI 实战系列(二):ChatClient封装,告别大模型开发样板代码

系列栏目Spring AISpring AI 实战教程一入门示例Spring AI 实战系列二ChatClient封装告别大模型开发样板代码Spring AI 实战系列三多模型共存双版本流式输出Spring AI 实战系列四Prompt工程深度实战Spring AI 实战系列五结构化输出让大模型严格适配你的业务数据模型在本系列的第一篇教程中我们完成了 Spring AI与阿里云百炼大模型的基础集成基于spring-ai-alibaba-starter-dashscope官方 Starter 完成了项目工程化搭建通过ChatModel原子API实现了基础的同步对话与流式响应接口完成了API Key的环境变量安全注入避免了密钥硬编码的安全风险但在实际业务开发中我们很快会发现ChatModel虽然提供了极致的底层灵活性但面对复杂的业务场景时需要我们手动组装提示词、处理消息结构、解析模型输出、串联对话记忆 / 向量检索等组件会产生大量重复的样板代码开发效率低且不易维护。本篇我们就来学习 Spring AI 提供的Fluent流式 API —— ChatClient它完美解决了上述痛点在不丢失灵活性的前提下将大模型交互的开发效率提升一个量级。一、ChatClient 核心定位从原子 API 到工程化封装1.1 什么是 ChatClientChatClient是 Spring AI提供的高层级Fluent API它底层基于ChatModel原子能力将大模型交互全流程的组件协调、样板代码全部封装为开发者提供了声明式、链式的开发体验。如果把ChatModel比作JDBC的原生Connection需要自己处理 SQL 拼接、结果集解析那ChatClient就是 MyBatis/MyBatis-Plus把底层繁琐的操作全部收敛让开发者只需要关注核心业务逻辑。1.2 ChatClient 核心优势能力维度ChatModel 原子 APIChatClient Fluent API代码量复杂场景需要大量样板代码手动组装 Message、处理 Prompt链式调用一行完成全流程无冗余代码提示词管理每次调用手动拼接系统提示、用户提示无统一管理能力支持全局默认提示词、动态参数模板一次配置全局生效输出解析需手动处理字符串转 JSON、实体映射、格式校验内置结构化输出能力一键映射为 Java 实体 / 集合自动约束模型输出格式高级能力对话记忆、RAG 检索、函数调用需手动串联组件内置 Advisor 切面机制一行配置开启记忆、RAG、日志、限流等能力编程模型同步 / 流式能力分离API 不统一同步call()、流式stream()统一 API无缝切换1.3 核心能力全景ChatClient 不仅封装了基础对话能力还覆盖了企业级大模型应用的全场景需求基础能力提示词定制、模型参数调优、同步 / 流式响应结构化输出自动将模型返回映射为 Java 实体类、泛型集合全局默认配置统一系统提示词、模型参数、函数定义一次配置全局生效高级扩展通过 Advisor 机制一键集成聊天记忆、RAG 检索、日志监控、函数调用等能力二、实战落地基于阿里云百炼的 ChatClient 集成本次实战完全承接上一篇的项目工程无需从零搭建所有代码可直接复制运行。2.1 环境前提已完成 JDK 17、Spring Boot 3.2.x 环境搭建已配置阿里云百炼API Key环境变量DASHSCOPE_API_KEY已在pom.xml中引入spring-ai-alibaba-starter-dashscope核心依赖2.2 第一步ChatClient 全局 Bean 配置Spring AI不会自动装配ChatClient实例只会自动装配ChatClient.Builder构建器我们需要在配置类中手动创建ChatClient的 Bean 并注入 Spring 容器。修改我们的配置类LLMConfig.java完整代码如下import com.alibaba.cloud.ai.dashscope.api.DashScopeApi; import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.model.ChatModel; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Spring AI 大模型配置类 */ Configuration public class SaaLLMConfig { /** * 阿里云百炼API实例负责与百炼服务通信 * 从系统环境变量读取API Key避免硬编码泄露 */ Bean public DashScopeApi dashScopeApi() { return DashScopeApi.builder() .apiKey(System.getenv(DASHSCOPE_API_KEY)) .build(); } /** * 全局ChatClient实例基于阿里云百炼ChatModel构建 */ Bean public ChatClient dashScopeChatClient(ChatModel dashscopeChatModel) { return ChatClient // 基于已自动装配的ChatModel构建Builder .builder(dashscopeChatModel) // 可选全局默认系统提示词所有调用都会自动携带 .defaultSystem(你是一个专业的Java后端开发工程师擅长Spring生态技术栈回答问题简洁、专业、有可落地的代码示例) // 可选全局默认模型参数统一管理避免每次调用重复配置 .defaultOptions(DashScopeChatOptions.builder() .withModel(qwen-turbo) .withTemperature(0.7) .withMaxTokens(2000) .build()) // 构建ChatClient实例 .build(); } }关键说明这里的ChatModel会由spring-ai-alibaba自动装配无需我们手动创建通过defaultSystem设置全局系统提示词统一模型的角色定位所有调用都会自动携带通过defaultOptions设置全局模型参数统一管理模型版本、温度、最大 Token 数避免硬编码分散在业务代码中2.3 第二步基础接口开发对比 ChatModel 与 ChatClient我们创建ChatClientController同时提供ChatClient和ChatModel的调用接口直观对比两者的开发体验。import jakarta.annotation.Resource; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.model.ChatModel; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * ChatClient 实战接口 */ RestController public class ChatClientController { // 注入原生ChatModel用于对比 Resource private ChatModel chatModel; // 注入我们配置的ChatClient实例 Resource private ChatClient dashScopeChatClient; /** * ChatClient 同步对话接口 */ GetMapping(/chatclient/dochat) public String doChat(RequestParam(name msg, defaultValue 你是谁) String msg) { // ChatClient 链式调用一行完成请求组装、调用、结果提取 String result dashScopeChatClient .prompt() // 创建提示词构建器 .user(msg) // 设置用户输入 .call() // 同步调用大模型 .content(); // 提取响应的文本内容 System.out.println(ChatClient响应 result); return result; } /** * ChatModel 同步对话接口对比用 */ GetMapping(/chatmodelv2/dochat) public String doChat2(RequestParam(name msg, defaultValue 你是谁) String msg) { // ChatModel 原生调用简单场景下一行完成但复杂场景需要大量样板代码 String result chatModel.call(msg); System.out.println(ChatModel响应 result); return result; } }接口测试启动项目后访问http://localhost:8003/chatclient/dochat?msg用Spring Boot写一个Hello World接口可以看到ChatClient会自动携带我们配置的全局系统提示词以 Java 工程师的专业视角返回结果代码简洁且行为统一。三、实践注意全局配置统一管理将系统提示词、模型参数、重试策略等全部在 ChatClient Bean 中统一配置避免硬编码分散在业务代码中便于后续维护与迭代。多模型实例隔离若项目同时对接多个大模型如阿里云百炼 本地 Ollama需为每个模型创建独立的 ChatClient Bean通过Qualifier注解区分注入避免 Bean 冲突。日志与监控集成通过SimpleLoggerAdvisor开启请求与响应的日志打印同时通过 Advisor 切面统一统计 Token 消耗、请求耗时对接 Prometheus 等监控系统。异常统一处理封装 ChatClient 调用的通用异常处理针对大模型调用超时、限流、API 密钥错误、输出解析失败等场景做统一的降级与容错处理。提示词模板外部化复杂的系统提示词不要硬编码在 Java 代码中放到application.yml配置文件或独立的资源文件中通过Value或Resource注入便于产品与运营同学修改优化。四、避坑指南坑点 1ChatClient 无法直接 Resource 注入Spring AI 不会自动装配 ChatClient 的 Bean只会自动装配ChatClient.Builder必须在配置类中通过 Builder 手动构建 ChatClient Bean否则会出现注入失败的异常。坑点 3多模型场景下的 Bean 注入歧义若项目中存在多个 ChatModel 实例构建 ChatClient 时必须通过Qualifier明确指定注入的ChatModel否则 Spring会抛出NoUniqueBeanDefinitionException异常。坑点 4环境变量 API Key 读取失败System.getenv()读取的是系统环境变量IDE 本地运行时需要在启动配置的 Environment variables 中添加DASHSCOPE_API_KEY否则会出现 API Key 为空的错误。下篇预告本篇我们掌握了ChatClient的核心用法实现了比ChatModel更优雅、更易维护的大模型交互代码。下篇我们将深入Spring AI实战核心能力一套代码实现多个大模型无缝共存与动态切换同时带来 ChatModel与ChatClient双版本流式输出完整实现解决长文本生成的用户体验痛点。传送门Spring AI 实战系列三多模型共存双版本流式输出如果本文对你有帮助欢迎点赞、收藏、评论跟着系列教程一步步完成Spring AI应用。

相关文章:

Spring AI 实战系列(二):ChatClient封装,告别大模型开发样板代码

系列栏目:Spring AI Spring AI 实战教程(一)入门示例 Spring AI 实战系列(二):ChatClient封装,告别大模型开发样板代码 Spring AI 实战系列(三)&…...

零基础玩转OpenClaw:Qwen3.5-9B镜像+可视化控制台体验

零基础玩转OpenClaw:Qwen3.5-9B镜像可视化控制台体验 1. 为什么选择OpenClawQwen3.5-9B组合 去年我在整理个人知识库时,每天要花2小时重复执行网页截图、OCR识别、内容归档的机械操作。直到发现OpenClaw这个能像人类一样操作电脑的开源智能体框架&…...

BleSerial:嵌入式BLE UART流式通信C++库

1. BleSerial 库概述BleSerial 是一个面向嵌入式系统的轻量级 C 库,其核心设计目标是将蓝牙低功耗(BLE)通信抽象为标准 CStream对象(即继承自Stream类的实例),从而无缝接入 Arduino 及兼容平台(…...

CGAL::Point_set_3 成员函数自查表

参考来源&#xff1a; CGAL 6.1.1 - 3D Point Set: CGAL::Point_set_3< Point, Vector > Class Template Reference 一、基础构造 / 容量 返回值函数名作用小 demoPoint_set_3()构造空点集Point_set ps;size_tnumber_of_points()获取点数auto n ps.number_of_points(…...

DownKyi:B站视频高效解决方案——如何三步搞定8K资源本地化管理

DownKyi&#xff1a;B站视频高效解决方案——如何三步搞定8K资源本地化管理 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视频下载工具&#xff0c;支持批量下载&#xff0c;支持8K、HDR、杜比视界&#xff0c;提供工具箱&#xff08;音视频提取、去水印…...

[带AI]基于SpringBoot+Vue的青少年心理健康管理系统设计与实现+文档+指导搭建视频

&#xff5c;前后端分离&#xff5c;Java&#xff5c;SpringBoot&#xff5c;Vue3&#xff5c;Spring AI智能对话一、项目技术栈项目采用技术&#xff1a;① 架构模式&#xff1a;前后端分离开发② 系统环境&#xff1a;Windows、Mac③ 开发环境&#xff1a;IDEA、JDK21、MySQL…...

避坑指南:思科模拟器做链路聚合时,你可能会遇到的5个报错及解决方法

思科模拟器链路聚合实战&#xff1a;5个典型报错分析与精准排错指南 在Packet Tracer中配置链路聚合时&#xff0c;最令人头疼的往往不是基础配置步骤&#xff0c;而是那些突如其来的报错信息。上周有位学员在CCNA备考群里发了一张截图&#xff1a;%EC-5-CANNOT_BUNDLE2: Fa0/2…...

ssm+java2026年毕设唐山铂悦山养老院护理管理【源码+论文】

本系统&#xff08;程序源码&#xff09;带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、选题背景关于养老院医护管理问题的研究&#xff0c;现有研究主要以医院信息管理系统&#xff08;HIS&#xff09;或综合性养老服务平台…...

STM32F103开发实录:当Clion的智能补全,遇上CubeMX+Keil5的稳定编译链

STM32F103开发实战&#xff1a;CLion智能编码与Keil5稳定编译的完美融合 第一次接触STM32开发时&#xff0c;我被Keil5那复古的界面和笨重的操作流程震惊了。作为一名习惯了现代IDE的开发者&#xff0c;我一直在寻找既能享受CLion智能编码体验&#xff0c;又能利用Keil5成熟编译…...

EspSoftwareSerial:ESP系列高性能软件串口实现

1. 项目概述EspSoftwareSerial是专为 ESP 系列微控制器&#xff08;ESP8266、ESP32、ESP32-S2、ESP32-S3、ESP32-C3&#xff09;设计的软件串口实现库&#xff0c;其核心目标是提供与 Arduino AVR 平台SoftwareSerial库高度兼容的 API 接口&#xff0c;同时充分利用 ESP 架构特…...

DDR5信号完整性解析:JESD79-5标准下的AC/DC输入测量关键指标

1. DDR5信号完整性的核心挑战 DDR5作为新一代内存标准&#xff0c;将数据传输速率推向了前所未有的高度。但随之而来的信号完整性问题&#xff0c;却让不少硬件工程师头疼不已。想象一下&#xff0c;当数据速率突破6400MT/s时&#xff0c;信号在传输线上就像是在走钢丝&#xf…...

数字电路实战:基于Multisim的74LS161计数器设计与应用

1. 从零认识74LS161计数器 第一次接触数字电路时&#xff0c;看到74LS161这个编号可能会觉得头大。其实它就是个非常实用的4位二进制同步计数器芯片&#xff0c;就像我们生活中常见的里程表一样&#xff0c;能够按照固定规律进行计数。我在实验室里第一次用它做实验时&#xff…...

RoboMaster装甲板灯条匹配算法实战:从图像预处理到目标框定(附完整C++/OpenCV源码)

1. 项目背景与核心挑战 RoboMaster机甲大师赛中的装甲板识别是自动瞄准系统的关键技术难点。赛场上高速移动的机器人装甲板通常配备LED灯条作为视觉标识&#xff0c;这种设计让计算机视觉算法能够在复杂环境下快速定位目标。但实际开发时会遇到几个头疼的问题&#xff1a;强光干…...

【2026年阿里巴巴春招- 3月28日-算法岗-第二题- 隐式素数计算】(题目+思路+JavaC++Python解析+在线测试)

题目内容 我们称一个正整数为隐式素数,如果它不同的正因子的个数是一个素数。给定一个闭区间$ [l,r]$,请计算该区间内隐式素数的个数 输入描述 每个测试文件均包含多组测试数据。第一行输入一个整数$ T (1 ≤ T ≤ 10^4)$,代表数据组数,每组测试数据描述如下: 在一行上…...

Comsol光子晶体:谷霍尔效应、单胞与超胞能带计算及谷单向传输

Comsol光子晶体谷霍尔效应。 单胞&#xff0c;超胞能带计算。 谷单向传输等。光子晶体玩拓扑这件事最近越来越上头。今天咱们撸起袖子直接干一个谷霍尔效应仿真&#xff0c;手把手教你在COMSOL里搞出单向传输这种神奇现象。先说重点&#xff1a;结构旋转6度就能打开带隙&#x…...

OpenClaw多账户管理:ollama-QwQ-32B模型服务同时支持多个飞书机器人

OpenClaw多账户管理&#xff1a;ollama-QwQ-32B模型服务同时支持多个飞书机器人 1. 为什么需要多账户管理&#xff1f; 去年我们团队在尝试用OpenClaw实现自动化办公时&#xff0c;遇到了一个典型问题&#xff1a;市场部和研发部都需要使用同一个ollama-QwQ-32B模型服务&…...

570-‘基于坠落机制改进的混沌麻雀算法SSACD‘在23个标准测试函数上可直接运行Matlab语言

570-基于坠落机制改进的混沌麻雀算法SSACD在23个标准测试函数测试可直接运行 Matlab语言 改进点如下&#xff1a; 1.首先&#xff0c;引入Sinusoidal混沌映射和变尺度混沌策略对种群进行初始化&#xff0c;提高种群多样性使算法具备跳出局部最优解的能力 2.其次&#xff0c;引入…...

Python内存暴涨突然崩溃?3个被90%开发者忽略的GC调优关键点揭秘

第一章&#xff1a;Python内存暴涨与崩溃的典型现象诊断当Python程序在运行中突然响应迟缓、频繁触发MemoryError&#xff0c;或进程被操作系统强制终止&#xff08;如Linux下收到SIGKILL (9)&#xff09;&#xff0c;往往标志着内存使用已严重失控。这类问题通常不会立即暴露&…...

【网络】Wireshark实战:TCP连接异常之RST报文深度解析

1. 认识TCP的RST报文&#xff1a;网络世界的紧急刹车 第一次在Wireshark里看到RST标志位时&#xff0c;我正盯着满屏的TCP握手包发呆。那个鲜红的[RST, ACK]就像交通信号灯突然变红&#xff0c;让原本流畅的数据传输戛然而止。简单来说&#xff0c;RST&#xff08;Reset&#x…...

隐式建模的革新:GemPy如何重新定义三维地质结构可视化

隐式建模的革新&#xff1a;GemPy如何重新定义三维地质结构可视化 【免费下载链接】gempy GemPy is an open-source, Python-based 3-D structural geological modeling software, which allows the implicit (i.e. automatic) creation of complex geological models from int…...

【紧急通知】Python 3.14 JIT默认profile已触发AWS Lambda冷启动恶化阈值!立即执行这4项低成本开关校准

第一章&#xff1a;Python 3.14 JIT编译器冷启动恶化现象的紧急定性Python 3.14 引入的实验性 JIT 编译器&#xff08;基于 pyjion 改进的 cpython-jit 后端&#xff09;在首次执行高密度计算函数时&#xff0c;观测到显著的冷启动延迟激增——部分基准测试中延迟较 Python 3.1…...

嵌入式按键事件处理框架:高可靠消抖与复合操作状态机

1. Button库深度解析&#xff1a;面向嵌入式系统的高可靠性按键事件处理框架1.1 设计定位与工程价值Button库并非简单的GPIO电平读取封装&#xff0c;而是一个面向工业级嵌入式应用的状态感知型按键事件引擎。其核心设计目标是解决传统按键处理中长期存在的三大工程痛点&#x…...

GHelper轻量级解决方案:华硕笔记本性能调校完全指南

GHelper轻量级解决方案&#xff1a;华硕笔记本性能调校完全指南 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目地址:…...

Polars 2.0快速接入全链路拆解(含Benchmark实测:比Pandas快42.6×,比Dask低68%内存)

第一章&#xff1a;Polars 2.0快速接入全链路概览Polars 2.0 是一个高性能、内存友好的 DataFrame 库&#xff0c;专为现代多核 CPU 和列式分析场景设计。它通过 Rust 编写核心引擎&#xff0c;Python 接口&#xff08;polars-py&#xff09;提供零拷贝数据交互能力&#xff0c…...

电动汽车车队虚拟发电厂的强化学习控制策略探索

电动汽车车队虚拟发电厂的强化学习控制策略 本论文基于 RL 代理的开发&#xff0c;该代理通过家庭环境中的电动汽车充电站管理 VPP。 VPP 的主要优化目标是&#xff1a;填谷、削峰和随时间推移实现零负荷&#xff08;供需负荷平衡&#xff09;。 为实现目标而采取的主要行动是&…...

中关村论坛重磅发布十五项脑机接口成果

当前&#xff0c;脑机接口技术正处于从实验室走向临床应用、从技术突破迈向产业转化的关键时期。中关村论坛重磅发布十五项脑机接口创新成果&#xff0c;聚焦学术创新性、产品合规性、临床突破性与生态共建性四大核心维度&#xff0c;集中呈现我国在该领域的前沿进展。本次发布…...

OpenClaw+GLM-4.7-Flash:自动化会议纪要生成实践

OpenClawGLM-4.7-Flash&#xff1a;自动化会议纪要生成实践 1. 为什么需要自动化会议纪要 每周三下午的团队例会是我最头疼的时刻。作为技术负责人&#xff0c;我需要同时参与讨论、记录关键决策点、跟踪行动项&#xff0c;最后还要整理成文档发给全员。手忙脚乱的结果往往是…...

QT6在Ubuntu20.4上的避坑指南:为什么你的安装总是失败?

QT6在Ubuntu 20.04上的避坑指南&#xff1a;从依赖缺失到环境配置的深度解析 Ubuntu 20.04作为长期支持版本&#xff0c;至今仍是许多开发者的首选系统。然而当你想在这个稳定版本上安装QT6时&#xff0c;可能会遇到各种意想不到的问题——从依赖库冲突到权限错误&#xff0c;从…...

3个维度突破股票数据获取难题:MOOTDX量化分析实战指南

3个维度突破股票数据获取难题&#xff1a;MOOTDX量化分析实战指南 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx 作为量化投资和金融数据分析的核心基础设施&#xff0c;稳定、高效、低成本的股票…...

OpenClaw自动化测试:百川2-13B-4bits模型驱动UI操作与结果验证

OpenClaw自动化测试&#xff1a;百川2-13B-4bits模型驱动UI操作与结果验证 1. 为什么选择OpenClaw百川做自动化测试&#xff1f; 去年接手一个老项目重构时&#xff0c;我遇到了一个典型困境&#xff1a;前端页面有200多个交互点需要回归测试&#xff0c;但团队只有我一个开发…...