Spring AI教程(二)Chat API之上下文对话

本文介绍了如何通过在ChatGPT中实现上下文对话功能,通过Message接口和队列管理来存储用户和AI的交互历史,以便AI根据之前的信息进行回复。同时提及了OpenAI的计费规则对消息队列长度的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上下文对话

 上下文对话的作用就是让AI具有记忆力,在快速入门流式对话中,我们是通过一种单一的输入输出方式进行调用的,这种调用方式无法让AI具有记忆力,例如,当我发起如下问题时:

  • hi
  • 中国的四大名著有哪些?
  • 本次对话中,我的第一个问题是什么?

 可以看到,AI无法根据之前的对话内容进行分析回复。因此,这就要求我们实现一个可以让ChatGPT具有一定的记忆力,并根据过去的聊天信息进行回复。

 ChatGPT上下文对话的实现原理较为简单,本质上其实就是将不同角色的聊天信息依次存储在一个队列中发送给ChatGPT即可,然后ChatGPT会根据整个聊天信息对回复内容进行判断。在OpenAI提供的接口中,每条信息的角色总共分为三类:

  • SystemMessage:系统限制信息,这种信息在对话中的权重很大,AI会优先依据SystemMessage里的内容进行回复;
  • UserMessage:用户信息
  • AssistantMessage:AI回复信息

还有一个FunctionMessage,这类信息用于AI的函数调用,一般不予以讨论。

 这些Message均实现了一个Message接口,如上图。AbstractMessage提供了对Message接口的抽象实现,SystemMessageUserMessageAssistantMessage等均继承了AbstractMessage,是Message的具体实现。而ChatMessage是Message的扩展实现,用于创建其它大语言模型需要的Message。

通俗点讲就是有些AI的Message不支持这类System、User、Assistant等,这时,我们就可以通过ChatMessage去自定义创建可用的Message对象了。

 如果我们需要实现上下文对话,就只需要使用一个List存储这些Message对象,并将这些Message对象一并发送给AI,AI拿到这些Message后,会根据Message里的内容进行回复。
不过,根据OpenAI的计费规则,你的消息队列越长,单次问询需要的费用就会越高,因此我们需要对这个消息列表的长度进行限制。

package com.ningning0111.controller;

import org.springframework.ai.chat.C
### 使用 Spring 和 Alibaba 技术实现带有上下文记忆的聊天机器人 #### 设计思路 为了创建一个具备上下文记忆功能的聊天应用,可以采用微服务架构并利用Spring Cloud Alibaba组件来管理分布式系统的复杂性。通过引入Nacos作为注册中心和服务发现工具,Sentinel用于流量防护和熔断降级机制,Seata处理跨服务事务一致性问题。 #### 关键技术选型 - **后端框架**: 基于Spring Boot快速搭建基础环境,并集成Spring AI Alibaba模块以增强自然语言理解和生成的能力[^1]。 - **会话状态存储**: Redis被广泛应用于缓存用户交互历史记录,确保每次请求都能获取到完整的对话背景信息。 - **消息队列**: Kafka可用于异步通信模式下传递事件通知给各个子系统之间同步数据更新操作。 #### 实现步骤概述 定义实体类表示用户的输入输出对象;编写控制器接收HTTP POST请求并将参数转发至业务逻辑层进行解析处理;调用第三方API接口查询外部资源或执行具体动作指令前先判断当前话题是否已经存在关联的历史记录;最后返回响应结果给客户端展示界面。 ```java @RestController @RequestMapping("/chatbot") public class ChatBotController { @Autowired private ChatService chatService; @PostMapping(value = "/talk", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<ChatResponse> talk(@RequestBody ChatRequest request){ String userId = request.getUserId(); String messageText = request.getMessage(); // Check and load conversation history from redis cache by user id. List<String> contextHistory = redisTemplate.opsForList().range(userId, 0 ,-1); // Pass the loaded context to service layer for processing along with new incoming messages. ChatResponse response = this.chatService.processMessage(messageText,contextHistory); // Save current interaction back into redis as part of ongoing session data. redisTemplate.opsForList().rightPush(userId,messageText); return ResponseEntity.ok(response); } } ``` 上述代码片段展示了如何在一个RESTful API中处理来自前端的消息,并且考虑到了保持连续性的需求——即保存之前的交流内容以便后续参考。每当收到新消息时都会尝试从Redis数据库读取该用户的过往对话列表,之后再把这些资料一并发往负责实际应答的服务单元做进一步分析计算得出最终答复后再追加进对应的链表里头去形成新的条目等待下次访问时候能够再次提取出来使用[^2]。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

PG Thinker

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

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

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

打赏作者

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

抵扣说明:

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

余额充值