deerflow2/docs/thread-memory-manual-test-checklist.md
2026-05-18 16:03:53 +08:00

214 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Thread Memory 手动测试清单
日期:`2026-05-08`
测试人:`__________`
---
## 0. 前置检查
- [ ] 已拉取包含以下修复的最新代码并重启后端进程
- `memory.enabled=false` 时仍允许 `thread_memory` 更新
- `thread_prompt` 的 JSON 模板转义修复(避免 `KeyError: "profile"`
- `thread_updater` 使用非流式安全参数(避免 `stream_options` 400
- [ ] `config.yaml` 中已启用 `thread_memory.enabled: true`
- [ ] 确认使用的是预期配置文件(当前项目根目录 `config.yaml`
---
## 1. 基础写入与读取
前置条件:
- 选择一个新的 `thread_id`(例:`1f571481-e3ae-42b5-a513-945bf8f1cbef`
步骤:
1. 在该线程发送 2-3 轮消息,包含姓名、角色、偏好语气等信息
2. 等待 `debounce_seconds`(默认 30 秒)
3. 查询 `thread_memory`
期望:
- 出现该 `thread_id` 记录
- `profile/preferences/facts` 有对应内容
结果:
- [1] 通过
- [ ] 失败(备注:`________________`
---
## 2. Per-Thread 隔离
前置条件:
- 准备两个线程 `thread_A`、`thread_B`
步骤:
1. 在 A 中输入“前端背景”信息
2. 在 B 中输入“后端背景”信息
3. 分别等待写入完成后查看两条记录
期望:
- A 仅保存 A 的画像B 仅保存 B 的画像
- 两个线程不串数据
结果:
- [1] 通过
- [ ] 失败(备注:`________________`
---
## 3. 全局记忆 Fallback
前置条件:
- 全局 memory 有内容
- 新建一个尚无 per-thread 记录的线程
步骤:
1. 先在该新线程发一轮普通消息
2. 观察回复是否体现全局记忆
3. 再继续对话触发 per-thread 写入后观察注入变化
期望:
- 无 per-thread 时可 fallback 到全局
- 有 per-thread 后优先使用 per-thread
结果:
- [ ] 通过
- [ ] 失败(备注:`未执行N/A当前环境 memory.enabled=false全局记忆关闭本用例不适用`
---
## 4. 注入裁剪优先级Profile > Preferences > Facts
前置条件:
- 某线程已有大量 facts
步骤:
1. 人为积累 facts 到接近/超过注入预算
2. 保持 profile/preferences 有值
3. 观察注入后的表现
期望:
- 超预算时保留 profile + preferences
- 优先裁剪 facts
结果:
- [1 ] 通过
- [ ] 失败(备注:`________________`
---
## 5. 敏感信息过滤
步骤:
1. 在对话中输入邮箱、手机号、token/password 等敏感样例
2. 等待写入后查库
期望:
- 敏感信息不应落入 `profile/preferences/facts`
结果:
- [1] 通过
- [ ] 失败(备注:`________________`
---
## 6. 并发覆盖保护CAS + version
步骤:
1. 同一 `thread_id` 短时间内触发两次更新(尽量并发)
2. 观察最终数据与日志
期望:
- 不出现明显“旧数据覆盖新数据”
- 冲突时可见重试行为(日志)
结果:
- [1] 通过
- [ ] 失败(备注:`________________`
---
## 7. Debounce 生效
步骤:
1. 在 30 秒内连续发送多条消息
2. 观察写库频率
期望:
- 多条输入被合并处理,不是每条都立即写库
结果:
- [1] 通过
- [ ] 失败(备注:`________________`
---
## 8. 线程删除联动清理
步骤:
1. 对已有 per-thread 记录的线程调用 `DELETE /api/threads/{thread_id}`
2. 查询 `thread_memory`
期望:
- 对应 `thread_id` 记录被删除
结果:
- [ ] 通过
- [ ] 失败(备注:`未执行:当前产品决策不接受“删线程即删记忆”,需改为用户显式触发清除后再复测`
---
## 9. SQLite 自动建表与路径
步骤:
1. 删除现有 `thread_memory.db`(测试环境)
2. 重启服务并触发一轮写入
3. 检查 DB 文件和表结构
期望:
- 自动创建 DB 文件与 `thread_memory`
- 索引 `idx_thread_memory_owner_id` 存在
结果:
- [1] 通过
- [ ] 失败(备注:`________________`
---
## 10. 配置开关验证
步骤:
1. 关闭 `thread_memory.enabled`,重启并测试写入
2. 开启 `thread_memory.enabled`,关闭 `thread_memory.injection_enabled`,重启并测试注入
期望:
- `enabled=false`:不更新 per-thread
- `injection_enabled=false`:不注入 per-thread可 fallback
结果:
- [1] 通过
- [ ] 失败(备注:`________________`
---
## 11. 已知错误回归验证
### 11.1 `KeyError: "profile"` 回归
- [ 1] 未再出现 `thread_prompt.py``KeyError` 报错
### 11.2 `stream_options` 400 回归
- [ 1] 未再出现 `"'stream_options' only set this when you set stream: true"` 报错
备注:`________________`
---
## 测试总结
- 总用例数:`11`
- 通过数:`____`
- 失败数:`____`
- 结论:
- [ ] 可上线
- [ ] 需修复后复测