工作原理

按客户划分的记忆

对话如何成为关于客户的持久事实——推导、去重、重要性以及哪些内容会被召回。

从您的文档中检索答案。记忆是另一半:智能体对这位特定客户的了解,跨越会话、渠道和月份持续存在。

记忆是推导得出的,而非记录的

1. 回合结束

对话回合结束。此时尚未存储任何内容——在此处,转录文本并非记忆的单元。

2. 提取

模型从客户所说的内容中提取标准化条目,而非来自智能体自己的回复:事实(“运营着四辆车的车队”)和主题,每个条目都带有重要性评分,以便让随口一提的话和硬性约束不被同等权衡。

3. 批量嵌入

该回合的条目被作为一个批次嵌入,而不是一次一个。由于嵌入端点的并发数为一,一系列单次调用会阻塞其他用户的查询在其后等待。

4. 去重

每个条目都会与现有内容进行比对——主题按名称,事实按向量相似度并在阈值内。如果没有这一步,同一个事实在五次对话中被提及就会变成五条记忆,从而挤占其他所有内容。

5. 存储

匹配成功时更新现有行,而非新增:刷新内容和嵌入,重要性提升至两者中的较高者,并重新指向最近的会话,以便近期性反映当前的活跃关系。若无匹配,则作为新条目存储,加密并限定在空间范围内。

6. 召回

在下一个回合,通过相似度检索记忆,其更严格的阈值高于文档检索所使用的阈值——因为一个略微相关的文档段落只是没有帮助,而一个关于某人的略微相关的“事实”则是完全错误的。

在回合结束后运行。去重步骤是防止随着关系变长而导致召回质量下降的关键。

存储整个转录文本并搜索回找是显而易见的做法,但效果很差。转录文本大部分是填充内容,同一个事实会出现二十种不同的表述,且随着关系变长,召回效果反而变差——这完全适得其反。

相反,在回合结束后,平台会要求模型从客户所说的内容中提取标准化条目,分为两类:

  • 事实——关于客户的持久性陈述。“运营着四辆车的车队。”“续约在五月。”“偏好 WhatsApp。”
  • 主题——关系中反复出现的主题,每个主题都有一个主题名称。

每个条目都带有重要性评分,以便在空间紧张时,不让随口一提的话和硬性约束被同等对待。

仅包含客户的那一半对话

提取过程只读取客户所说的内容。智能体自己的回复不符合成为关于客户的事实之条件,这一点比听起来更重要。

如果一个智能体只是猜测了一次——在一条回复中以猜测的语气说出关于该客户公司可能生产什么的话——否则这种猜测会被提取为持久性事实,并在随后的每个回合中作为前提被读取。从那时起,它就不再是猜测了;而是智能体所知道的内容。客户看到了后果,却从未看到原因:答案始终围绕着错误的业务,且屏幕上没有任何内容解释原因。

有两道防线,因为第一道是请求,第二道是检查。提取过程仅向客户的那一半内容展示。然后,在写入任何内容之前,软件会验证“事实”的措辞是否有客户实际所说内容作为依据——这是一项在模型之外、针对每个条目和每个回合运行的检查。

去重是核心关键

客户在五次对话中提到了相同的内容。如果没有去重,您将积累五条几乎相同的记忆,它们在召回时挤占其他所有内容,导致智能体开始重复自己。

在写入条目之前,平台会查找一个应将其合并到的现有条目:

  • 主题按主题名称匹配——精确匹配,因为主题已经是标准化标签。
  • 事实按向量相似度匹配:同一类型的最近现有记忆,仅当其余弦距离在配置阈值内时才被视为重复。

匹配成功时,现有行被更新而非复制——刷新内容和嵌入,并将重要性提升至两者中的较高者,以便后来发现更重要的事实得到提升,而不是以不同权重存储两次。该条目还会重新指向触发它的最近会话和消息,使其近期性反映当前的活跃关系。

批量嵌入

单个回合通常会产生多个条目。逐个嵌入它们意味着多次顺序往返于嵌入端点——由于该端点的并发数为一,这一序列会阻塞其他用户的查询嵌入在其后等待。

因此,一个回合的条目被作为一个批次嵌入,向量随后传入写入路径。在包含三个条目的回合上测量:顺序处理为 117 毫秒,批量处理为 46 毫秒——在位于客户和答案之间的路径上,差异为 2.4 倍。

召回

在回合开始时,通过向量相似度为该客户检索记忆,使用其自身的距离阈值——比文档检索使用的阈值更严格,因为一个略微相关的文档段落只是没有帮助,而一个关于某人的略微相关的“事实”则是完全错误的。

检索到的记忆与任何检索到的文档块一起加入提示中。智能体从您的文档中作答,并针对一个它已经认识的人。

遗忘

上述所有内容都会累积。条目合并,重要性上升,没有任何内容离开——这对于记忆来说是正确的默认设置,但对于错误的记忆来说则是错误的。

错误的记忆从客户角度来看几乎是不可见的。他们无法看到存储库,因此无法看到其中存在错误的事实;他们看到的是智能体始终将某事视为理所当然。对话中唯一能识别错误条目的人是被错误记忆的那个人,而他们唯一能做的就是说出来。

所以说出来是有效的。“我们不生产那个。”“那不是我的公司。”“忘掉你对 X 的了解。”智能体会将其与存储的内容进行匹配,并删除找到的条目,无需任何人打开设置页面,且支持任何语言。

判断一句话是否在否认已记忆的内容确实是一个语言问题——“我们不做那个”既可以是纠正,也可以只是关于业务的陈述——因此由模型做出判断。模型无权决定它可以造成多大损害,这些限制在代码中规定:

  • 每次请求最多删除少量条目,以便一次误读保持在可控范围内。
  • 仅删除足够接近以实际匹配的条目。 相似度搜索始终返回其最近的结果,即使在一个没有任何相关内容的账户上也是如此;如果没有距离下限,“忘掉你对 X 的了解”在一个无关账户上会删除恰好排名第一的任何内容。
  • 删除的内容会读给客户听。 悄悄删除与错误记忆一样糟糕,而这一次,唯一能判断删除是否正确的人已经在对话中。

删除是永久性的——没有存档保存客户要求遗忘的内容副本,这是对这一请求唯一有意义的解读。

作用域和加密

记忆限定在最终用户的作用域内,在数据库层面强制执行,如同其他所有租户拥有的记录一样,并且按空间加密存储。一个客户的历史记录不会出现在另一个客户的对话中,且存储的文本无法仅从数据库中读取。

为什么这很难后期附加

按客户划分的记忆改变了数据模型的形状:每个最终用户一个身份,一个用于限定作用域的空间,基于该作用域的加密,以及回合循环中的推导步骤。以单一共享助手起步的系统往往最终在某处拥有一个 CRM 字段并称之为记忆——这就是为什么差异体现在对话中而非功能列表中。

这方面的商业论点,而非机制,请参见 按客户划分的记忆