Spring AI - ChatClient接口演示

1. ChatClient接口

  • Spring AI 的 ChatClient 是一个面向对话式大模型的统一客户端接口,提供 Fluent API 来组织提示词、发起同步或流式调用,并支持 JSON 结构化响应。它屏蔽了不同 AI 提供商(OpenAI、DeepSeek、ZhiPu 等)的差异,仅需修改配置即可切换模型。通过 prompt()call() 等链式方法,开发者能以极少的代码完成聊天、问答、RAG 等应用开发。

2. ChatClient案例演示

2.1 创建Spring Boot项目

  • 设置项目基本信息
    在这里插入图片描述
  • 选择Spring Boot 3.4.7版本,添加三个项目依赖
    在这里插入图片描述
  • 单击【Create】按钮,生成项目基本骨架
<think>我们使用Spring AI来开发一个智能客服系统。Spring AI是一个新兴的项目,旨在简化在Spring应用中集成人工智能功能。它提供了与OpenAI、Azure OpenAIAI服务交互的便捷方式。 步骤: 1. 添加Spring AI依赖 2. 配置API密钥(如OpenAI) 3. 创建与AI模型交互的服务 4. 创建控制器处理HTTP请求 5. 创建简单的客服对话界面(可选,这里我们可以先实现后端) 我们将使用OpenAI的聊天模型(如gpt-3.5-turbo)作为智能客服的引擎。 详细步骤: 1. 在pom.xml中添加依赖(假设使用Spring Boot和Spring AI): 注意:Spring AI目前可能还在孵化阶段,因此需要添加Spring的里程碑仓库。具体依赖请参考官方文档。 2. 在application.properties或application.yml中配置OpenAI的API密钥。 3. 编写一个服务类,使用Spring AIChatClient来与OpenAI交互。 4. 编写一个REST控制器,接收用户的消息并返回AI的回复。 代码实现: 首先,确保你的项目已经初始化,并且使用了Spring Boot(例如3.x版本)。 添加仓库和依赖(在pom.xml中): ```xml <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> <dependencies> <!-- 其他依赖,如Spring Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring AI OpenAI --> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai-spring-boot-starter</artifactId> <version>0.8.0</version> <!-- 请使用最新版本 --> </dependency> </dependencies> ``` 配置application.properties: ```properties # OpenAI API Key spring.ai.openai.api-key=YOUR_API_KEY # 可选:指定模型,默认是gpt-3.5-turbo spring.ai.openai.chat.model=gpt-3.5-turbo ``` 创建服务类:ChatService ```java import org.springframework.ai.chat.ChatClient; import org.springframework.stereotype.Service; @Service public class ChatService { private final ChatClient chatClient; public ChatService(ChatClient chatClient) { this.chatClient = chatClient; } public String getResponse(String message) { // 调用ChatClient生成回复 return chatClient.call(message); } } ``` 创建控制器:ChatController ```java import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class ChatController { private final ChatService chatService; public ChatController(ChatService chatService) { this.chatService = chatService; } @PostMapping("/chat") public String chat(@RequestBody String userMessage) { return chatService.getResponse(userMessage); } } ``` 这样,我们就创建了一个简单的智能客服后端。当用户发送一个POST请求到/chat,请求体为消息内容,就会返回AI生成的回复。 测试: 可以使用Postman或curl发送POST请求: ``` curl -X POST -H "Content-Type: text/plain" --data "你好,你是谁?" http://localhost:8080/chat ``` 进阶: 为了构建一个完整的客服系统,你可能需要: - 添加上下文管理(例如记住之前的对话) - 设置系统提示词(System Prompt)来定义客服的角色 - 添加持久化存储对话历史 - 前端界面 注意:Spring AIChatClient的call方法默认是无状态的,每次调用都是独立的。为了实现多轮对话,我们需要维护对话历史。 如何维护对话历史? 我们可以使用Spring AI提供的PromptTemplate和ChatMessage来构建包含历史消息的对话。具体步骤如下: 1. 修改ChatService,使其能够存储每个会话的对话历史(注意:这里简单实现,不考虑并发和分布式,实际生产环境需要更健壮的方案)。 2. 使用ChatClient的另一个方法,它可以接受一个Prompt对象,其中包含多个消息(包括历史消息)。 修改后的ChatService(示例,仅展示思路): ```java import org.springframework.ai.chat.ChatClient; import org.springframework.ai.chat.messages.Message; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.SystemPromptTemplate; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; import java.util.Map; @Service public class ChatService { private final ChatClient chatClient; // 系统提示词,用于设定AI的角色 @Value("classpath:/prompts/system-prompt.st") private Resource systemPromptResource; // 存储对话历史,实际中应该以会话ID为键存储,这里简化用全局变量(仅用于演示,不适用于多用户) private List<Message> history = new ArrayList<>(); public ChatService(ChatClient chatClient) { this.chatClient = chatClient; } public String getResponse(String message) { // 读取系统提示词 SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPromptResource); Message systemMessage = systemPromptTemplate.createMessage(Map.of()); // 将历史消息和新的用户消息组合 List<Message> messages = new ArrayList<>(); messages.add(systemMessage); messages.addAll(history); messages.add(new UserMessage(message)); // 调用ChatClient Prompt prompt = new Prompt(messages); AssistantMessage assistantMessage = (AssistantMessage) chatClient.call(prompt).getMessages().getLast(); // 更新历史记录(注意:控制历史记录的长度,避免过长) history.add(new UserMessage(message)); history.add(assistantMessage); return assistantMessage.getContent(); } } ``` 在resources/prompts/system-prompt.st文件中写入系统提示词,例如: ``` 你是一个智能客服助手,负责回答用户关于我们公司产品的问题。你的回答应该专业、友好且简洁。 公司产品包括:A产品、B产品、C产品。 如果用户询问与产品无关的问题,请礼貌地告知用户你只回答与产品相关的问题。 ``` 注意:上述代码中,我们使用了一个全局的history变量来存储对话历史,这在多用户环境下是不行的。实际应用中,应该为每个会话(session)维护一个对话历史列表,并考虑会话超时和内存管理。 以上就是一个基于Spring AI的智能客服系统的简单实现。 相关问题: 1. 如何为不同的用户维护独立的对话历史? 2. 如何限制对话历史的长度以避免过长的上下文? 3. 如何在前端展示对话历史? 4. 除了OpenAISpring AI还支持哪些AI模型?</think>### 使用 Spring AI 开发智能客服系统 Spring AISpring 生态中用于集成 AI 能力的模块,可轻松接入 OpenAI、Azure AI 等服务。以下是实现智能客服系统的完整方案: #### 核心实现步骤 1. **添加依赖** (`pom.xml`): ```xml <dependencies> <!-- Spring AI Starter --> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai-spring-boot-starter</artifactId> <version>0.8.0</version> </dependency> <!-- Web 支持 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> ``` 2. **配置 API 密钥** (`application.yml`): ```yaml spring: ai: openai: api-key: ${OPENAI_API_KEY} # 从环境变量读取 chat: model: gpt-3.5-turbo # 指定模型 temperature: 0.7 # 创造性控制 ``` 3. **服务层实现** (`AiChatService.java`): ```java import org.springframework.ai.chat.ChatClient; import org.springframework.stereotype.Service; @Service public class AiChatService { private final ChatClient chatClient; public AiChatService(ChatClient chatClient) { this.chatClient = chatClient; } public String getResponse(String userMessage) { // 添加系统角色提示词 String prompt = """ 你是一个专业客服助手,请用友好、简洁的方式回答用户问题。 当前服务范围:订单查询、退货政策、产品咨询。 禁止回答与客服无关的问题。 用户问题:%s """.formatted(userMessage); return chatClient.call(prompt); } } ``` 4. **控制器层** (`ChatController.java`): ```java import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/chat") public class ChatController { private final AiChatService chatService; public ChatController(AiChatService chatService) { this.chatService = chatService; } @PostMapping public String handleChat(@RequestBody String userInput) { return chatService.getResponse(userInput); } } ``` 5. **上下文管理** (增强历史记录支持): ```java // 在服务层添加对话历史管理 private final Map<String, List<Message>> sessionHistory = new ConcurrentHashMap<>(); public String getResponse(String sessionId, String userMessage) { List<Message> history = sessionHistory.computeIfAbsent(sessionId, k -> new ArrayList<>()); // 添加历史上下文 StringBuilder context = new StringBuilder(); history.forEach(msg -> context.append(msg.role() + ": " + msg.content() + "\n")); String prompt = context.toString() + "用户: " + userMessage; String aiResponse = chatClient.call(prompt); // 更新历史 history.add(new Message("user", userMessage)); history.add(new Message("assistant", aiResponse)); // 限制历史长度 if(history.size() > 10) history.remove(0); return aiResponse; } ``` #### 功能增强建议 1. **知识库集成**: ```java // 结合向量数据库实现知识检索 @Autowired private VectorStore vectorStore; public String getAugmentedResponse(String query) { // 1. 从知识库检索相关文档 List<Document> docs = vectorStore.similaritySearch(query); // 2. 构建增强提示词 String context = docs.stream() .map(Doc::getContent) .collect(Collectors.joining("\n")); String prompt = """ 基于以下知识库信息回答问题: %s 问题:%s 答案: """.formatted(context, query); return chatClient.call(prompt); } ``` 2. **多模型支持**: ```java // application.yml 配置 spring: ai: openai: api-key: ${OPENAI_KEY} azure: openai: endpoint: https://xxx.openai.azure.com/ api-key: ${AZURE_KEY} // 服务层选择模型 @Autowired private ChatClient openaiClient; @Autowired @Qualifier("azureChatClient") private ChatClient azureClient; public String getResponse(String userInput, boolean useAzure) { return useAzure ? azureClient.call(userInput) : openaiClient.call(userInput); } ``` #### 系统架构图 ``` 用户界面 (Web/App) │ ▼ Spring Boot API │ ├──▶ 会话管理 (Session Storage) ├──▶ 知识检索 (Vector DB) └──▶ AI 服务 (OpenAI/Azure) │ ▼ 响应生成 ``` #### 关键优化点 1. **性能优化**: - 使用异步处理:`@Async` 注解处理耗时请求 - 实现响应流:Server-Sent Events (SSE) 实时输出 ```java @GetMapping("/stream") public Flux<String> streamChat(@RequestParam String message) { return Flux.create(sink -> { chatClient.stream(message) .subscribe( chunk -> sink.next(chunk.getResult().getOutput().getContent()), sink::error, sink::complete ); }); } ``` 2. **安全控制**: - 输入验证:过滤敏感词和恶意指令 - 速率限制:`@RateLimiter` 防止滥用 - 内容审核:集成 Moderation API 3. **监控指标**: - 使用 Micrometer 跟踪: ```java @Timed(value = "ai.response.time", description = "AI响应时间") public String getResponse(...) { ... } ``` #### 部署配置 ```yaml # Kubernetes 部署示例 apiVersion: apps/v1 kind: Deployment spec: containers: - name: ai-agent image: your-registry/ai-customer-service env: - name: OPENAI_API_KEY valueFrom: secretKeyRef: name: ai-secrets key: openai-key resources: limits: memory: 1Gi cpu: "1" ``` ### 常见问题解决方案 1. **超时处理**: ```java @Bean public ChatClient chatClient(OpenAiChatOptions options) { return new OpenAiChatClient(options) .withDefaultTimeout(Duration.ofSeconds(30)); } ``` 2. **成本控制**: ```java // 限制最大token数 spring.ai.openai.chat.options.maxTokens=500 ``` 3. **上下文切换**: ```java // 添加会话重置端点 @PostMapping("/reset/{sessionId}") public void resetSession(@PathVariable String sessionId) { sessionHistory.remove(sessionId); } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酒城译痴无心剑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值