qpeter
Java后端
·昨天 23:50
Day 6 ✅ 今天做了: 1. 复习昨日内容 2. 零代码:对话历史模块-后端开发 3. 零代码:对话历史模块-前端开发 4. 零代码:对话历史模块-对话记忆 5. AI速通第五章 ⏰ 明天计划: 1. 复习今日内容 2. 零代码:工程项目生成-方案设计 3. 零代码:工程项目生成-生成功能 4. 零代码:工程项目生成-构建部署 5. 零代码:工程项目生成-前端和扩展 6. AI速通第六章 📚 今日感悟: 1. 今天最值的一件事,是把 LangChain4j 的对话记忆彻底搞清楚了:记忆根本不在 AiService 实例里。 a. 我一开始的判断是——实例创建的时候从数据库把历史加载到 Redis,之后再发给模型,所以后续对话的记忆不会更新,Redis 是"死"的 b. 通过 AI 把 MessageWindowChatMemory 的字节码和源码拆开看才发现,这个类只有 id、maxMessages、store 三个字段,压根没有装消息的 List。messages() 每次都是 new LinkedList(store.getMessages(id)),add() 每次都是"读 store → 追加 → 整份写回" c. 结论:每次调模型前都从 Redis 现读一次,每轮的 userMessage 和 AI 回复也都自动写回 Redis,增量是框架自己写的,跟数据库一点关系都没有。我以为的那个 bug,前提就是错的 2. 顺着又搞清楚:数据库那份对话历史和 Redis 那份,从来就没有同步机制,是两份完全独立的数据。 a. MySQL 那份是我自己手写的,给前端看;Redis 那份是框架自动写的,给模型看 b. 两者唯一的交汇点,就是 loadChatHistoryToMemory 那一次性的拷贝,之后再无往来 c. 具体表现:流失败那一轮,数据库里多一条"AI回复失败:xxx",Redis 里没有;AI 回复超过 text 长度那一轮,Redis 有、数据库没有。两边长得完全不一样 3. 学会了多实例的管理——Caffine,之前在 AI 超级智能体中加入 AskHuman 后,需要暂停对话再回复对话,这里就存在了多个实例的管理,多个会话就会存在多个实例,当时没想内存的事,直接使用 ConcurrentHashMap 通过 ChatId 和实例来管理每个会话实例,今天学 Caffine 来缓存 Aiservice 让我想到 AI 超级智能体多实例也完全可以这样,这样就能使用 Caffine 的淘汰策略去管理内存了
0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
下载 APP