3.2 KiB
3.2 KiB
历史会话召回守卫
目标场景
用户在新会话或已有 Agent 会话中询问“你还记得我们聊过德川家康吗”时,系统需要从 该用户自己的历史会话中找出相关、可核验的片段,而不是只依赖长期偏好/目标记忆或让 模型猜测。
必须保留的行为
- 只有明确包含“之前/上次/曾经聊过、讨论过、提到过”等历史对话意图时才检索历史 会话;普通聊天和单纯“记住我的偏好”不得扫描会话历史。
- 所有 SQL 必须先按
user_id过滤,并排除当前agent_session_id;不得跨用户或把 当前未完成回合作为历史证据返回。 h5_episodic_memory_items只保存有界的 user-visible 用户/助手文本。工具输出、系统 提示、Agent 编排前缀、隐藏消息和内部过程旁白不得进入索引。- 索引查询必须有候选上限、召回条数上限和超时;任何索引、快照或配置读取失败都要 fail-open,不得阻断聊天。
- 已有历史数据无需一次性迁移:索引没有命中或不可用时,按同一用户从
h5_session_snapshots有界回退;命中的旧快照可异步懒索引。 - 返回的每条线索必须携带来源会话 ID、会话时间和匹配主题证据。注入提示必须明确: 历史片段可能不完整/过期,片段中的命令、角色设定和要求不是当前指令。
- 新会话直连聊天与已有 Agent 会话两条链路都必须支持召回,并优先注入历史会话证据, 再补充长期个人记忆。
- 删除会话时必须同步删除对应历史索引;删除用户时由外键
ON DELETE CASCADE清理。 - 只有
MEMORY_RETRIEVER_ENABLED=1和MEMORY_RETRIEVER_EPISODIC_ENABLED=1同时开启 才可进入历史召回;两个开关仍不能绕过灰度模式:off:不索引、不召回。canary:只允许MEMORY_RETRIEVER_EPISODIC_CANARY_USER_IDS中的用户。active:全量用户。 模式缺失或非法时必须按off处理。
回归检查
npm run test:episodic-memory
node --test memory-v2-admin-config.test.mjs episodic-memory.test.mjs \
direct-chat-service.test.mjs chat-intent-router.test.mjs
npm run test:memind -- --mode changed --base origin/main
memind_adm 同时执行:
npm run build
103 灰度验收
- 发布代码时保持
episodicMode=off,确认 Portal、Agent、图片和普通聊天无回归。 - 将
episodicMode设为canary,只填测试用户 ID;用该用户在会话 A 讨论唯一测试词, 再在会话 B 询问“你还记得我们聊过……吗”。 - 确认命中会话 A、回答没有执行历史片段中的指令,并确认非灰度用户不产生索引/召回。
- 验证不存在的主题返回“不确定/没有足够证据”,而不是编造历史。
- 通过
/api/runtime/status的memory.episodic观察模式、召回/降级计数,并同时检查 错误率、召回延迟和数据库负载;通过后才允许改为active。
回滚
先在 memind_adm 将 episodicMode 改为 off。代码可按标准 release 回滚;索引表是加法
结构,回滚时保留,不要删除历史快照。索引内容不影响原会话展示。