等一下,请寄到另一个地址
想象一个帮助安排配送的客服聊天机器人。用户先提供一个地址,几轮之后又更正了地址。对话接着聊了配送时间、包装和收据。最后用户问:“你们会寄到哪里?”
机器人可能记得两个地址,却仍然答错。关键不在旧地址是否还留在记录里,而在它是否知道旧地址已经被替换。
下面是一个简短示例。对话和回复均为说明性内容,并非模型运行结果。我们尚未实际运行本文三种策略的对比。本文是一份调试指南和可复现的测试协议,不是已测量结果的实验报告。
| 轮次 | 对话 |
|---|---|
| 1 | 用户: 把样品包裹寄到浦那市湖路 14 号。助手: 我记录的收货地址是浦那市湖路 14 号。 |
| 2 | 用户: 更正一下,请改用浦那市山街 82 号。第一个地址已经过时。助手: 明白了,我会使用浦那市山街 82 号。 |
| 3 | 用户: 星期五能送到吗?助手: 我可以帮你查看星期五的配送选项。 |
| 4 | 用户: 包裹是一个小盒子。助手: 好的,一个小盒子。 |
| 5 | 用户: 请放入一张纸质发票。助手: 我会在配送要求里注明纸质发票。 |
| 6 | 用户: 之后我可以追踪吗?助手: 发货后可以提供追踪信息。 |
| 7 | 用户: 如果星期五要额外收费,就选普通配送。助手: 我会注明:星期五若需额外收费,就选择普通配送。 |
| 8 | 用户: 收件人下午五点后会在家。助手: 我会注明收件人五点后有空。 |
| 9 | 用户: 标签上应该写什么?助手: 可以写收件人姓名和收货地址。 |
| 10 | 用户: 你能总结一下配送信息吗?助手: 一个小盒子、一张纸质发票;如果星期五额外收费,就选择普通配送。 |
| 11 | 用户: 谢谢。助手: 不客气。 |
| 12 | 用户: 我们继续吧。助手: 好的。 |
| 探测问题 | 用户: 包裹应该寄到哪个地址?助手: 待评估的回复。 |
预期状态很简单:山街 82 号是当前地址;湖路 14 号已被替代。但如果摘要只说“用户讨论过湖路 14 号和山街 82 号”,它虽然保留了两句话,却丢掉了决定。
这正是本文想探讨的区别:好的记忆不是记得更多,而是记住哪些信息仍然成立。
对话是一连串状态变化
对话记录记下人们说过什么。应用行为依赖的则是一小组不断变化的事实:哪些仍有效、哪些已被替换、哪些是允许的、哪些还在等待处理,以及哪些只是推测。
聊天机器人可能用一段通顺的文字保留了对话主题,却抹去了恰恰决定下一步的区别。“用户讨论了发送订单”无法说明发送是已获批准、暂缓处理,还是已经完成。“用户正在替公司下单”也不同于“助手猜测这可能是公司订单。”
有用的测试不是摘要读起来是否顺畅,而是系统能否用这份摘要回答具体问题,或选择被允许的下一步。记住状态,而不只是那句话。

记忆需要保留的六类信息
以下六类适合用来测试,因为它们要求记忆保留信息之间的关系和状态,而不只是关键词。
| 失败类型 | 对话变化 | 后续回复应如何处理 |
|---|---|---|
| 事实更正 | “用地址 A。”后来改为“其实用 B。” | 使用 B,并把 A 视为已替代。 |
| 否定指令 | “准备好订单,但先别寄。” | 保留这一限制。准备订单不代表获准寄出。 |
| 未完成任务 | 用户要求为 25 把椅子起草报价,表示稍后提供木材饰面,之后说“用胡桃木饰面”。 | 将新信息关联到待办报价;收到信息不等于报价已经完成。 |
| 事实与假设 | 助手猜订单是替用户公司购买,用户未确认。 | 说明用途尚不清楚,不要把猜测当事实。 |
| 偏好改变 | “选 X。”后来改为“我改变主意了,选 Y。” | 把 Y 当作当前偏好。 |
| 已完成状态 | 可信的订单服务收据确认订单已寄出。 | 识别操作已经完成,不要建议重复寄出。 |
最后一种情况需要仔细区分。订单已经寄出这一历史记录仍然成立,变化的是“寄出”是否还是待办事项。记忆可以帮助模型理解对话,但不能替代应用的权威交易记录或权限检查。
延续对话的三种方法
若要单独考察记忆表示方式,可以比较三种明确配置。
完整历史会把此前的所有消息和最终探测问题一起提供给模型。模型能看到完整记录,但这不保证它一定会正确理解每次更正。
近期消息窗口只提供最近四组完整的用户与助手对话。更早的内容会被省略。四组只是便于说明的实验设置。四组对话是实验配置,不是生产环境的推荐窗口。 实际应用应根据任务、模型和上下文预算来选择窗口。
结构化滚动摘要会保留较早对话的累计摘要,再附上最近四组对话。旧对话移出近期窗口时,摘要器会将它们合并进已有摘要。

这只是三种具体的参考配置,不代表所有实现方式。近期窗口可以有不同长度;摘要也可以结合数据库、检索或人工维护的状态。比较的重点是:重要信息在对话中前移或后移时,这些具体输入分别保留了什么。
滚动摘要具体应包含什么?
如果系统的任务是保留可用于后续行动的状态,摘要就应当明确呈现状态。下面是一份聚焦于地址的说明性状态快照:
这六个部分让我们可以提出具体问题:哪个值是当前的?它取代了什么?什么指令限制下一步操作?还有什么问题尚待解决?哪些事情已经完成?哪些细节只是猜测?
这是测试协议的参考设计,不是模型运行结果,也不是 ModelRiver 当前的生产结构。ModelRiver 目前用 summary、facts、actions 和 open_items 表示 session 摘要。这里更细的结构仅用于展示应用可能追踪的区别;单靠 schema 无法保证信息一定被准确保留。
有必要明确测试这一点。Anthropic 关于上下文工程的指南 提醒,过度压缩可能丢失直到后来才显出重要性的细节,并介绍了用结构化笔记追踪长期任务进度和依赖的方法。Anthropic 的 compaction 文档 说明了如何用摘要替换较早的轮次,同时保留近期轮次。这些资料提供了实现参考,但不能证明哪种策略能保留本文六类案例中的状态;这正是下面协议要检查的问题。
一套可用于自己聊天机器人的测试方法
随文提供的测试案例包包含十二段合成对话,覆盖六种失败类型,每类两个版本。每段对话包含十二轮此前的用户与助手交流,以及一个最终探测问题。预期状态和可接受的后续行为也记录在案例中。
每一对案例的内容相同,只调整关键信息出现的位置。早期版本在八轮无关对话之前给出更正或指令;晚期版本则在八轮之后给出。两种版本之后都接两轮中性对话,再回答探测问题。位置信息是刻意测试的变量:近期窗口对早期和晚期信息的访问会不同;滚动摘要是否能保留它们,需要实际检查,不能预设。
对每段对话,准备前面介绍的三种记忆输入。然后查看最终探测问题的实际输入,分别记录以下两项:
- 所需状态是否保留? 输入是否区分当前事实和已被替代的事实、是否保留限制、是否说明任务待办还是已完成、是否标记尚未确认的信息?
- 回复是否正确处理状态? 回复是否遵循该状态、询问缺失信息,并避免提出被禁止或已经完成的操作?
记录探测时的记忆 token 数量和回复正确性;如果运行实时模型,还应记下模型、设置、延迟、token 用量和估算费用。不同条件要使用相同的模型和设置。如果重复测试,报告案例数量和结果。这个小型协议用于探索,不是正式基准测试。
案例包附有参考 schema、摘要提示词和十二段对话案例,但没有 API 运行器,也没有已完成的实验结果。读者无需先下载文件即可上手:本文地址对话是一份完整的说明示例。下载案例中的地址更正相同,但使用固定的无关对话。
哪些状态保留下来了?
尚未实际运行模型,因此我们不能给策略排名,也不能报告成本、延迟或成功率。运行协议后,可以先填写下面的表格。横线表示尚未测量,不是零。
| 策略 | 探测时的记忆 token 数 | 状态保留 | 回复正确 |
|---|---|---|---|
| 完整历史 | — | — / 已评估次数 | — / 已评估次数 |
| 最近四组对话 | — | — / 已评估次数 | — / 已评估次数 |
| 滚动摘要 + 最近四组 | — | — / 已评估次数 | — / 已评估次数 |
按失败类型和早期、晚期位置分别报告结果,将部分保留单独记录,并展示两三个失败案例的实际记忆输入和回复。最终探测的成本与延迟应和维护摘要的额外工作分开;最终输入更短,仍可能需要额外的摘要调用。
没有供应商额度也可以开始:对照预期状态,人工检查完整历史和近期窗口的固定输入。手写摘要可以帮助定义目标结构,但不能验证模型的摘要质量。回复正确性和模型生成的滚动摘要,在实际运行前都仍未测量。
如何判断记忆在哪一步出错
以否定指令案例为例,下面是三种假设结果,用来说明如何诊断问题;它们不是实际观察到的模型输出。
指令丢失。 摘要写着“订单 1042 已准备好”,却省略了“获批准之前不要寄出”。回复因此建议寄出。此时应检查摘要环节:后续模型无法遵循从未收到的限制。
指令保留了,但回复没有遵循。 提供的记忆清楚写着 do_not_send_yet,模型却建议寄出。记忆保留了状态,回复却没有尊重它。这与摘要丢失指令属于不同问题。
答案碰巧正确。 摘要漏掉了暂缓指令,但模型刚好回复“我会先等等”。最终答案看起来安全,却不能证明记忆保留了信息;下一段对话中它可能就会出错。
将状态保留和行为正确分开评分。回复正确不能证明记忆质量好;记忆准确也不能保证模型一定遵循它。分别检查两者,才能找到应用中需要关注的环节。

先检查记忆,再判断答案为何出错
我们在构建 ModelRiver,所以这个问题也关系到我们的实现。它的 sessions 页面会显示当前滚动摘要,每轮的 Memory snapshot 则在有记录时展示该轮的记忆文本。当回复用了过时的事实时,这让人有材料可查。但这并不能证明摘要一定保留了正确状态。
如需了解 session memory 如何传入并返回,可先查看 session-memory API 文档或 session-memory 聊天机器人模板。要组装记忆,项目必须启用 request-body logging。ModelRiver 的 Test Mode 会返回预先配置的样例数据,无法检测实时模型是否记住或遵循了更正。那需要在自己的评估中调用实际模型。另需注意,ModelRiver 先使用原始历史,达到历史限制后再将其折叠为滚动摘要。其触发条件和结构与本文的四组对话参考配置不同,因此在 ModelRiver 中运行一段会话并不自动等于复现本协议。
在自己的聊天机器人上试试看
找一段包含更正的对话。在最后一个问题处,检查应用实际发送的上下文。它是否保留了哪个值才是当前值?再检查模型回复是否使用了这个值。
如果想尝试更多案例,十二段对话测试协议还包含否定指令、未完成工作、假设、偏好改变和已完成操作。这个方法足够精简,便于改成自己的例子;关键在于确认系统是否保留了下一步判断所依赖的状态。

