用Redis给智能体做多轮会话记忆

📅 2026/6/27 12:23:32
用Redis给智能体做多轮会话记忆
直接说结论智能体多轮对话别拿内存的 dict 存上下文进程一重启全没了、多实例还各记各的。用 Redis 存,按 session 一个 key,带过期、限长度、加并发锁,基本就稳了。下面是我自己踩出来的方案。先说我遇到的坑上个月我给一个客服智能体加记住上文的能力。第一版图省事,Python 里一个全局dict,key 是用户 id,value 是消息列表。本地测得好好的,一上线就翻车。三个问题接连冒出来:部署了两个实例,负载均衡随机打,用户这句话进了 A 进程,下句进了 B,B 完全不知道前面聊了啥,answer 牛头不对马嘴。凌晨重启了一次服务,所有人的对话记忆清零,第二天早上一堆人问你怎么不记得我昨天说的了。有个用户一口气聊了四百多轮,那条 value 撑到几十 KB,每次拼进 prompt token 哗哗烧,响应也越来越慢。说白了就是:状态不能放进程内存。得有个独立的、能跨进程共享的地方存,Redis 正合适。存储怎么设计我最后定的结构,就三件事:键、过期、限长。键设计:一个会话一个 List,key 用chat:{session_id}。为什么用 List 不用 String 塞 JSON?因为追加一条消息用RPUSH是 O(1),想取最近 N 条直接LRANGE -N -1,不用每次把整段读出来反序列化再写回去。过期:每次写完顺手EXPIRE,我设的 30 分钟。会话冷了自动消失,不用写定时清理任务,省心。注意是每次写都要重置 TTL,不然聊到一半被回收了。限容量:RPUSH之后跟一个LTRIM,只留最近 20 条。这步是上面那个四百轮逼出来的——记忆不是越多越好,太长既烧 token 又拖慢推理,留个滑动窗口就够。需求Redis 手段说明跨进程共享Listchat:{id}多实例读同一份过期回收EXPIRE30min每次写重置 TTL控制长度LTRIM 0 -21滑动窗口留最近20条并发安全SET NX短锁防同一会话并发写乱序上代码核心就这么点,Python redis-py:import redis, json, time r redis.Redis(hostlocalhost, port6379, decode_responsesTrue) WINDOW, TTL 20, 1800 def append_msg(sid, role, content): key fchat:{sid} r.rpush(key, json.dumps({role: role, content: content})) r.ltrim(key, -WINDOW, -1) # 只留最近 20 条 r.expire(key, TTL) # 每次写都续命 def get_history(sid): raw r.lrange(fchat:{sid}, 0, -1) return [json.loads(x) for x in raw]并发那块,同一个 session 短时间内来两条请求,List 顺序可能乱。我加了个最简单的锁,够用:def with_lock(sid, fn): lock flock:{sid} # NX 抢锁,5 秒自动释放,防死锁 if r.set(lock, 1, nxTrue, ex5): try: return fn() finally: r.delete(lock) time.sleep(0.05) # 没抢到稍等重试 return with_lock(sid, fn)append_msg里那三条命令,讲究点可以塞进pipeline一次发,少两个 RTT。我量了下本地大概省 1 毫秒出头,业务量不大就没上,先记着。真实取舍几个我没藏着的点:滑动窗口会丢早期信息。留最近 20 条意味着开头说的需求,聊久了就掉出窗口了。我的折中是把首轮系统设定单独存一个 String,永远拼在最前面,中间靠窗口。要更狠就得上摘要——把旧消息压成一段 summary 再存回去,但那又要多调一次模型,我这场景没必要,没做。30 分钟 TTL 是拍脑袋的。客服场景用户走神五分钟很正常,设太短记忆断得突兀;太长 Redis 内存又顶不住。这数得按业务调,我也是观察了两天对话间隔才定下来的。这套只解决记住聊了啥,不解决答得准不准。会话记忆是个杂活,把上下文喂对地方而已;真正答得好不好,还得看背后的模型和知识库。说到这,记忆持久化我是自己用 Redis 撸的,但模型和那套对话编排没自己造——我直接用了一个零代码就能搭智能体的平台,拖拖拽拽把流程配出来,挂上现成大模型再绑个私有知识库,一个能用的客服小助手当天就跑起来了,记忆层从外面用上面这套 Redis 兜住。第一版回答确实有点干、太书面,我又回去调了几轮提示词才像个人话,学习曲线不算陡但也不是零成本。(模型和 API 我走的讯飞星辰MaaS,现成调用,没自己部署算力。)你们的智能体会话记忆是怎么存的?有上 Redis 还是直接塞数据库的,评论区聊聊,我挺好奇高并发下大家怎么处理顺序问题的。