客服热线第三次接到同一位客户,他把同一个问题完整讲了一遍,这已经是第三遍。

三次,客户都得重新报上订单号,以及上周聊到了哪一步,因为所有 Agent 的出厂状态,LLM 那一侧没有记忆。

模型不存昨天,每一次请求对它都是初次见面。

对内部工具、一次性问答机器人来说,这固然无所谓,但在面向客户的真实场景里,支持、销售、预约、客户管理——这是底线。

因为客户记得很清楚:自己被遗忘过几次。

一个 Agent 是聊天机器人,还是一段关系,差别就在这里,它决定了下一次开口时,Agent 是只能问一句今天我能帮您什么,还是能接上一句上次那个账单、我帮您查一下进展。

下面我们按三层把记忆系统拆开讲——会话、持久、语义,再故意把它打碎,看看当真实用户涌进来时,它会在哪些地方翻车。

一、失忆的AI智能客服系统:为什么能对话不等于有关系

LLM 是无状态的,它不记得任何东西,每一次它只是被喂进一段文本,然后预测下一段文本。

所谓记住上下文,其实是调用方把历史消息重新拼进请求里——记忆的载体不在模型里,在你这一侧的工程里。

这就带来一个绕不过去的硬约束:随着多轮次长任务对话,上下文信息量会超线性增长,而窗口是有限的。 

而真实对话不会为了迁就窗口而变短,窗口一满,最旧的那几轮就得腾位置——而且是被硬生生挤出去且不留副本。

上下文压缩不就好了?上下文窗口无论是滑动窗口还是摘要压缩都会失真,如何尽可能确保上下文压缩不失真又是一个大话题,后续另起文章单独讲解。

客户第一轮就报过的订单号,聊到中段时已经不在请求里了:不是模型忘了,是它压根没被送进去。

更麻烦的是,这个问题不会自己暴露,演示时你不会发现,因为演示永远只有几轮对话。

它只在长会话、老客户、反复来电的场景里发作,而这类场景恰恰是面向客户业务的主战场。

所以:对话是模型的默认能力,关系是工程的额外投入。 

模型天然能接话茬,但只有你给它建了记忆,它才可能在下一次开口时,说出上次我们聊到……

二、AI智能客服绕不过去的三大历史难题

面向客户的 Agent,会同时撞上三种问题,它们的时间尺度不同、该存的东西不同、失效方式也不同。

问题一:会话连续性。

客户提起刚才讲过的事,Agent 却接不上,那句话已经不在它此刻能看到的内容里了,不是它不认真听,是它这一轮根本没拿着那句话。

问题二:跨会话记忆。

昨天客户来问过账单,今天又来跟进,Agent 对昨天一无所知,于是客户只能把来龙去脉、试过什么、你回复过什么,全部再讲一遍,每一位回头客,都从零开始。

问题三:事实偏好。

打交道次数多了,规律自然会浮现:性格,喜好,语气等等,每一次接触都是一座孤岛。

三种问题,对应三层记忆:

记忆层

生命周期

取回方式

解决的问题

典型触发

会话记忆

单次会话(分钟/h)

顺着对话带着走

会话连续性

就像我刚才提到的……

持久记忆

跨会话(天/周)

按实体键取

跨会话记忆

上次我们聊过……

语义记忆

跨会话(数月/永久)

按相似度取

事实偏好

您更喜欢这款产品……

这三层会像积木一样往上叠:会话记忆管这一通电话别跑题,持久记忆管下一次电话有上下文,语义记忆管该记的记很久、但别一股脑全塞回去。

这里有个容易搞混的点值得先点破:三层记忆不是三种存储介质。

 你完全可以用同一个数据库存三层——真正的差别不在介质,在生命周期和取法,如果把三层混成一坨,三层都会作废。

不过,这只是记忆的其中一种分法,你在别处见过的另外两套分法,下一章我们先把坐标系对齐,再一层一层往下看。

三、AI Agent三类记忆分法,三种不同的视角

在钻进每一层之前,先把坐标系对齐,因为你去翻资料,会发现记忆的分法不止一种,而且经常互相打架:有人分三层,有人分四层,还有人的第一层叫身份。

  • 产品视角:存多久——身份(Identity)、短期记忆(Short-term)、长期记忆(Long-term)。
  • 认知学视角:存什么——程序记忆(Procedural)、情景记忆(Episodic)、语义记忆(Semantic)。
  • 工程学视角:存多久——工作记忆(Working)、会话记忆(Session)、语义记忆(Long-term)。

第一套里的身份,本质上不在这把尺子上,它一半是从长期记忆里切出来的视图——关于这位客户是谁,内容以语义事实为主;另一半是作用域键——这些记忆归谁,产品上它极其好用,逻辑上它跟短期、长期并不同类。

我们按照生命周期分才一目了然,什么短期记忆,会话记忆,持久记忆到底在哪一层:

层级

类比

生命周期

Working Memory

工作记忆

单次请求

Short-term / Session Memory

短期记忆

单次会话

Long-term Semantic Memory

语义记忆

跨会话持久

Episodic / Procedural Memory

情景/程序记忆

跨会话持久

综上为常见记忆分层架构设计,但一味生搬硬套不可取,记忆分层架构设计取决于具体的产品形态。

拿WorkBuddy举例,其产品形态决定了需要根据作用域来划分为四层:

  • 身份(Identity):用户画像
  • 用户级(User Level):跨项目
  • 工作区(WorkSpace):当前项目
  • 技能记忆:系统提示词(归一为程序记忆)

程序、情景、语义,并不是并排的三格,它们的关系通过如下表格可清晰说明

大类

子类

是什么

客服场景里的例子

陈述性

情景记忆

绑着时间、地点的具体经历

上周三那通电话,客户说账单对不上

陈述性

语义记忆

剥离时空后剩下的事实与偏好

这位客户习惯用文字沟通

非陈述性

程序记忆

会不会做——说不出口,但做得出

退款流程该怎么走

情景和语义是亲兄弟,程序是堂兄弟。

它们之间还有一条沉积通道:同一类事反复发生,描述就会被一次次压扁——上周三那通电话、上个月那次退款、三个月前那次改地址,攒够了,就沉成一条记忆这位客户习惯用文字沟通。

语义记忆往往是情景记忆的沉淀物,情景记忆到语义记忆的过程又称之为:反思或者记忆巩固或者记忆蒸餾。

在今天的 Agent 框架里,程序记忆通常不放在记忆层,它被挪到了三个地方:

  • 系统提示——你的角色、要遵守的规则、遇到什么情况该怎么处理;
  • 工具定义——每个工具叫什么、要什么参数、什么时候该调;
  • 工作流编排——先查订单、再判断能不能退、最后回复,这条路径本身就是程序记忆。

为什么被挪走?因为它跟另外两类的性质完全不同。

四、第一层:会话记忆,让当前对话不跑题

会话记忆是最简单的一层:它跟踪当前这通对话,别让 Agent 在中途把线头丢了。

它要存的东西很朴素——这一轮里用户说了什么、Agent 回了什么,不需要智能,不需要检索,甚至不需要持久化,它的全部价值只有一条:让刚才提到的那种回指,有明确的指向。

但这一层有个天然的短命属性:它跟着会话生,也跟着会话死,通话一结束,这一层就该被清空。

客户早在通话开头报过的那个工单号,等聊到中段时已经不在 Agent 眼前了;它只好开口再问一次,而客户已经在电话那头叹了一口气。

站在记忆系统的角度,关于这一层只需要记住两件事:它是最短命的一层,它的产物不应被当成长期记忆事实;而且它丢东西的时候,是无声的。

会话记忆自己不脏,脏的是从会话里抽出来的东西,被当成事实存了下去,这正是第 08 章记忆污染要讲的事。

五、第二层:持久记忆,让下一次通话有上下文

持久记忆存的是关于实体的事实——客户、账户、对话,它们比任何单次会话活得更久,每次对话结束后,你把重要的部分抽出来,存到未来会话找得到的地方。

存储本身没什么花样:每条记忆要有唯一标识、归属对象、内容、来源、创建时间,再加访问次数和最近访问时间。

难的是判断该往里放什么。

整段对话原样扔进去是最省事的,但那是知识库,不是记忆。

区别在指向:知识库回答我们有什么规定,记忆回答这位客户是什么情况。

所以要有一道抽取:对话结束后,让模型通读一遍,只挑出下次这位客户再来时用得上的,偏好、诉求、承诺、账户信息——这些要留;寒暄、您好请问有什么可以帮您、客户提了个问题,这类没有信息量的描述,一句都别留。

抽出来的每条还得能自己站住,因为一条记忆将来要能被单独召回、单独比较、单独替换,它先得是一句完整、独立的话,而不是半截需要回原文才能读懂的片段。

1.实体范围界定。

一条记忆首先得回答它属于谁——这就是实体范围界定:它该挂在某位客户名下,还是挂在某个账户、某次会话名下?边界划不清,后果很直接。

如果所有记忆都丢进一个公共池子、按相似度去捞,那客户 A 打进来时,系统完全可能把客户 B 的信息递上去——这不是准不准的问题,是能不能出事的问题。

2.TTL(生存周期)。

这位客户在等回电,今天有用,两周后就是干扰;这位客户习惯用文字沟通,放几个月都成立——不同事实,该活的时长并不一样。

不给每条记忆各自设一个 TTL,库里就会积压一批说起来没错、用起来误事的旧条目。

3.溯源追踪。

这条记忆是机器从对话里抽的,还是手工补的?抽的方便,但也更容易错——模型可能抽偏、抽漏,甚至把一句气话当成结论。

手工的可靠性更高,所以要把它的来路一并存下:哪次对话、什么时候写进来的,有了这条链路,日后才能按出处给不同记忆配不同权重,出了问题也追得回去——这就是溯源追踪。

4.去重。

同一位客户十次提到偏好邮件,如果不去重,库里就躺着十条几乎一样的内容。等召回时,这几条会把名额占满,把别的有用信息挤出去。

去重要放在写入那一刻:持久层至少先过一道粗略的相似检查,精细的合并留到语义层。

六、第三层:语义记忆,在对的时刻捞回对的记忆

一位客户身上可能存着几百条记忆,Agent 需要的是其中与当前这轮对话相关的那几条——而不是把全部记忆倒进模型。

客户问起那个物流的事,你要找的是那条关于包裹延误的记忆,而不是关于账单偏好的那条。

可关键词在这里帮不上忙——客户嘴里说的是物流,而库里那条写的是三号仓发出后被转运中心扣住、预计月底才能派送,两边一个字都不重合,但谁都知道该选哪条。

语义检索用嵌入解决这个问题:把一段文字转成一组数字(向量),这组数字代表它的语义,意思越接近的两段文字,它们的向量在空间里就越靠近。

于是找相关记忆就被翻译成了算距离——把当前问题也转成向量,再和库里每一条比一比,取最近的几条。

衡量靠近的常用尺度是余弦相似度:看两个向量的方向是否一致,结果落在 0 到 1 之间。越接近 1,语义越像。

检索里最要紧的参数,不是取几条,而是最低分。

如果只是按相似度排序取前几名,那每一次查询都会有结果——哪怕库里根本没有相关的记忆,客户问价格,系统照样把一条物流记忆以 0.1 的相似度递上来,还觉得自己完成了任务。

这些不相关的条目混进来,只会干扰模型。定一条底线(比如 0.3),低于它的一条都不要,宁可什么都不给,也别给噪声。

七、三层记忆拼接:如何合成系统提示词?

三层都齐了,接下来要把它们合成一个装配器:在 Agent 每次作答之前跑一遍,把这位客户身上值得说的东西拼成一段文字,作为系统提示的一部分送进去。

拼的顺序本身就是一种判断:

先放客户档案。 

这位客户的全部持久事实,按最近访问、访问频次排个序,但一定要卡数量——不卡的话,一位老客户能轻松把窗口占满,十条左右是个稳妥的起点。

再放相关过往。

语义检索挑出来的那几条历史互动,这里不用再筛——语义层已经筛过了,再加一道只会削弱信号,可以把相关度一并带上(比如 89% 相关),让模型自己掂量该有多看重。

最后放当前对话。

正在进行的这一通,压在末尾。

为什么当前对话要放最后?因为模型对一段输入的开头和结尾更敏感,而现在正在发生什么,是它此刻最该盯住的,越具体越靠前,越当下越靠后——这条经验法则值得记住。

拼完之后,Agent 才第一次说得出这样一句:我看到上周在处理您的物流延误,让我查一下最新进展,而不是让客户从头讲起。

三层到这里就齐了:会话记忆管当前这通别断线,持久记忆管事实跨会话存活,语义记忆管在对的时刻取回对的那条。

八、面向真实用户的AI智能客服系统:五种生产故障模式

上面三层,在演示环境里都不会出问题,一个人、一个测试账号、几十条记忆、输入可控。

一旦真实客户进来,情况就变了,下面五处,是这套记忆系统会翻车的地方——而且每一处都比看起来更难补。

1.记忆污染

Agent 遇到过一通难缠的电话,客户情绪很激动,说了不少重话,抽取环节照实记下了一条:这位客户对服务强烈不满,态度对抗。

三个月后,客户来问一件毫不相干的小事,Agent 把那条记忆捞了出来,开场白成了这样一句:我注意到您过去对我们有些不满,这次我一定格外仔细。

客户早把那次不愉快丢在脑后,现在却被重新提醒了一遍,更糟的是,Agent 的语气变得过分小心、过分抱歉,而对方只是想要一个干脆的答复。

旧情绪没到期,就会污染新关系。

修法不止是加个期限,有些事实记忆(账户信息、偏好)本来就该长期保留,一刀切地设短过期时间,只会把有用的东西一起清掉。

你需要先给记忆分类:事实 vs 情绪,可操作 vs 仅历史;再让情绪类的衰减速度快于事实类。

而这要求在写入的那一刻就打上类别标签——事后回头补,是补不上的。

2.隐私与合规

客户随口提了一句:我听力不太好,您说慢一点。

抽取环节贴心地记了下来,于是库里多了一条健康信息,取决于行业,这可能构成相关违规。

隐私友好的记忆,需要在写入那一刻就做内容识别:在敏感信息落进持久存储之前就认出来、打上标。

它还需要按类别划分的保留策略,以及谁在什么时候读了哪条记忆的审计日志。这三样,都得在存储层设计阶段就留好位置。

3.跨Agent污染

客服 Agent 留下过一条:这位客户在比较其他家的方案,后来销售 Agent 在另一通对话里把它捞了出来,顺势改成挽留话术:听说您在对比别家,那我给您重点讲讲我们新上的能力。

客户从没主动跟销售提过这件事,他的第一反应不是被重视,而是被盯上了——那通客服对话本应是保密的,现在却被拿去对付他自己。

这是Agent作用域问题,多Agent系统里,记忆不该在不同角色的代理之间自由流动,客服记忆是客服上下文,销售记忆是销售上下文,有些可以共享(账户信息、账单状态),但情绪上下文和竞争情报,默认应当隔离。

难点在默认隔离这个方向,如果系统一开始是全局共享的,事后想补作用域,就得把每一条已有记忆重新过一遍——还要逐条判断谁有权访问,这是一场没有终点的考古。

4.规模与成本

算一笔账,一万个客户,人均 50 条记忆,就是 50 万条带向量的条目。

单个客户打进来时,检索只在他的记忆里比——大概 50 次比较,很快,但那次把问题转成向量的调用本身就要几十到上百毫秒,在延迟预算低于 300 毫秒的语音场景里,这是一笔不小的开销。

再把抽取算进来,每通对话结束触发一次抽取,每条抽出来的事实再触发一次向量化,按每天 200 通算,就是 200 次抽取,外加大约 600 次向量调用。

单次成本很小,但它在持续累积——而且它会随着客户数和使用量线性增长,不会自己收敛。

更要命的是检索方式,如果在内存里逐条比对,开销随记忆条数线性上升,某位高接触企业客户攒到上万条记忆时,检索延迟就肉眼可见了。

生产系统用的是近似最近邻(ANN)索引——HNSW、IVF 之类等等,用一点点精度换大幅度的速度提升,这是从能跑到能规模化的分水岭。

5.去重噩梦

客户在三个月里换着说法提过十几次收货地址,每次抽出来的措辞都不太一样:

  • 客户地址是杭州西湖区某某路 12 号
  • 收货地点:杭州市西湖区某某路 12 号 3 单元
  • 寄往杭州西湖区的那个地址
  • 客户说东西寄到他杭州那边就行

任何和地址沾边的查询,都会一次返回其中三四条,它们说的是同一件事,但每一条都在吃掉本可以装更有用信息的空间。

插入前先查一下有没有相似的——听起来简单,可相似这个词本身就是模糊的,精确匹配会漏掉上面所有变体;阈值定得太高(比如 0.95),又会把语义相近、但确实不同的两条记忆误并成一条。

而且,记忆更新了怎么办?客户搬家了,这时候新地址应该顶掉旧地址,而不是与它并列,系统得能分清这条是推翻了那条,还是补充了那条——而这两者在文字层面可能长得很像。

生产级去重需要四件事:插入前的相似检测、近似条目的合并、矛盾条目的取代,以及区分同一件事的不同说法,与两条听起来像、其实是两件事。

五种模式摊平来看

故障模式

表现

本质

需要补的能力

记忆污染

旧情绪污染新交互

情绪记忆衰减不够快

记忆分类 + 差异化衰减

隐私与合规

敏感信息入库、删除不彻底

缺写入时的分类与保留策略

内容识别、保留策略、审计日志

跨Agent污染

角色之间记忆越界

没有Agent作用域概念

Agent作用域 + 显式共享

规模与成本

检索延迟与费用失控

暴力检索 + 逐条向量化

ANN 索引 + 向量库

去重噩梦

同一事实多条并存

相似判定模糊、缺更新语义

相似检测 + 合并 + 取代

看一眼本质那一列,会发现它们有个共同点:没有一个是实现有 bug, 全都是架构缺一层,每一个都要求你在存储层重新做决定,而不是在业务代码里打补丁。

资料展示:
下面是我整理的AI大模型      学习资料和工具包预览,适合收藏后按主题逐步学习

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐