事情本身不复杂,线索都在日志里。用 ConversationBufferMemory 跑客服,一个会话 60 轮后内存里存了 2MB 文本,服务重启前 RSS 涨到 3.2G,10 个并发就吃满。

第一反应是「会话结束后没释放,字典一直持有引用」,验证下来不成立。

这类报错背后常见的原因有几处,逐个排除就行。Buffer 模式不裁剪,历史随轮次线性增长。还有一种是每条消息都带完整工具结果,单条就几 KB。

另外,并发下每个会话各存一份副本。

量单条消息的内存占用

python -c "import sys;print(sys.getsizeof('x'*1000))"

再往下换成按窗口裁剪的记忆

python -c "from langchain.memory import ConversationBufferWindowMemory;print(ConversationBufferWindowMemory(k=6).buffer)"

会话结束时显式清理

python -c "d={'s1':1};d.pop('s1',None);print(d)"

压测并发看进程 RSS

python -c "import psutil;print(round(psutil.Process().memory_info().rss/1024**2))"

这类改动我都写进变更记录,过两周再出问题时能对上号。

怎么算真的好了,看的是同一批现象。60 轮会话的历史稳定在 6 条消息以内,单会话内存不超过 20KB,10 并发下 RSS 保持在 1G 以下。

窗口裁剪会丢早期约束,重要事实要抽成结构化槽位单独存,别指望历史里还留着。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189