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

基于SpringAI实现简易聊天对话

简介
本文旨在记录学习和实践 Spring AI Alibaba 提供的 ChatClient 组件的过程。ChatClient 是 Spring AI 中用于与大语言模型(LLM)进行交互的高级 API,它通过流畅(Fluent)的编程接口,极大地简化了构建聊天应用程序的复杂度。相比直接使用底层的 ChatModel,ChatClient 封装了提示词构建、响应处理、结构化输出、流式响应以及与 RAG、聊天记忆等高级功能的集成。
通过本文的学习,我们将掌握:

ChatClient 的核心概念和优势。
如何创建和配置 ChatClient 实例。
使用 ChatClient 处理不同类型的 AI 响应(文本、完整响应对象、结构化实体、流式响应)。
结合 Spring Boot 快速搭建一个可交互的聊天后端服务。
了解 Server-Sent Events (SSE) 在流式响应中的应用。

我们将从官方文档入手,结合代码实践,逐步深入理解 ChatClient 的使用方法。

ChatClient相关原理
在这里插入图片描述
核心知识点:ChatClient in Spring AI Alibaba
ChatClient 是 Spring AI Alibaba 提供的一个更高级别的 API,用于与 AI 模型进行交互。它旨在简化开发流程,特别是当应用程序需要组合多个组件(如提示词模板、聊天记忆、模型本身、输出解析器、RAG 组件等)时。

  1. ChatClient 简介

目的: 提供一个 Fluent API (流畅 API) 与 AI 模型通信,支持同步和反应式 (Reactive) 编程模型。
优势:

隐藏复杂性: 将与 LLM (Large Language Model) 及其他组件(提示词模板、聊天记忆、RAG 等)交互的复杂性封装起来。
减少样板代码: 相比直接使用 ChatModel、Message 等原子 API,ChatClient 减少了需要编写的重复性代码。
类似服务层: 在应用程序中扮演类似服务层 (Service Layer) 的角色,直接为应用提供 AI 服务。
快速组装交互流程: 使用 Fluent API 可以快速地组装一个完整的 AI 交互流程。

基础功能:

定制和组装模型的输入 (Prompt)。
格式化解析模型的输出 (结构化输出 Structured Output)。
调整模型交互参数 (ChatOptions)。

高级功能:

聊天记忆 (Chat Memory)。
工具/函数调用 (Function Calling)。
检索增强生成 (RAG)。

  1. 创建 ChatClient
    创建 ChatClient 实例需要使用 ChatClient.Builder 对象。有两种主要方式获取 ChatClient:

方式一:使用自动配置的 ChatClient.Builder (推荐)

Spring Boot 会根据你的依赖和配置自动创建一个默认的 ChatClient.Builder Bean。
你只需要在你的类中注入这个 ChatClient.Builder,然后调用 build() 方法即可获得 ChatClient 实例。
示例代码 (带详细注释):

import org.springframework.ai.chat.client.ChatClient; // 导入 ChatClient 类
import org.springframework.web.bind.annotation.GetMapping; // 导入 GetMapping 注解,用于处理 HTTP GET 请求
import org.springframework.web.bind.annotation.RequestParam; // 导入 RequestParam 注解,用于获取请求参数
import org.springframework.web.bind.annotation.RestController; // 导入 RestController 注解,标识这是一个 RESTful 控制器 // 声明这是一个 Spring MVC 的 REST 控制器,其方法默认返回 JSON 或其他指定格式的数据
public class ChatController {// 声明一个 final 的 ChatClient 成员变量,用于与 AI 模型交互private final ChatClient chatClient;// 控制器的构造函数// Spring Boot 会自动查找并注入一个 ChatClient.Builder 类型的 Beanpublic ChatController(ChatClient.Builder builder) {// 使用注入的 builder 构建 ChatClient 实例,并赋值给成员变量// builder 会使用自动配置好的底层 ChatModel (例如通义千问模型) 和其他默认设置this.chatClient = builder.build();}("/chat") // 将 HTTP GET 请求映射到 /chat 路径// @RequestParam("input") String input 表示从请求参数中获取名为 "input" 的值,并赋给 input 变量public String chat(("input") String input) {// 使用 chatClient 的 Fluent API 开始构建一个请求return this.chatClient.prompt() // 1. 调用 prompt() 方法开始构建一个 Prompt (提示).user(input)          // 2. 调用 user() 方法设置用户角色的消息内容,内容为传入的 input 字符串.call()               // 3. 调用 call() 方法,执行与 AI 模型的同步调用 (发送请求并等待响应).content();           // 4. 调用 content() 方法,从 AI 模型的响应 (ChatResponse) 中提取文本内容并返回}
}

方式二:以编程方式创建 ChatClient

禁用自动配置: 如果你想完全控制 ChatClient 的创建过程,或者需要使用多个不同的 ChatModel 实例,可以先禁用 ChatClient.Builder 的自动配置。在 application.properties 或 application.yml 中设置:

spring.ai.chat.client.enabled=false

手动创建: 然后,你可以手动创建 ChatClient.Builder,并传入你想要使用的 ChatModel 实例。
示例代码 (带详细注释):

import org.springframework.ai.chat.client.ChatClient; // 导入 ChatClient 类
import org.springframework.ai.chat.model.ChatModel;   // 导入 ChatModel 接口// ... 其他 importpublic class MyService {private final ChatClient customChatClient;// 假设 myChatModel 是你通过其他方式配置或注入的特定 ChatModel 实例public MyService(ChatModel myChatModel) {// 方法一:使用 ChatClient.builder() 静态方法,并传入 ChatModel 实例ChatClient.Builder builder = ChatClient.builder(myChatModel);// 这里可以继续使用 builder 配置其他选项,例如 .defaultOptions(), .defaultSystem(), etc.this.customChatClient = builder.build(); // 构建 ChatClient 实例// 方法二:使用 ChatClient.create() 静态方法,这是一个更简洁的方式// 它会使用传入的 ChatModel 和默认的 Builder 设置来创建 ChatClient// this.customChatClient = ChatClient.create(myChatModel);}public String askSomething(String question) {// 使用手动创建的 customChatClient 进行交互return customChatClient.prompt().user(question).call().content();}
}
  1. 处理 ChatClient 响应
    ChatClient API 提供了多种方式来处理和格式化来自 AI 模型的响应:

返回 ChatResponse:

call() 或 stream() 方法默认返回 ChatResponse 对象。
ChatResponse 是一个丰富的结构,包含:

AI 生成的实际结果 (Generation)。
与响应生成相关的元数据 (例如模型名称、token 使用情况等)。
可能包含多个子响应结果 (如果模型支持,例如返回多个候选答案)。

你可以从 ChatResponse 中获取详细信息。
示例: (在上面的 /chat 接口示例中,.call() 返回的就是 ChatResponse,之后 .content() 是从中提取内容)

返回实体类 (Entity) - 结构化输出:

ChatClient 支持将 AI 模型的文本输出自动映射为你定义的 Java POJO (Plain Old Java Object)。这对于需要固定格式输出的场景非常有用。
使用 .entity(YourClass.class) 方法来指定期望的输出类型。
示例代码 (带详细注释):

import org.springframework.ai.chat.client.ChatClient; // 导入 ChatClient 类
import org.springframework.web.bind.annotation.GetMapping; // 导入 GetMapping 注解
import org.springframework.web.bind.annotation.RequestParam; // 导入 RequestParam 注解
import org.springframework.web.bind.annotation.RestController; // 导入 RestController 注解
public class StructuredOutputController {private final ChatClient chatClient;// 定义一个简单的 POJO 类,用于接收结构化输出static class ActorFilms {public String actor; // 演员姓名public List<String> movies; // 电影列表}public StructuredOutputController(ChatClient.Builder builder) {this.chatClient = builder.build();}("/actor-films") // 将 HTTP GET 请求映射到 /actor-films 路径public ActorFilms getActorFilms(("actor") String actorName) {// 使用 chatClient 的 Fluent APIreturn this.chatClient.prompt()// 设置用户消息,要求模型列出指定演员的电影,并明确要求 JSON 格式.user("Generate a list of films for the actor " + actorName + ". Respond in JSON format with keys 'actor' and 'movies'.").call() // 执行与 AI 模型的同步调用// 调用 entity() 方法,并传入 ActorFilms.class// ChatClient 会尝试将 AI 返回的文本内容 (预期是 JSON 字符串)// 解析并映射到 ActorFilms 类的实例中.entity(ActorFilms.class);}
}

流式响应 (Streaming):

对于需要实时显示或处理部分结果的场景 (例如聊天机器人),可以使用流式响应。
调用 .stream() 方法代替 .call()。
.stream() 方法返回一个 Flux (如果使用了 Reactive 库) 或支持类似的流式处理机制。你可以订阅这个流来接收模型逐步生成的内容块。
示例代码 (概念性,具体实现依赖 Reactive 库如 Project Reactor):

import org.springframework.ai.chat.client.ChatClient; // 导入 ChatClient 类
import org.springframework.http.MediaType; // 导入 MediaType 类
import org.springframework.web.bind.annotation.GetMapping; // 导入 GetMapping 注解
import org.springframework.web.bind.annotation.RequestParam; // 导入 RequestParam 注解
import org.springframework.web.bind.annotation.RestController; // 导入 RestController 注解
import reactor.core.publisher.Flux; // 导入 Flux 类 (来自 Project Reactor)
import org.springframework.ai.chat.model.ChatResponse; // 导入 ChatResponse 类
public class StreamingChatController {private final ChatClient chatClient;public StreamingChatController(ChatClient.Builder builder) {this.chatClient = builder.build();}// produces = MediaType.TEXT_EVENT_STREAM_VALUE 指定响应类型为 Server-Sent Events (SSE)(value = "/stream-chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<String> streamChat(("input") String input) {// 使用 chatClient 的 Fluent APIreturn this.chatClient.prompt().user(input) // 设置用户消息.stream()    // 1. 调用 stream() 方法,启动与 AI 模型的流式交互,返回 Flux<ChatResponse>.content();  // 2. 调用 content() 方法 (针对 Flux),将 ChatResponse 流映射为 String 内容流//    每次模型生成一部分内容,就会在这个 Flux 中发布一个 String 片段}// 如果需要更详细的流信息,可以直接处理 Flux<ChatResponse>(value = "/stream-chat-response", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<ChatResponse> streamChatResponse(("input") String input) {return this.chatClient.prompt().user(input).stream() // 直接返回 ChatResponse 的流.chatResponse(); // 获取原始的 ChatResponse 流}
}
  1. 定制 ChatClient 默认值
    可以在创建 ChatClient 时设置一些默认行为,这些默认值会应用于该 ChatClient 实例发出的所有请求,除非在单次请求中被覆盖。

设置默认系统消息 (System Message):

系统消息通常用于给 AI 模型设定角色、提供指令或上下文背景。
在 ChatClient.Builder 上调用 .defaultSystem(…) 方法。

ChatClient chatClient = ChatClient.builder(chatModel)// 设置默认的系统消息,告诉 AI 它是一个乐于助人的 AI 助手.defaultSystem("You are a helpful AI assistant.").build();// 后续使用这个 chatClient 发送请求时,会自动带上这个系统消息
chatClient.prompt().user("What is the capital of France?").call().content();

其他默认设置:

默认用户消息: .defaultUser(…)
默认模型选项: .defaultOptions(…),可以设置温度 (temperature)、最大 token 数 (maxTokens) 等模型参数。
默认函数: .defaultFunctions(…) (用于 Function Calling)
默认头信息: .defaultHeaders(…) (可能用于特定模型的 API 调用)

  1. Advisors (增强器/顾问)

Advisors 是一种强大的机制,用于向 ChatClient 的请求/响应流程中添加额外的功能,类似于中间件 (Middleware) 或 AOP (Aspect-Oriented Programming) 中的切面。
它们可以在请求发送前对其进行修改,或者在收到响应后对其进行处理。
通过 ChatClient.Builder 的 .defaultAdvisors(…) 方法添加。
常见的 Advisors 应用场景:

检索增强生成 (RAG): 在发送用户问题给 LLM 之前,先从知识库 (Vector Store) 中检索相关文档,并将文档内容添加到提示词中。QuestionAnswerAdvisor 是一个常见的 RAG Advisor。
聊天记忆 (Chat Memory): 在发送请求前,从 ChatMemory 组件中加载历史对话记录,并将其添加到提示词中;在收到响应后,将当前的问答对保存到 ChatMemory 中。ChatMemoryAdvisor 用于此目的。
日志记录: 记录请求和响应的详细信息。

示例 (概念性):

// 假设 vectorStore 和 chatMemory 是已经配置好的 Bean
VectorStore vectorStore = ...;
ChatMemory chatMemory = ...;ChatClient chatClient = ChatClient.builder(chatModel)// 添加一个 RAG Advisor,使用指定的 VectorStore 进行检索.defaultAdvisors(new QuestionAnswerAdvisor(vectorStore))// 添加一个聊天记忆 Advisor.defaultAdvisors(new ChatMemoryAdvisor(chatMemory)).build();// 现在使用这个 chatClient 时,会自动进行 RAG 检索和聊天记忆管理
chatClient.prompt().user("Tell me about Spring AI based on my previous questions.").call().content();

总结:
ChatClient 是 Spring AI Alibaba 中进行 AI 模型交互的核心组件之一。它通过 Fluent API 极大地简化了与 AI 模型的通信,隐藏了底层实现的复杂性,并提供了强大的功能,如结构化输出、流式响应和通过 Advisors 实现的 RAG、聊天记忆等高级特性。掌握 ChatClient 的使用对于在 Spring 应用中高效地集成 AI 功能至关重要。

资料推荐

💡大模型中转API推荐
✨中转使用教程

相关文章:

  • Python PyTorch库【机器学习框架】全面深入讲解与实践
  • windows 使用 FFmpeg 放大视频原声
  • BUUCTF——Online Tool
  • nextcloud私有网盘系统搭建
  • 百度语音合成API调用
  • SOLIDWORKS广东东莞地区代理商哪个服务好?都有哪些代理商?
  • 1.1 点云数据获取方式——引言
  • 图漾官网Sample_V1版本C++语言完整参考例子---单相机版本
  • Java练习6
  • 大数据项目全生命周期工具链解析
  • ​MCP协议深度解析:原理、应用与物联网时代的机遇-优雅草卓伊凡
  • 认识Linux基本操作、命令
  • Spring Boot 集成 ActiveMQ 实现异步消息通信(二)
  • 面试篇 - LoRA(Low-Rank Adaptation) 原理
  • 《图像采集与处理技术的研究与洞察》
  • Vue 3 浏览器使用 Composition API
  • 开源模型应用落地-qwen模型小试-Qwen3-8B-快速体验(一)
  • 在 JMeter 中使用 BeanShell 获取 HTTP 请求体中的 JSON 数据
  • 【计算机架构】CISC(复杂指令集计算机)架构
  • 【Science】强耦合手性准BIC驱动动量空间可编程高Q圆偏振激光——哈工大突破拓扑光子学新维度
  • 辽宁省委书记、省长连夜赶赴辽阳市白塔区火灾事故现场,指导善后处置工作
  • 国际锐评:菲律宾“狐假虎威”把戏害的是谁?
  • 中国建设银行浙江省分行原党委书记、行长高强接受审查调查
  • 辽宁辽阳市白塔区一饭店发生火灾,事故已造成22人遇难3人受伤
  • 五一假期如何躺赚利息?来看国债逆回购操作攻略
  • 药明康德一季度净利增长89%,在手订单增超四成至523亿元