聊天机器人最大的问题不是不会说话,是记不住。聊过的事过两天就忘,说过的偏好反复问,久了就很出戏。
人脑的记忆不是全存全取,而是会衰减。心理学里的遗忘曲线可以写成:
R = exp(-t / S)
其中 t 是距上次回忆的时间,S 是记忆强度。强度越大,忘得越慢。每次被用到,强度就涨一点——这就是"回忆巩固"。
这样设计的好处是:不常用的记忆自然下沉,重要的记忆靠反复使用留下来,不需要人工维护一张"要不要留"的清单。
一开始想上向量检索,后来发现对中文小规模记忆,BM25 + 分词已经够用,而且可解释:能明确看到是哪个词命中的。
具体做法:把每条记忆分词、建倒排索引,查询时算 BM25 分数,取前几条。中文分词用 jieba,注意自定义词典,否则专有名词会被切碎。
上下文有上限,不能把记忆全塞进去。现在的策略是:
加起来控制在几百字,不挤占对话空间。
作用域写错:记忆按会话 ID 存,ID 和实际会话对不上,结果就是"记了,但从不注入"。这个 bug 很隐蔽——写记忆的日志是正常的。
上下文膨胀:把模型自己的推理过程也存进历史,历史体积翻倍。后来限制了历史轮数才稳定。
垃圾进库:解析失败时如果不加校验,模型的残缺输出会被当成"记忆"写进库,污染长期数据。加一道质量门,宁可不记。
经验:记忆系统的难点不在存和取,在"信不信"——怎么保证写进去的是真的,取出来的是相关的。