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

Solon AI 开发学习9 - chat - 聊天会话(对话)的记忆与持久化

大语言模型的接口是无状态的服务,如果需要形成有记忆的会话窗口。需要使用“多消息”提示语,把历史对话都输入。

1、使用“聊天会话”接口(ChatSession)

ChatSession 可以记录消息,还可以作为提示语的参数使用(直接输给 chatModel 的提示语,先输给 chatSession)。起到会话记忆的作用。

public void case3() throws IOException {//聊天会话ChatSession chatSession = InMemoryChatSession.builder().maxMessages(10).sessionId("session-1").build(); //安排个会话id//1.chatSession.addMessage(ChatMessage.ofUser("hello")); //添加请求消息chatModel.prompt(chatSession).call();  //(把 chatSession 作为参数)AI消息自动记录到会话里//2.chatSession.addMessage(ChatMessage.ofUser("Who are you?")); //添加请求消息chatModel.prompt(chatSession).stream(); //(把 chatSession 作为参数)AI消息自动汇总并记录到会话里
}

2、基于 Web 的聊天会话记忆参考

import org.noear.solon.ai.chat.ChatModel;
import org.noear.solon.ai.chat.ChatSession;
import org.noear.solon.ai.chat.message.ChatMessage;
import org.noear.solon.ai.chat.session.InMemoryChatSession;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Header;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.web.sse.SseEvent;
import reactor.core.publisher.Flux;import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;@Controller
public class DemoController {@InjectChatModel chatModel;final Map<String, ChatSession> sessionMap = new ConcurrentHashMap<>();//手动转为 sse@Mapping("case3")public Flux<SseEvent> case3(@Header("sessionId") String sessionId, String prompt) throws IOException {ChatSession chatSession = sessionMap.computeIfAbsent(sessionId, k -> InMemoryChatSession.builder().build());chatSession.addMessage(ChatMessage.ofUser(prompt));//注意提示语的参数:chatSessionreturn Flux.from(chatModel.prompt(chatSession).stream()).filter(resp -> resp.hasContent()).map(resp -> new SseEvent().data(resp.getContent()));}
}

3、ChatSession 的持久化定制

InMemoryChatSession 只适合开发测试用。一般需要与业务结合,定制需要的聊天会话实现(比如用 Redis 性能就会比较好)。也可以用 JDBC(Mybql、PgSQL、MongoDb),假如有个 SessionJdbcService 服务,是用于会话的消息执久化管理的。通过定制直接同步数据(仅供参考)

public class JdbcChatSession implements ChatSession {private SessionJdbcService sessionService; private String sessionId;public JdbcChatSession(String sessionId) {this.sessionId = sessionId;}@Overridepublic String getSessionId(){return sessionId;}@Overridepublic List<ChatMessage> getMessages() {//设计时,可以通过时间限制消息,或者具体的数量return sessionService.getMessages(getSessionId(), 100); //只取100条}@Overridepublic void addMessage(ChatMessage... messages) {sessionService.addMessages(getSessionId(), messages);}@Overridepublic void clear() {sessionService.clearMessages(getSessionId());}
}

4、ChatSession 的接口字典(参考)

public interface ChatSession extends ChatPrompt {/*** 获取会话id*/String getSessionId();/*** 获取消息*/List<ChatMessage> getMessages();/*** 添加消息*/default void addMessage(String userMessage) {addMessage(ChatMessage.ofUser(userMessage));}/*** 添加消息*/default void addMessage(ChatMessage... messages) {addMessage(Arrays.asList(messages));}/*** 添加消息*/default void addMessage(ChatPrompt prompt) {addMessage(prompt.getMessages());}/*** 添加消息*/void addMessage(Collection<? extends ChatMessage> messages);/*** 清空消息*/void clear();/// ///////////////////////////////////////*** 转为 ndjson*/default String toNdjson() throws IOException {ByteArrayOutputStream out = new ByteArrayOutputStream();toNdjson(out);return new String(out.toByteArray(), Solon.encoding());}/*** 转为 ndjson*/default void toNdjson(OutputStream out) throws IOException {for (ChatMessage msg : getMessages()) {out.write(ChatMessage.toJson(msg).getBytes(Solon.encoding()));out.write("\n".getBytes(Solon.encoding()));out.flush();}}/*** 加载 ndjson*/default void loadNdjson(String ndjson) throws IOException {loadNdjson(new ByteArrayInputStream(ndjson.getBytes(Solon.encoding())));}/*** 加载 ndjson*/default void loadNdjson(InputStream ins) throws IOException {try (BufferedReader reader = new BufferedReader(new InputStreamReader(ins))) {while (true) {String json = reader.readLine();if (Utils.isEmpty(json)) {break;} else {addMessage(ChatMessage.fromJson(json));}}}}
}
http://www.jsqmd.com/news/59322/

相关文章:

  • 2025比较出名的留学机构
  • 常州有哪些ERP企业推荐?本地及国内优质服务商盘点
  • 2025北京留学中介十大排名
  • 常州靠谱的ERP企业有哪些?本地及国内优质服务商盘点
  • Mac Airmail 5 v5.7.0.dmg 邮件客户端安装教程 附详细步骤图解
  • 2025深莞惠消防技术服务公司TOP5权威测评:深圳市安富消
  • 看到一篇文章,轻松戒掉短视频,改变习惯。先抄下来,再修改一下实践。
  • 盘点2025年口碑最佳的镀锌打包扣品牌,前三名实至名归。铝锭打包带/铜棒打包带/冷镀锌打包带/五金打包带镀锌打包扣源头厂家哪个好
  • 天谋科技参与筹备中国科协联合国咨商开源创新专业委员会
  • 5日均线VS10日均线
  • 2025年纸箱装箱机源头厂家权威推荐榜单:侧边封箱机‌/抓取装箱机‌/纸箱机‌源头厂家精选
  • 口碑好的芝士条全自动生产线源头厂家有哪些?
  • 2025年深圳消防安全技术服务公司排行榜,看看哪家服务性价比
  • 深入解析Oracle数据库的启动、访问与关闭机制
  • dumps 和dump
  • 2025 年质量好的成都艺术玻璃生产厂家实力推荐榜
  • 成都地区有实力的夹丝玻璃定制公司哪家好?求口碑推荐
  • 成都夹丝玻璃哪家好?如何选择适合自己的夹丝玻璃厂家
  • 2025年花灯厂家实力榜:生肖花灯谁家强?,评价好的花灯产品排行华景灯彩专注行业多年经验,口碑良好
  • 2025 年 12 月成都智能镜公司最新排名出炉!破局行业乱象
  • 从包过滤到深度检测:防火墙的演进之路
  • 麒麟V10 ARM架构Docker部署GreatSQL+Nacos+Kkfile+Nginx+Redis
  • 2025年南宁合规法律科技公司排名:南宁惠恩科技公司资质齐全
  • 2025年光亮小扁钢源头厂家权威推荐榜单:冷拉扁钢/工具钢/不锈钢扁钢生产厂家精选
  • 2025年12月全国拉森钢板桩厂家十大推荐出炉!深基坑支护工程首选!
  • 2026推荐PE电缆填充条机器公司-阳光机械PE发泡电缆填充条生产线
  • 2025年五大实力不错的GEO推广企业推荐:看看哪家服务性价
  • 2025年焊烟净化器实力分析报告出炉:技术革新驱动绿色制造新标准
  • API的集成与守护:高效使用与必须知道的安全要点
  • 2025年焊接打磨房厂家分析报告:济南华信环保凭什么成为行业标杆?