一个聊天员可以听起来令人信服 五分钟而不记任何事。
然后你提到上周你被强调的工作面试, 你的狗的名字, 或者一个小细节 从一个深夜的对话。
它的反应是,它没有发生。
大部分"AI相伴"的演示都在这里分崩离析.
我正在建造本地Waifu,一个在用户自己的Mac或PC上运行的桌面AI同伴.
我早期制定的规则之一很简单:对话与记忆应该留在机器上.
没有中央聊天数据库.
没有服务器需要在线才能让角色记住某人.
规则听起来很干净。
建设它不是。
保存聊天不是内存 第一个版本的内存是显而易见的:保存消息.
这给你历史,这是有用的,但它不能解决回忆。
漫长的聊天历史发展得很快.
将全部发回每个消息的本地语言模型是缓慢的,在上下文空间中很昂贵,通常会使回复更糟糕.
模特儿不需要看到过去六个月的每一次谈话 它需要现在重要的几块 如果有人说"我明天必须带露娜去兽医那里",角色应该能够找到露娜是他们的狗.
它不应该重读上百条与工作、电影和晚餐计划无关的信息。
所以我把聊天历史和长期记忆视为不同的东西。
聊天历史是最近的对话。
它给模型提供了直接的上下文.
长期记忆是一个小集合的事实,瞬间,偏好,以及关系细节,这些可能后来才重要.
这些记忆需要通过意义来搜索,而不仅仅是通过确切的文字来搜索.
内存数据留在了SQLite I想让应用程序在没有主机数据库的情况下工作,所以存储层是本地的SQLite.
每个角色都获得自己的数据.
聊天,记忆,被取出的实体,以及关系在当地存储在设备上.
如果用户创造出两个字符,一个角色不会悄悄地继承另一个角色的记忆.
分离比听起来更重要 同伴应用是个人设计的.
跨字符的混合上下文不是一个无害的bug.
如果一个角色开始谈论属于另一个角色的东西,整个幻觉会立即消失.
对于每个内存,我将文本本身与元数据一起存储,例如: 当它被创建时它所属的字符 重要情感重量 用于语义搜索的矢量嵌入的频率 嵌入是让应用程序按意义搜索的部分. "预约"和"露娜有病"可能没有确切的关键词.
语义搜索仍然可以看到它们很可能是相通的.
我使用直接存储在SQLite的768维向量作为二进制数据.
提醒时,该应用会在当地计算相似性并排出结果的顺序.
没有信件内容需要离开用户的计算机进行搜索.
召回需要的不只是相似性 纯粹相似性分数是不够的 想象一下一个用户两年前曾提到过他们最喜爱的游戏,然后用上一个月的时间谈论一个困难的家庭状况.
这两种记忆都可能以某种模糊的方式与新的信息有关。
更近和情感上更重要的记忆通常应该取胜.
因此回想的加权比矢量相似。
重要性很重要。
紧急情况。
情感重量很重要。
在获得额外功劳之前 已经有用的记忆 这里没有完美的公式。
我不认为会有一个。
一个大胆地回顾每个细节的系统 感到恐怖和重复。
一个几乎无法回忆任何事物的系统感觉空虚.
作品大多是调和中间立场,接受同伴有时不应提出来的东西.
用户应感到被记住,而不是受到监视。
我也会取出一个小的知识图 一些信息比聊天文本的段落更容易检索。
例如:月是用户的狗 亚历克丝是用户的弟弟 用户wor