本文档记录了开发记忆系统时的一些设计思路和实现细节,以及一些遇到的问题和解决方案。本文档的目的是为了记录该系统在设计开发过程中的一些思考,以便日后回顾和参考。本文档的内容可能会随着开发的进展而不断更新,也可能会被删除。
由于 GPT3.5 模型的单次响应只能接收 4096 tokens,而我们希望 bot 能够在更长地时间范围内记忆会话中的信息,因此需要开发一个记忆系统,用于存储和检索会话中的信息。其根本目的是为了让 bot 的 “人格特征” 更加丰富,让 TA 拥有 “回忆” 的能力,拓宽数字生命的边界。
外置记忆系统空间更大,可以保存更细节的对话信息,通过设计合理的数据结构和检索方法,可以更好地实现对话信息的细节化存储和检索。以支持更丰富的长期对话记忆,增强 bot 的人格特征。
sqlite 数据库是一个轻量级的数据库,可以在不同的平台上运行,而且可以通过 python 的 sqlite3 模块进行操作,方便快捷。同时,sqlite 数据库的数据存储在一个单独的文件中,可以方便地进行备份和迁移。
记忆信息块是指存储在记忆库中的对话信息,可以是一段对话,也可以是一段对话的摘要。记忆信息块的设计有两种
记忆信息块存储 bot 在会话中的聊天记录,包括用户的输入和 bot 的输出。
记忆信息块存储 bot 在会话中的聊天记录摘要,对话过程中每经过特定轮次,就会生成一个摘要和一个索引标签(由 bot 总结和其它分词工具共同生成),摘要是对会话中的信息进行抽象和总结,索引标签是用于检索的关键词。
当 bot 需要记忆信息时,需要给出一个记忆标签,记忆标签可以是一个关键词,也可以是一个关键词列表(即多个关键词),同时给出一个记忆的重要程度指数,记忆的重要程度指数越高,记忆的优先级越高。
在 bot 需要检索记忆信息块时,需要给出一个检索标签,检索标签可以是一个关键词,也可以是一个关键词列表(即多个关键词)。检索方法可以是:
-
检索标签与记忆信息块的索引标签完全匹配 (优先级最高)
-
检索标签与记忆信息块的索引标签部分匹配 (优先级次之)
-
检索标签与记忆信息块的内容完全匹配 (优先级最低)
-
检索标签与记忆信息块的内容部分匹配 (优先级最低)
在 bot 需要回复用户时,根据用户的输入,检索记忆信息块,如果检索到相关的记忆信息块,则将其推送给 bot,供 bot 进行参考。
权重指的是记忆信息块在检索时的优先级,权重越高的记忆信息块,检索时越容易被检索到。影响权重的因素有很多,比如:记忆信息块的创建时间、记忆信息块的内容、记忆信息块的使用次数等。
- 重要性权重(bot 生成):记忆信息块的重要性越高,检索时越容易被检索到。
- 时间距离权重(检索时计算):记忆信息块的创建时间越近,检索时越容易被检索到。
- 使用次数权重(检索后更新):记忆信息块的使用次数越多,检索时越容易被检索到。
- 邻用权重(检索后更新):记忆信息块的上次使用时间越近,检索时越不容易被检索到。
- 内容权重(检索时计算):记忆信息块的内容与检索标签的匹配程度越高,检索时越容易被检索到。
- 反馈权重(bot 生成):检索到记忆信息块后要求 bot 给出价值评价,如果 bot 认为该记忆信息块的价值不高,那么该记忆信息块的权重就会降低。
权重比例是指各个权重的比例,权重比例的设置可以根据 bot 的使用场景进行调整,比如:如果 bot 的使用场景是用于学习,那么可以将反馈权重的比例设置的更高一些,这样 bot 就会更容易记住一些价值较高的记忆信息块。
默认的权重比例如下:
- 重要性权重:0.3
- 时间距离权重:0.2
- 使用次数权重:0.1
- 邻用权重:0.2
- 内容权重:0.1
- 反馈权重:0.1
具体的权重计算公式如下:
weight = 重要性权重 * 重要性权重比例 + 时间距离权重 * 时间距离权重比例 + 使用次数权重 * 使用次数权重比例 + 邻用权重 * 邻用权重比例 + 内容权重 * 内容权重比例 + 反馈权重 * 反馈权重比例
在检索出一定数量记忆信息块后,根据权重进行轮盘赌选择,选择出一个记忆信息块。这样做的目的是为了让检索的结果存在一定随机性,避免 bot 一直回复同一个记忆信息块。
记忆信息块的基本结构如下:
- 记忆信息所属会话 id
- 记忆信息块的 id
- 记忆信息块的内容
- 记忆信息块的索引标签
- 记忆信息块的重要性权重
- 记忆信息块的反馈权重
- 记忆信息块的创建时间
- 记忆信息块的使用次数