多轮对话老是丢前文——MemT 1.0 的记忆到底该存在哪一层?

文章导读
对话到第四五轮开始答非所问,先别急着换模型,也别急着把上下文窗口调大。丢前文通常发生在三个不同位置:会话窗口被截断、该轮内容根本没写进外部存储、或者写进去了但检索没取回来。三者的修法完全不同——截断要改窗口或摘要策略,未写入要查写入链路,未取回要查检索与注入。按轮次摊开、按层级定位,比在提示词里反复加“请记住上文”更有效。
📋 目录
  1. 一 在会话记录里定位第一次出现指代失败的那一轮
  2. 二 区分该轮属于截断、未写入还是未取回
  3. 三 对照三层各自负责保存什么
  4. 四 用指代回指问题做一次最小验证
A A

对话到第四五轮开始答非所问,先别急着换模型,也别急着把上下文窗口调大。丢前文通常发生在三个不同位置:会话窗口被截断、该轮内容根本没写进外部存储、或者写进去了但检索没取回来。三者的修法完全不同——截断要改窗口或摘要策略,未写入要查写入链路,未取回要查检索与注入。按轮次摊开、按层级定位,比在提示词里反复加“请记住上文”更有效。

建议先把一次丢前文的会话按轮逐条摊开,标出第一次指代落空的那一轮,再判断该轮前文是完全消失、部分消失还是只在跨话题时消失:完全消失优先怀疑会话窗口截断;外部存储查不到该轮记录是写入问题;存储里有但召回为空是检索问题。三层各管一段,先定层再改配置,避免在错误的层上反复调参。具体阈值与开关以你环境的配置、日志和页面行为为准。

在会话记录里定位第一次出现指代失败的那一轮

“变笨了”不是可处理的问题描述。把一次出问题的会话导出成逐轮记录,标两列:用户这一轮想指代的到底是什么对象;模型回答有没有命中该对象。指代对象可以是表名、项目代号、人名、某个已确认的规则条目。命中与否只按事实判,不按语气判。

轮次用户指代对象模型是否命中备注
1定义:巡检对象 t_order,阈值 25 号—(定义轮)原始信息落点
2补充:只查未支付单命中正常
3“按刚才那个阈值”命中正常
4插入无关话题(导出报表)—干扰轮,但不算失败
5“那个表还是按原来的日子跑”未命中首次偏离,起因为“那个表”
与“原来的日子”两处指代

标注完成后,回看第 5 轮之前的窗口长度:从第 1 轮到第 5 轮一共多少条消息、有没有触发摘要、摘要里还留不留阈值和表名。这些都能在会话日志或调试面板里看到,不需要猜测。取日志时至少保留轮次序号、角色、时间戳、内容摘要,便于按 turn 对齐:

多轮对话老是丢前文——MemT 1.0 的记忆到底该存在哪一层?
# 用途:把一次会话按轮次导出,便于逐轮标注;字段名按实际环境替换
SELECT turn_no, role, created_at, left(content, 80) AS snippet
FROM chat_message
WHERE session_id = '替换为出问题的会话ID'
ORDER BY turn_no;

区分该轮属于截断、未写入还是未取回

三类现象的外在表现不一样,用同一份逐轮记录就能分开。判别时不要只看“有没有忘”,要看“忘得干不干净、什么时候忘”。

现象典型特征优先怀疑验证动作
前文完全消失早期轮次的定义、命名全无,模型反问“你指的是什么”;轮次越靠后越明显会话窗口截断把同一段信息分别放在第 1 轮和第 6 轮,看哪次还记得;查窗口条数与是否触发摘要
部分消失回答里出现相关但不正确的实体,或只记得大意记得错细节摘要压缩过度,或检索只召回片段对比摘要文本与原文,看被压缩掉的正是命名和数值
只在跨话题时消失连续追问都正常,插入一个无关话题后再问就丢未取回(召回排序被新话题挤掉)用原文实体名直接检索一次,能否命中该轮记录
外部存储查不到该轮同会话内检索为空,但刷新后新建会话也读不到历史未写入(写入失败、异步积压、条件过滤)按会话 ID 查消息表,确认该轮是否有行、是否有报错日志

一个常见误判是把“未取回”当成“截断”,于是不断加大窗口,结果是成本上去了、第四五轮照样丢。判断的分水岭很简单:外部存储里能不能查到这轮原文。查得到,问题就不在写入和窗口,而在召回与注入。

对照三层各自负责保存什么

把记忆拆成会话窗口、外部存储、模型侧记忆三层,各自负责的信息类型不同,混着用就会互相顶掉。下表是通用划分,具体容量上限、是否开放跨会话记忆,需要结合你所用的 MemT 1.0 界面与配置确认。

多轮对话老是丢前文——MemT 1.0 的记忆到底该存在哪一层?
层负责保存什么容量约束可见范围
会话窗口(上下文)最近若干轮原文、本轮检索注入的片段受单次请求 token 上限约束,超出即截断或摘要仅当前请求内可见,会话结束后不保留
外部存储(会话库/记忆库)全量轮次、抽取出的结构化事实(对象名、阈值、负责人、日期)容量按存储与检索方案定,但每次只能取回有限片段模型默认看不到,必须经检索后才能进入窗口
模型侧记忆稳定的偏好、长期设定、系统提示中固定注入的规则可注入的固定内容有限,不适合放长清单和逐轮细节跨会话可见与否取决于产品是否开放该能力,需在设置中确认

据此定分工:逐轮细节交给外部存储,靠检索按需取回;当前任务的操作约定放在会话窗口的靠前位置;长期稳定设定才考虑写进模型侧固定注入。把逐轮细节塞进固定注入,会挤占窗口且难以更新;把长期设定只放窗口,一截断就丢。

用指代回指问题做一次最小验证

不用复现整段业务对话,五轮就够。关键是第 1 轮埋入唯一可识别的实体,第 2、4 轮插入干扰,第 3 轮用原文名称回指,第 5 轮改用描述性指代,用来区分“截断”和“召回词面不匹配”。

多轮对话老是丢前文——MemT 1.0 的记忆到底该存在哪一层?
  1. 第 1 轮(埋点):“记一下:项目代号 ZQ-114,负责人老陈,验收日是每月 25 号。后面我会用‘那个项目’指它。”
  2. 第 2 轮(干扰):问一个与该项目无关的问题,例如让模型写一段导出 CSV 的说明。
  3. 第 3 轮(原名回指):“ZQ-114 的负责人是谁?”
  4. 第 4 轮(干扰):再插入一个无关话题,让窗口里多几条与本项目无关的内容。
  5. 第 5 轮(描述性回指):“那个项目验收日是几号?”——不使用代号,只靠指代。

每轮只记四件事:是否答出老陈/25 号、答出的值是否正确、外部存储该轮是否有记录、检索输入用的原始查询是什么。记录样式可以直接照抄:

turn1 defined: ZQ-114 / 老陈 / 25号   storage_row: yes
 turn2 干扰: CSV 说明                 storage_row: yes
turn3 原名回指 正确? [ ] 应为 老陈     recall_hit: [ ]
turn4 干扰: 另一个无关问题            storage_row: yes
turn5 描述回指 正确? [ ] 应为 25号    recall_hit: [ ]

结论按组合判断,不按单轮感觉判断:第 3 轮就答不出,且消息表里第 1 轮有记录——查窗口条数与摘要,属于截断层;第 1 轮在消息表里根本没有记录或写入报错——属于写入层;第 3 轮正确、第 5 轮错误,且用“ZQ-114”能检索到原文——属于召回层,通常是查询用了“那个项目”而文档里只有代号,需要在召回时补实体对齐或把代号与别名一起写入。三类问题分别改窗口、改写入链路、改检索与注入,改完用同一组五轮再跑一遍确认,不要把一次验证结果当成长期结论。