AI 超级智能体 - 历史消息存储Advisor
在实现自定义mysql存储消息时发现,ChatMemory和MessageWindowChatMemory都是只能维持当前窗口的消息,即maxMessage窗口内的消息。一但消息超过maxMessage,就会进行一次覆盖。若是在自定义mysql存储消息实行增量存储而不覆盖的话,llm的上下文记忆又会出错,因此我在自定义mysql存储消息时也和内存和文件存储一样使用了覆盖并实现了这个历史消息存储Advisor,在消息发送和llm输出时实现拦截并将消息存储到mysql中,存储整个会话的所有消息。
▼text复制代码@Resource private HistoryMessageMapper historyMessageMapper; private int order = 1; public MessageToDBAdvisor() { } @Override public ChatClientResponse adviseCall(ChatClientRequest chatClientRequest, CallAdvisorChain callAdvisorChain) { HistoryMessage userHistoryMessage = before(chatClientRequest); ChatClientResponse chatClientResponse = callAdvisorChain.nextCall(chatClientRequest); after(chatClientResponse, chatClientRequest, userHistoryMessage); return chatClientResponse; } @Override public Flux<ChatClientResponse> adviseStream(ChatClientRequest chatClientRequest, StreamAdvisorChain streamAdvisorChain) { HistoryMessage userHistoryMessage = before(chatClientRequest); Flux<ChatClientResponse> chatClientResponseFlux = streamAdvisorChain.nextStream(chatClientRequest); return afterFlux(chatClientResponseFlux, chatClientRequest, userHistoryMessage); } private Flux<ChatClientResponse> afterFlux(Flux<ChatClientResponse> chatClientResponseFlux, ChatClientRequest chatClientRequest, HistoryMessage userHistoryMessage) { String conversationId = chatClientRequest.context().get("chat_memory_conversation_id").toString(); String model = chatClientRequest.prompt().getOptions().getModel(); StringBuilder contentBuilder = new StringBuilder(); AtomicInteger promptTokens = new AtomicInteger(0); AtomicInteger completionTokens = new AtomicInteger(0); Flux<ChatClientResponse> responseFlux = chatClientResponseFlux.doOnNext(chatClientResponse -> { String chunk = chatClientResponse.chatResponse().getResult().getOutput().getText(); if (StrUtil.isNotBlank(chunk)) { contentBuilder.append(chunk); } promptTokens.set(chatClientResponse.chatResponse().getMetadata().getUsage().getPromptTokens()); completionTokens.set(chatClientResponse.chatResponse().getMetadata().getUsage().getCompletionTokens()); }).doOnComplete(() -> { String content = contentBuilder.toString(); HistoryMessage assistantHistoryMessage = new HistoryMessage(); assistantHistoryMessage.setConversationId(conversationId); assistantHistoryMessage.setRole(MessageType.ASSISTANT.getValue()); assistantHistoryMessage.setModel(model); assistantHistoryMessage.setContent(content); assistantHistoryMessage.setTokenCount(completionTokens.get()); historyMessageMapper.insert(assistantHistoryMessage); userHistoryMessage.setTokenCount(promptTokens.get()); historyMessageMapper.updateById(userHistoryMessage); }); return responseFlux; } public HistoryMessage before(ChatClientRequest chatClientRequest) { String conversationId = chatClientRequest.context().get("chat_memory_conversation_id").toString(); String model = chatClientRequest.prompt().getOptions().getModel(); String content = chatClientRequest.prompt().getUserMessage().getText(); HistoryMessage userHistoryMessage = new HistoryMessage(); userHistoryMessage.setConversationId(conversationId); userHistoryMessage.setModel(model); userHistoryMessage.setRole(MessageType.USER.getValue()); userHistoryMessage.setContent(content); historyMessageMapper.insert(userHistoryMessage); return userHistoryMessage; } public void after(ChatClientResponse chatClientResponse, ChatClientRequest chatClientRequest, HistoryMessage userHistoryMessage) { String conversationId = chatClientRequest.context().get("chat_memory_conversation_id").toString(); String model = chatClientRequest.prompt().getOptions().getModel(); String content = chatClientResponse.chatResponse().getResult().getOutput().getText(); Integer promptTokens = chatClientResponse.chatResponse().getMetadata().getUsage().getPromptTokens(); Integer completionTokens = chatClientResponse.chatResponse().getMetadata().getUsage().getCompletionTokens(); HistoryMessage assistantHistoryMessage = new HistoryMessage(); assistantHistoryMessage.setConversationId(conversationId); assistantHistoryMessage.setRole(MessageType.ASSISTANT.getValue()); assistantHistoryMessage.setModel(model); assistantHistoryMessage.setContent(content); assistantHistoryMessage.setTokenCount(completionTokens); userHistoryMessage.setTokenCount(promptTokens); historyMessageMapper.updateById(userHistoryMessage); historyMessageMapper.insert(assistantHistoryMessage); } @Override public int getOrder() { return this.order; } @Override public String getName() { return this.getClass().getSimpleName(); }
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
内容推荐
day39学到ai服务化了,腾讯云托管没有弄好,好像没有小程序和公众号账号,明天搞一个试试。基本上ai智能体和ai恋爱大师开发完了。但是,很多扩展内容没有做好,还有不能自己完整讲述清楚原理。后面还要自己独立完成一遍,然后再写进简历里。另外还缺少了很多agent知识。跟进java知识,ai项目,还有每日算法。这个星期ai智能体初步阶段应该能完成了。
3
Day 10✅ 今天做了:claude code开发了一个网站⏰ 明天计划:学前端
1
Day 11✅ 今天做了:前端整体布局, 动态菜单栏⏰ 明天计划:进入前端项目实战📚 今日感悟:vue组件层层嵌套
1
day40ai服务化学完了,也部署成功了。前端真的全是ai生成的,没有写一行代码。ai恋爱大师,ai超级智能体,两个应用。感觉后续可以优化一下界面,没有ai思考的过程,然后很多东西要优化。我发现生成的pdf文件不能下载,以前在后端代码页面的时候可以直接找到目录,但是ai对话页面是看不到的。所以,生成的文档我看不到也下载不了。这个我希望优化一下,天气,恋爱咨询感觉还可以,然后就是,每次恋爱咨询回复太
2
Day 12✅ 今天做了:vue前端, 了解vue - Nginx - springboot关系⏰ 明天计划:继续搞前端的功能实现
3

