
1. 上下文管理不是记性好而是知道什么时候该忘很多人第一次听到上下文管理这个词脑子里浮现的是让模型记住更多东西。这个理解只对了一半而且是最容易踩坑的那一半。我见过太多项目一上来就拼命往上下文里塞历史记录结果 token 烧得飞快回答质量反而下降——模型被一堆无关信息干扰抓不住重点。上下文管理的本质是在有限的窗口里做信息取舍。它要解决的核心矛盾是对话需要连贯性但窗口容量是硬约束。你要做的不是记住一切而是判断哪些信息此刻必须出现、哪些可以压缩、哪些干脆丢掉。这跟人开会做笔记是一个道理——你不会把每个人说的每句话都记下来你只记结论、待办和关键分歧。这篇文章适合三类人看一是正在做对话类应用的开发者二是被 token 成本和响应质量两头夹击的工程同学三是想搞明白为什么我的助手聊着聊着就失忆了的产品同学。我会从窗口机制讲起把裁剪、摘要、检索、分层记忆这几套主流方案拆开讲透再给出一套可以直接抄的落地策略最后聊聊那些文档里不会写的坑。先说一个反直觉的结论上下文管理的最高境界是让用户感觉不到你在管理。用户只关心它懂我不关心你用了什么策略。所以所有技术手段都要服务于一个目标——在关键节点上把对的信息放到模型眼前。2. 窗口机制决定了你的策略上限2.1 上下文窗口到底装了什么要谈管理先得搞清楚仓库里都堆了些什么。一次请求送进模型的上下文通常由这几块拼成系统提示词角色设定、行为约束、输出格式要求这部分基本固定但往往最占地方。工具/函数定义如果你接了外部能力这些 schema 描述会常驻。历史对话用户和助手的往返消息这是增长最快、最需要管理的部分。检索到的外部知识RAG 场景下召回的文档片段。当前用户输入本次问题本身。很多人只盯着历史对话做文章却忽略了系统提示词和工具定义这两个隐形大户。我实测过一个项目光工具定义就占了将近三分之一的窗口历史对话还没开始堆空间就紧张了。所以做管理的第一步是先量一下各部分的实际占用别凭感觉优化。2.2 为什么塞满是错误目标窗口大不等于效果好这里有两个机制在起作用。第一是注意力稀释上下文越长模型对单个信息的关注度越容易被摊薄关键指令可能被淹没在噪声里。第二是位置偏差大量实验表明模型对上下文开头和结尾的信息利用得更好中间部分容易被忽略。你把最重要的约束放在正中间等于主动降低它的权重。所以正确的目标不是用满窗口而是让关键信息落在高注意力区域同时把总量控制在合理范围。这就引出了后面所有策略的设计原则重要的往前放或往后放次要的压缩或丢弃。2.3 一个必须先做的动作给上下文建预算在写任何裁剪逻辑之前先给各类内容分配 token 预算。我的习惯是这样切内容类型建议预算占比说明系统提示词10%~15%越精简越好能合并的规则合并工具定义10%~20%按需加载不用的工具别挂检索知识20%~30%按相关度截断宁少勿滥历史对话30%~40%动态伸缩的主要区域当前输入与输出预留10%~15%必须留够否则会被截断这张表不是标准答案但它能帮你在动手前想清楚哪里可以省。预算定下来之后任何一块超支都要触发对应的处理策略而不是无脑挤占其他区域。3. 裁剪、摘要、检索三套主流方案的取舍逻辑3.1 滑动窗口裁剪最简单也最容易翻车滑动窗口的思路很直接只保留最近 N 轮对话超出的丢掉。实现成本极低几行代码就能搞定。但它有个致命问题——丢掉的可能是关键前提。用户第一轮说我在做一个面向儿童的绘本应用聊了二十轮之后问配色怎么调你把开头丢了模型就不知道受众是儿童给出的建议可能完全跑偏。我的改进做法是滑动窗口 锚点保留滑动丢弃普通轮次但把用户明确表达过的长期约束身份、偏好、硬性要求抽出来作为锚点常驻在系统提示词附近。这样既控制了长度又不会丢掉核心前提。判断哪些是锚点可以靠规则比如用户说记住以后都这类词也可以让模型在每轮结束后做一次轻量抽取。3.2 滚动摘要把历史压成一段话滚动摘要的做法是当历史超过阈值就让模型把较早的对话总结成一段简短摘要用摘要替换原始消息。这样能把几十轮压缩成几百 token信息密度高。但摘要有个隐蔽的坑摘要是有损的而且损失不可控。模型总结时可能丢掉它认为不重要、但对你很关键的细节比如一个具体的数字、一个专有名词。我踩过一次用户报的订单号被摘要概括掉了后面排查问题完全对不上。所以我的经验是摘要只用于叙事性、背景性的内容凡是精确信息ID、金额、日期、代码片段一律原样保留不进摘要。可以维护一个事实槽位结构专门存这些精确值摘要负责讲清楚发生了什么槽位负责记住具体是什么。3.3 检索式记忆按需召回而非全量携带检索式记忆的思路是把历史对话存进向量库每轮根据当前问题召回最相关的若干条。它的优势是理论上可以记住无限长的历史而且只把相关的调出来不浪费窗口。代价是引入了检索的不确定性。召回不准模型就失忆召回太多又变成噪声。我一般会做两件事来稳住它一是混合检索向量相似度加上关键词匹配避免纯语义检索漏掉精确匹配二是设置相关度阈值低于阈值的宁可不召回也不要硬塞。空着比塞错强。3.4 三套方案怎么选没有银弹看场景场景特征推荐方案理由短对话、轮次少滑动窗口简单够用别过度设计长咨询、需要背景连贯滚动摘要 锚点平衡长度与连贯知识密集、需精确回溯检索式记忆按需召回容量无上限复杂助手、多任务分层组合不同信息用不同策略实际项目里我几乎没见过只用一种方案的。分层组合才是常态系统提示词常驻长期约束做锚点近期对话保留原文远期历史做摘要精确事实进槽位外部知识走检索。每一层管好自己的事整体才稳。4. 分层记忆架构把记什么和记多久分开设计4.1 四层记忆模型我把上下文管理拆成四层从快到慢、从短到长工作记忆当前这一轮正在处理的信息包括用户输入和刚召回的内容生命周期就是这一轮。短期记忆最近若干轮对话原文保证即时连贯超过阈值就往下沉。长期记忆经过摘要或抽取的稳定信息比如用户偏好、项目背景、已确认的结论。外部记忆向量库或数据库里的全量历史按需检索。这个分层的好处是职责清晰。工作记忆只管当下短期记忆管连贯长期记忆管稳定外部记忆管兜底。每层有自己的容量和淘汰规则互不干扰。4.2 信息在层间怎么流动关键是定义好下沉和上浮的触发条件。我的做法是短期记忆超过 N 轮最老的轮次触发下沉先抽取精确事实进长期记忆的槽位再把剩余叙事内容并入摘要。当前问题进来时先查长期记忆的槽位有没有相关约束再决定要不要去外部记忆上浮检索。每轮结束做一次轻量整理把新产生的稳定信息写进长期记忆。这套流动机制的核心是异步整理——不要在用户等待响应时做重活把摘要、抽取这些耗时操作放到轮次结束后异步跑。否则响应延迟会很难看。4.3 长期记忆的写入要克制新手最容易犯的错是什么都往长期记忆里塞。结果长期记忆越来越臃肿每次都要全量加载等于没分层。我的原则是只有跨轮次仍然有效、且未来大概率会用到的信息才写入长期记忆。一次性的问答、临时的寒暄聊完就让它随短期记忆自然淘汰。判断标准可以简化成一句话如果这条信息在下一轮就失效了它就不配进长期记忆。用户说帮我查下今天的天气这个今天明天就没用了不该记。用户说我习惯用中文回复这是长期偏好该记。5. 一套可以直接抄的落地策略5.1 先量化再优化动手前先埋点统计每次请求各部分的 token 占用和命中情况。没有数据支撑的优化都是瞎猜。我一般会记录总 token 数、各层占比、裁剪触发次数、摘要触发次数、检索召回条数和相关度分布。跑上一周你就能看出瓶颈在哪。5.2 分阶段实施路线别想一步到位按这个顺序推进比较稳第一阶段实现滑动窗口 锚点保留。成本最低先解决聊久了失忆的问题。第二阶段加入滚动摘要和事实槽位。解决长对话的连贯性。第三阶段接入检索式记忆。解决知识密集场景的回溯需求。第四阶段做分层调度和异步整理。把响应延迟压下来。每上一个阶段都要用真实对话回放验证效果别只看指标。5.3 关键参数怎么定几个我常用的经验值供参考短期记忆保留轮次8~12 轮视单轮长度调整。摘要触发阈值短期记忆占用超过预算的 70% 时触发。检索召回条数3~5 条多了就是噪声。相关度阈值先用 0.7 起步根据召回质量微调。输出预留至少留 15% 窗口给模型生成否则容易被截断。这些数字不是圣旨但能帮你快速起步避免从零调参。6. 那些文档里不会写的坑6.1 摘要会漂移滚动摘要做多了会出现信息漂移每一轮摘要都基于上一轮摘要再总结几轮下来原始信息被层层稀释最后变得面目全非。这跟传话游戏一个道理。我的对策是定期回源每隔若干轮用原始对话重新生成一次摘要而不是在旧摘要上叠加。虽然多花点算力但能防止信息失真。6.2 锚点也会过期锚点保留解决了丢前提的问题但锚点本身可能过期。用户上个月说我在用某框架这个月可能已经换了。如果锚点不更新模型会基于过时信息给建议。所以要给锚点加时效标记定期让用户确认或自动失效。6.3 检索召回的假相关向量检索经常召回看起来相关其实没用的内容。比如用户问怎么优化查询速度召回了一堆讲查询语法的片段语义相近但答非所问。这时候重排序很关键先粗召回一批再用更精细的模型或规则重排把真正有用的顶上来。别省这一步它直接决定检索式记忆的成败。6.4 多轮工具调用会撑爆窗口如果助手会调用外部工具每次调用的请求和返回都会进上下文几轮下来窗口就满了。我的做法是工具结果只保留摘要和关键字段原始返回存到外部需要时再取。比如查数据库返回一百行上下文里只放查到 100 条前 3 条是……其余按需拉取。6.5 别忽略沉默成本有些信息用户没说但隐含在场景里。比如用户一直在问某个项目的细节说明这个项目是当前焦点。这种隐式上下文如果丢了体验会很割裂。可以在每轮做一次轻量的焦点推断把当前话题作为软锚点带上成本很低但效果明显。7. 我踩过的几个真实教训第一个教训关于过度摘要。早期我为了省 token把摘要压得极短结果模型经常答非所问。后来发现摘要不是越短越好保留足够的因果链比压缩字数更重要。一段好的摘要应该能回答为什么走到这一步而不只是发生了什么。第二个教训关于检索阈值。我一度把阈值设得很低想着多召回总比漏召回好。结果模型被一堆弱相关内容带偏回答质量反而下降。后来把阈值调高宁可这轮不召回让模型基于已有信息回答效果反而更稳。召回不足可以靠追问补救召回错误会直接污染回答。第三个教训关于异步整理的时序。有次我把摘要任务和用户请求放在同一个队列里结果高峰期摘要任务把响应任务堵住了延迟飙升。后来把整理任务单独隔离用低优先级队列跑才解决。用户等待的路径上只放必须同步做的事。8. 怎么验证你的上下文管理真的有效光看感觉变好了不算数得有可复现的验证方法。我常用两招一是长对话回放。准备一批几十轮的真实对话记录让系统跑一遍检查在关键节点上是否还能正确引用早期信息。比如第 30 轮问一个只有第 2 轮提过的细节看它答不答得上来。二是干扰测试。故意在历史里插入无关信息看系统会不会被带偏。好的上下文管理应该能过滤噪声而不是被噪声牵着走。三是成本对照。记录优化前后的平均 token 消耗和响应延迟用数据说话。我做过一次优化平均 token 降了四成响应质量没降这才是真的有效。9. 关于上下文管理我最后想说的这套东西没有终点。窗口在变大模型在变强今天的最优解明天可能就过时了。但有一条底层逻辑不会变上下文管理的核心不是技术是判断力——判断什么信息此刻最重要判断用户真正在意什么判断什么时候该记、什么时候该忘。我见过太多团队把精力花在堆技术上却忘了问一句用户到底需要它记住什么。技术是手段体验才是目的。把这句话想清楚剩下的都是工程问题。如果你刚开始做我的建议是先从最简单的滑动窗口加锚点做起跑起来收集数据再逐步加层。别一上来就搞复杂架构你会在调试里迷失。等真实数据告诉你瓶颈在哪再针对性优化这条路走得最稳。