首页 文章 精选 留言 我的

精选列表

搜索[Agent],共10000篇文章
优秀的个人博客,低调大师

AI Agent 会话一长就失忆?上下文管理 4 种策略的取舍与落地对照

> 导读:做 AI 客服、AI 助手最常收到的投诉是:"前面明明说过的信息,聊到后面它全忘了。"这不是模型变笨了,而是上下文没管好。这篇文章给你一套可落地的上下文管理方案:先讲清楚"失忆"的底层原因,再用一张对照表讲清滑动窗口、优先级截断、摘要压缩、向量记忆四种策略各自适合什么场景,最后附可直接抄走的实现要点与踩坑清单。全文为通用工程做法,不绑定任何平台,拿来就能用。 ## 一、为什么会"失忆":窗口有限,而对话无限 大模型对单次请求能处理的文本量是有限的,这个上限就是上下文窗口。一次完整请求要把"历史对话 + 当前问题 + 系统指令"全部装进窗口里,对话轮次越多,占用的空间越大,超出窗口的部分只能被丢弃。 被丢弃的往往是最早的信息——而用户最早说的恰恰是需求、背景这类关键内容。更隐蔽的是"中间遗忘"现象:模型对开头和结尾的记忆明显好于中间,即便信息没被丢弃,落在中段的细节也容易在回答时"想不起来"。所以"失忆"本质上是两个问题:信息被截掉,和信息被稀释。 理解了这一点,上下文管理的目标就很清楚:在有限窗口内,尽量保留"最可能被用到"的信息,而不是机械地保留"最新的信息"。 ## 二、四种策略对照:先理清取舍,再实现 |策略|原理|优点|缺点|适合场景| | --- | --- | --- | --- | --- | |滑动窗口|只保留最近 N 轮,更早的直接丢弃|实现最简单、开销最低|早期关键信息必丢|短会话、闲聊型、对历史依赖弱| |优先级截断|按"重要程度"排序,低优先级先被淘汰|关键信息存活率高|需要给消息打重要性标记|有明确业务规则、可人工标注的场景| |摘要压缩|把早期对话实时压缩成摘要|信息留存率明显提升|有压缩开销与信息损失|长会话、需要连续理解上下文| |向量记忆|历史事实写入向量库,按需检索注入|理论上可存无限历史|工程复杂度最高、有召回误差|强依赖历史事实的垂直场景| 四种策略不是互斥的,生产环境几乎都是组合使用,这一点后面展开。 ## 三、滑动窗口与优先级截断的实现要点 滑动窗口最容易写错的地方是"按轮次切"还是"按 token 切"。按轮次切实现简单,但遇到一条超长消息(比如用户粘贴一大段日志)就会瞬间挤爆窗口;建议按 token 预算切,给系统指令和当前问题预留固定额度。 ``` // 滑动窗口:按 token 预算裁剪历史 function buildMessages(history, systemPrompt, maxTokens) { const budget = { system: 0, history: maxTokens - estimateTokens(systemPrompt) - 200 }; const kept = []; let used = 0; for (let i = history.length - 1; i >= 0; i--) { const t = estimateTokens(history[i].content); if (used + t > budget.history) break; kept.unshift(history[i]); used += t; } return [{ role: "system", content: systemPrompt }, ...kept]; } ``` 优先级截断的核心是给每轮消息打"重要性分":比如用户明确给出的约束("不要推荐超过预算的方案")记高分,纯寒暄记低分;窗口满时按分数从低到高淘汰,同时保证"用户最新一条"永远保留。 ## 四、摘要压缩与向量记忆:长会话的进阶方案 摘要压缩的思路是:每当历史超过阈值,就把"最旧的对话块"交给模型总结成一段摘要,之后用摘要代替原文参与后续对话。 ``` // 摘要压缩:旧对话块 → 一段摘要 async function compressOldest(history) { const block = history.splice(0, 6); // 取最旧 6 条 const summary = await summarize(block); // 调用模型生成摘要 history.unshift({ role: "system", content: `历史摘要:${summary}` }); return history; } ``` 注意摘要要"可增量更新":新摘要应基于旧摘要加新对话生成,而不是每次从头总结,否则长会话后期每次都要重算全部历史,既慢又贵。 向量记忆适合"事实型"信息:用户报过的手机号、偏好的地址、之前确认过的规格,都值得写入向量库;每轮对话前按当前问题做一次检索,把命中结果拼进提示词。它的代价是引入一次额外的检索链路,因此要做召回兜底——检索不到时宁可不用记忆,也不要注入错误事实。 ## 五、生产组合拳:近全量 + 摘要 + 按需检索 落到生产,推荐这样组合:最近 2~3 轮全量保留;再往前的历史维护一份滚动摘要;涉及用户画像、订单、偏好等强事实数据,独立走向量检索按需注入。三部分拼起来再进窗口,既保证连贯性,又控制体积。关键是要给每段内容打上来源标签,方便排查"这条信息是哪来的"。 ## 六、踩坑清单 - 只按轮次切窗口,被一条超长消息挤爆预算; - 摘要每轮全量重算,长会话耗时爆炸; - 向量记忆无兜底,检索不到时注入过期或错误事实; - 系统指令被历史挤出窗口,模型突然"忘了自己的身份"; - 只测 3 轮以内的短对话,上线后被长会话打回原形; - 没有记录每轮 token 用量,窗口爆了才发现。 ## 七、工程落地建议 落地顺序建议从简到繁:先埋点,把每轮对话的输入输出 token 用量、窗口占用率记录下来;再上滑动窗口,满足大多数短会话场景;当"长会话失忆"成为真实投诉后,再升级摘要与向量记忆。开源向量库、自研摘要服务都可以,核心是先建立度量,让每次改动都有数据说话。上线前用"20 轮以上的长对话脚本"做回归,模拟真实使用强度。 如需将上下文管理方案快速落地到业务会话中,可参考乔拓云轻应用产品。 ## 八、复盘清单 - 上线前:是否记录 token 用量?窗口预算是否给系统指令留了余量? - 上线后:长会话失忆投诉是否下降?摘要准确率是否有抽查机制? - 每次模型升级:重跑长对话回归,确认窗口策略仍然成立。 > 结语:上下文管理没有银弹,本质是在"保留什么、丢弃什么"之间做取舍。先度量、再分步升级,比一上来就上最复杂的方案更稳妥。本文与《企业知识库问答老答错?一张排查清单分清"检索问题"还是"生成问题"》同属 AI 工程落地系列,可对照阅读。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册