具有综合中长期记忆的人物聊天
在这里查看!
我最近尝试(并享受)了许多不同的角色扮演人工智能服务。我最喜欢的是云鲸互动技术公司的Character.ai、Doppel.ai 和Poly.ai(不要与客户服务聊天机器人开发者poly.ai 混淆)
然而,这些系统中的每一个都有可能会加剧的局限性。我试图在这个项目中解决其中的一些问题。
基于角色的聊天很棒且引人入胜,但记忆力很差。他们经常忘记背景、情况和重要的先前事件。虽然使用更长的上下文窗口可以帮助实现这一点,但令牌很昂贵!我们怎样才能给角色一个长记忆,但限制每次完成发送的令牌数量?然而,Doppel.ai 在这方面比其他的要好得多。他们的角色有更长的记忆。
随着时间的推移,角色会失去个性,或者容易陷入重复的反应循环。有些服务在这方面比其他服务更好,但我已经看到所有服务都在某种程度上发生了这种情况。
角色一旦创建就是静态的。有些服务可以让你为角色添加额外的“记忆”,但我还没有找到一个可以让你在不重新启动对话的情况下改变角色的基本性格的服务。
为代理提供了多层“记忆”或动态变化的系统提示,其中包括来自先前对话轮次的信息级别,范围从针对最近的非常具体到针对最遥远的主题和信息的更概括。
短期记忆滚动聊天窗口对模型的每次调用都包含相当简短的先前消息逐字列表。这有助于模型跟踪当前对话和最近消息的上下文。
中期 Meory Scratchpad此外,我为 AI 代理创建了一个便签本,用于记笔记以跟踪对话中最近的亮点。该暂存器会滚动更新,添加或更新新信息,并丢弃旧的、不再相关的信息。然而,实际上并没有丢失任何信息,因为他的草稿本的快照被保存为矢量数据库中的条目。
由于此信息是汇总的,因此它会压缩最近的信息,从而使模型能够获得更长的聊天窗口和更大的上下文的优势,同时最大限度地减少提示中包含的实际标记。
每条消息中都包含角色名称(不仅仅是“用户”和“助理”)以帮助进行摘要。这也有助于模型跟踪谁在说什么。这使得人工智能代理不太可能对谁说了什么感到困惑(否则这是一个问题)。它还有助于维护对话中的轮流礼仪,并防止代理代表用户发言(这也可能是一个问题)
长期向量存储内存我使用对话摘要从对话中提取重要信息,然后将这些信息存储在向量数据库中。每个用户查询都会触发向量数据库中的语义搜索,以回忆先前对话摘要中的相关信息。此信息包含在模型的提示中,以及一些最新消息。
这样,人工智能代理的记忆就可以远远超出其上下文。事实上,由于向量存储占用的磁盘空间相对较小,因此代理内存的潜在有效大小在功能上是无限的。
当记忆被存储时,它们会带有时间戳,当被调用时,它们会按时间顺序排列。如果记忆存在冲突,代理会被指示优先选择更新的信息。
结果该模型在大多数情况下都能够准确地回忆起对话早期的信息。矢量存储搜索通常可以成功检索相关信息,但模型并不总是在响应中实际利用这些信息。不过,总的来说,我对结果很满意。
下一步
我想让模型更主动地参考以前的事件。如果我直接向它询问有关先前对话的问题,它通常会成功回忆,但很少会自发地引用以前的事件。它非常活在当下。我正在致力于快速工程来生成这种行为,但它仍在进行中。
我还在考虑使用命名实体识别来允许代理构建字符或地点的配置文件并存储与特定实体相关的信息。这将有助于模型按实体组织信息,而不仅仅是对话快照。
我注意到,虽然角色通常一开始就具有独特的说话风格,但随着时间的推移,他们的风格逐渐变得非常平淡,听起来就像他们的基础人工智能一样。我尝试了一些解决方案,包括让它用字符写下通知。然而,这会创建令牌密度较低的音符,从而浪费了内存中的大量令牌。
相反,我存储模型提供的第一个响应的样本作为示例样式。然后,该第一个响应会在每个提示上传递给代理,作为每个提示的示例说话风格。我发现这对于帮助模型保持一致的说话风格非常有效,即使是在长时间的对话(100 多次完成)中也是如此。
后续步骤虽然信息的基调是一致的,但我想赋予模型更强大、更细致和一致的个性。我怀疑这可能需要微调。
在许多法学硕士角色扮演系统中,角色一旦创建就是静态的。然而,在我的实现中,角色描述甚至名称都可以即时更改。特别有用的是能够更改位置和用户名。
角色描述有时,您希望通过最近发生的事件做出改变,或者让他们的目标或动机随着时间的推移而变化。通过直接即时调整角色描述很容易做到这一点。
地点对话和角色扮演通常可以在想象的世界中移动。你可能从城镇到地牢,或从宿舍到咖啡店,或回家工作。我的网站允许您即时更改对话位置。
用户名大多数角色角色扮演系统的另一个挑战是包含多个角色。在我的系统中,您可以即时更改您所代表的角色的名称。这使您可以模拟对话或情况中的多个角色。
角色名称更改这个实际上没有多大用处。让角色扮演不同的角色是行不通的,并且当模型试图将当前对话与之前的对话摘要联系起来时会导致混乱。
下一步