多轮AI记忆不能只按会话号拼接:五道隔离门如何避免串话

会话号只是入口;真正可回灌模型的历史,还要同时通过身份、来源、精确匹配、清洗和窗口门。
摘要| 多轮AI最危险的故障不一定是忘记上下文,而是记住了不属于当前人的上下文。本文基于Microi吾码当前AI会话源码与一组可复现本地探针,拆解粗筛、精确复核、错误清洗、当前消息去重和长会话压缩五道边界,并说明为什么ConversationId不能单独承担授权职责。
✦ ① 会话号相同,不代表这些消息就属于同一次对话
很多多轮AI实现都会从一个ConversationId开始:查出历史消息,按时间排序,再塞回模型。这个流程看起来完整,却漏掉了三个更早的问题:当前登录用户是谁、数据属于哪个租户、同一个会话号来自哪个产品入口。
如果会话号由前端生成,两个入口可能使用相同格式;如果查询只在一段JSON文本里做Like,`chat-12`还可能先捞到`chat-123`。因此ConversationId只能表达业务关联,不能替代授权与精确归属。
风险模型| 串话不是模型“想象”出来的;它往往发生在模型调用前,错误历史已经被服务端装进ChatHistory。
✦ ② 第一门:先用权威租户和当前用户缩小候选集

数据库粗筛只负责控制候选规模;后续每一门都处理一种不同的错误。
当前服务在缺少ConversationId、CurrentUserId或OsClient时直接不恢复上下文。查询`mic_ai_record`时,OsClient来自已认证的调用上下文,Where里再绑定CurrentUserId;会话号只作为Content上的Like条件参与候选查询。
候选集 = 当前OsClient
∩ 当前UserId
∩ Content中可能包含ConversationId
注意:最后一项仍是粗筛,不是最终许可。
这样设计的价值,是先让数据库把几百条候选缩到当前身份范围,同时不把JSON字段搜索冒充精确索引。哪怕前端伪造另一个用户的会话号,也无法把权威UserId一起改掉。
✦ ③ 第二门:Like之后必须解析JSON再做双精确匹配
候选记录读出后,源码会安全解析Content,并分别精确比较Source与ConversationId,而且忽略大小写。只有产品来源和完整会话号同时命中,记录才进入历史。`chat-12`与`chat-123`、工作台与开放接口,就在这里被拆开。

四个维度各自回答一个问题,任何一个不一致都应拒绝回灌。
if (row.Source != request.Source) reject;
if (row.ConversationId != request.ConversationId) reject;
// Like只负责候选召回
// 精确字段才决定是否进入上下文
为什么保留两段式| 数据库粗筛控制成本,内存精确复核守住语义;把任意一段删掉都会牺牲性能或正确性。
✦ ④ 第三门与第四门:错误回答不能变成记忆,当前问题不能出现两遍
历史记录通过归属检查后还不能直接使用。当前实现会排除空内容和运行期错误:显式Error字段、无AI权限提示、开源版无法使用在线AI等响应都不会进入下一轮。否则一次临时故障会被模型当成事实反复引用。
前端通常先保存用户消息,再请求AI。服务端若又把`UserChatMsg`作为本轮输入发送,当前问题会在历史与新消息中出现两次。源码因此只移除最后一条与当前文本完全相同的user记录,保留更早真正重复的业务讨论。
清洗顺序:
1. 去空内容
2. 去运行期错误
3. 按时间恢复顺序
4. 删除最后一条“本轮已保存”的用户消息
5. 再构造ChatHistory
去重边界| 不能把所有相同文本都删掉;用户可能隔了十轮再次追问同一句。只移除最后一次已保存的本轮输入。
✦ ⑤ 第五门:长会话需要摘要加最近窗口,而不是无限回放
当前非摘要记录超过28条时,较早消息会被压成系统摘要,最近20条原始消息继续保留。摘要最多查看靠后的60条旧记录,单条截到260字符,总文本超过6000字符就停止。这个组合同时保护上下文预算与近期细节。
摘要持久化被设计为可降级优化:写入失败不能拖垮当前AI请求。真正参与本轮推理的摘要直接在内存生成;只有满足节奏条件时才异步保存,避免每轮都制造一条新摘要。
- 超过28条非摘要记录才进入长会话压缩,短对话保持原始顺序。
- 最近20条继续以原文参与推理,保住当前任务的动作、参数和纠错细节。
- 旧消息最多取靠后的60条,每条最多260字符,总摘要输入不超过6000字符。
- 摘要写库失败只失去复用优化,不得让当前回答一起失败。
窗口不是遗忘| 旧消息保留压缩后的意图与决定,最近消息保留原文;两者承担不同粒度的记忆。
✦ ⑥ 本地证据探针检查了什么

探针读取当前源码并验证12项可定位约束;结果、命令、退出码、源码哈希均留档。
本轮本地探针结果为12 / 12通过,覆盖三项必填上下文、租户与用户候选约束、Source与ConversationId精确复核、错误清洗、当前消息去重、28条阈值、最近20条窗口,以及摘要的60条、260字符和6000字符上限。
这项证据证明当前检出的源码包含这些门禁,并不等于已对线上租户做了破坏性串话实验,也不证明数据库JSON模糊查询在任意数据量下都有相同性能。证据边界必须与结论写在一起。
可复现边界| 源码SHA-256与结果文件已固定;源码变化后,验证器会因哈希不一致而要求重新取证。
✦ ⑦ 一份可直接执行的多轮记忆清单
- ConversationId只表达关联,不承担租户、用户或产品来源授权。
- 先用权威OsClient与CurrentUserId缩小候选,再对JSON中的Source和完整会话号精确复核。
- 运行期错误、权限提示和空回复不得回灌为历史事实。
- 前端先保存当前问题时,只删除最后一条完全相同的本轮user消息。
- 长会话使用摘要与最近窗口组合,并让摘要持久化可降级。
- 改标题、删除会话等写操作重复使用同一套归属检查,不能只校验列表页。
多轮AI的“记忆力”不是消息越多越好,而是每一条被记住的消息都能说明来自谁、属于哪、为何被保留。Microi吾码AI在这里体现的核心不是一个神奇提示词,而是一组发生在模型调用之前、能够被测试和回读的确定性边界。
结论| 先证明历史属于当前会话,再讨论怎样让模型记得更多;隔离正确性永远排在记忆长度之前。
更多推荐




所有评论(0)