上下文窗口管理:长对话不丢重点
当你和模型聊了几十轮,突然发现它「忘了」开头定下的规则或偏好,多半不是模型记性差,而是上下文窗口管理没做好。窗口是固定长度的,超出的内容会被截断,而即便没截断,过长上下文也会让模型更难聚焦重点。如何在有限窗口里不丢关键信息,是长对话与长文档任务的核心工程问题。
窗口限制的表现
- 截断:超过上限的历史直接被丢弃,模型对早期约定一无所知。
- 早期信息被遗忘:即使内容在窗口内,离当前越远,模型在生成时赋予的注意力权重往往越低,关键前提被稀释。
这类问题在客服长会话、代码长上下文、多步骤推理中尤其常见。
管理策略
- 滚动摘要:定期把较早的对话压缩成一段摘要,替换掉原始多轮内容,腾出空间给近期交互。
- 重要信息置顶:把用户偏好、任务目标、硬性约束等「元信息」固定在提示开头,每轮都可见,避免被后续内容淹没。
- 分层记忆:区分「工作记忆」(当前几轮)与「长期记忆」(已存数据库或摘要),需要时再取回,而不是把所有历史都塞进窗口。
下面是一段把多轮对话折叠成摘要的示例:
def summarize_history(history, summarizer, keep_recent=4):
recent = history[-keep_recent:] # 保留最近几轮原文
older = history[:-keep_recent]
if not older:
return recent
digest = summarizer(older) # 把更早的轮次压成摘要
return [{"role": "system", "content": "此前摘要:" + digest}] + recent
核心思想是:越久远越该被压缩,越近期越该保真。
何时改用向量检索
当历史长到摘要也放不下,或需要跨大量文档精确回忆时,全量上下文不再经济。此时更合适的做法是把历史或文档写入向量库,按需检索最相关的片段注入当前窗口,也就是把「记忆」外置。这比把所有内容常驻上下文更省 token,也更能抗截断。
需要权衡的是:检索会引入相关性与召回问题,关键但罕见的信息可能没被检索到,因此常把「重要信息置顶」与「向量检索」结合使用。
小结
上下文窗口管理通过滚动摘要、重要信息置顶与分层记忆,在固定长度的窗口里保住关键前提与近期交互,缓解截断与注意力稀释。当历史或文档过长、摘要也难以容纳时,应把记忆外置到向量检索,按需注入当前上下文。置顶元信息与检索结合,是在成本与保真之间最稳健的折中。
参考与延伸阅读
- 关于对话记忆与摘要的研究可追溯至对话系统的摘要式记忆方案;具体算法与开源实现以各框架文档为准。待核实。
- 向量检索替代全量上下文的思路与 RAG 一致,可参考向量数据库与检索增强生成的相关文档。待核实。
本文累计阅读 — 次