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应用。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2463580.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!