知识点思维导图
36 个知识节点
记忆系统(04) - Redis Agent Memory:短期状态、长期召回与事件流
读完后,你应能完成以下任务:
- 绘制“记忆系统(04) - Redis Agent Memory:短期状态、长期召回与事件流 / 先按访问模式选数据结构”的关键对象与数据流,解释“Redis 不只是“把 messages 放进 List”。”,并用源码位置、日志或 Trace 标注证据。
- 为“记忆系统(04) - Redis Agent Memory:短期状态、长期召回与事件流 / 短期会话的安全实现”设计正常与异常输入,验证“滑动 TTL 的含义是:只有通过身份和线程所有权校验的合法访问才刷新过期时间。”,输出首个偏差位置与回归测试结果。
- 实现“记忆系统(04) - Redis Agent Memory:短期状态、长期召回与事件流 / 事件流与异步总结”的最小代码或配置,检验“总结器使用 Consumer Group 消费事件并写回滚动摘要。”,输出命令、结果与 Diff,并说明不适用边界。
更新日期:2026/08/11
本文是 AI 应用开发中 Redis 短期记忆的主文。Redis 在 RAG 中还可承担检索缓存和限流,但缓存键、失效维度与验收指标不同,详见 RAG(08) - Redis 检索缓存、语义缓存与限流。不要把会话窗口与 RAG 候选缓存放进同一套键空间、TTL 和淘汰策略。
一、先按访问模式选数据结构
Redis 不只是“把 messages 放进 List”。不同记忆需要不同访问方式:
| 数据 | Redis 结构 | 关键操作 | 生命周期 |
|---|---|---|---|
| 线程工作状态 | Hash | HSET / HGETALL |
短 TTL |
| 最近消息 | List 或 JSON | LPUSH / LTRIM |
会话级 |
| 长期语义记忆 | JSON + HNSW | FT.SEARCH |
按类型衰减 |
| Agent 事件日志 | Stream | XADD / XREVRANGE / XTRIM |
长度有界 |
| 幂等锁 | String | SET NX EX |
秒到分钟 |
| 语义缓存 | JSON + Vector | 相似检索 | 跟模型和 Prompt 版本绑定 |
订单结果、扣费记录、审批结果和审计证据必须进入持久主库。判断标准不是“Redis 会不会持久化”,而是数据丢失或回滚时业务能否接受。
二、短期会话的安全实现
滑动 TTL 的含义是:只有通过身份和线程所有权校验的合法访问才刷新过期时间。写入工作状态、追加最近消息和读取会话都要使用同一条原子更新边界;无效请求不能续期,否则攻击流量会让本应删除的会话永久存活。
键必须包含租户、用户和线程。只用 session_id 并假设它全局唯一,是常见的串数据根因。若服务允许用户提交 thread_id,还要在业务层校验其所有权。
三、事件流与异步总结
Agent 每一步可写入 Redis Stream:
总结器使用 Consumer Group 消费事件并写回滚动摘要。模型调用不要持有 Redis 分布式锁;应先获取事件快照,再释放锁并调用模型,最后用版本号或 Lua 脚本做乐观并发更新。
四、长期记忆也可以放 Redis,但不是同一个键
Redis Search 可对带 Embedding 的 JSON 建 HNSW 索引,同时按 tenant_id、user_id、namespace、memory_type 做 TAG 过滤。写入前可用同一索引查近邻,避免重复记忆;召回后仍要做新鲜度、可信度和冲突处理。
长期记忆记录至少包含:
{
"memory_id": "mem-20260811-001",
"tenant_id": "tenant-a",
"user_id": "user-42",
"namespace": "preferences",
"memory_type": "explicit_preference",
"text": "回答默认使用中文",
"embedding": [0.12, -0.08],
"source_thread_id": "thread-9",
"created_at": "2026-08-11T09:00:00Z",
"valid_until": null,
"status": "active"
}
删除记忆时要同时删除 JSON、向量索引可见性、语义缓存和异步副本,并记录删除传播是否完成。
五、缓存、锁与幂等
- 生成缓存键至少包含模型、Prompt 模板版本、知识库版本、权限摘要和规范化问题。
SET key value NX EX seconds可用于短锁;锁值使用随机 token,释放时用 Lua 校验 token,不能直接DEL。- 工具副作用用业务幂等键落主库,Redis 只能做快速挡板,不能成为唯一幂等凭证。
- Redis 达到内存上限触发淘汰时,不能让关键业务记录随缓存一起消失。
六、验收与故障注入
必须测试:
- Redis 短暂不可用时,聊天是降级为无记忆,还是明确失败。
- 同一线程两个请求并发更新时,是否丢消息或覆盖新摘要。
- TTL 到期后,主库中的业务事实是否仍可恢复。
- 跨租户、跨用户读取是否始终返回空。
- Redis 重启、主从切换和网络抖动时,P95 延迟与重试是否可控。
- 内存接近上限时,淘汰策略是否符合数据分级。
七、常见错误
- 不设置 TTL 和 Stream 上限,短期状态无限增长。
- 在 Redis 键里遗漏租户或用户边界。
- 把整段对话每轮重新 JSON 序列化,造成大键和网络放大。
- 用分布式锁包住 LLM 调用,锁持有几十秒并形成雪崩。
- 缓存键漏掉权限或知识库版本,导致旧答案或越权答案复用。
八、总结
- 先按访问模式选数据结构:Redis 不只是“把 messages 放进 List”。
- 短期会话的安全实现:键必须包含租户、用户和线程。
- 事件流与异步总结:总结器使用 Consumer Group 消费事件并写回滚动摘要。
- 长期记忆也可以放 Redis,但不是同一个键:写入前可用同一索引查近邻,避免重复记忆;
- 缓存、锁与幂等:生成缓存键至少包含模型、Prompt 模板版本、知识库版本、权限摘要和规范化问题。
- 验收与故障注入:Redis 短暂不可用时,聊天是降级为无记忆,还是明确失败。 -> 同一线程两个请求并发更新时,是否丢消息或覆盖新摘要。 -> TTL 到期后,主库中的业务事实是否仍可恢复。 -> 跨租户、跨用户读取是否始终返回空。
九、动手实践:Redis Session Memory 机制
用内存实现一个最小 Redis 语义模拟器,复现会话记忆真正依赖的四个行为:租户键隔离、最近消息截断、滑动 TTL、过期降级。
9.1 在线运行
零依赖,Python 3.10+ 可运行。这个实验用于观察 Redis 数据结构和生命周期,不会伪装成真实 Redis 网络连接;生产接入仍应使用 redis-py、事务管道和 Redis 故障测试。
9.2 重点观察
- 相同
thread_id在不同租户下是两条不同的键。 - 每次合法读写刷新 TTL,但越权读取不会刷新。
- 消息超过窗口后淘汰最早内容。
- TTL 到期返回空,应用可以明确降级为“无短期记忆”。
9.3 可运行源码:Redis Agent Memory:短期状态、长期召回与事件流
main.py
学完自测
选择所有正确答案;提交后逐项核对判断依据。