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