长程Agent上下文管理四板斧:压缩、检索、缓存与多Agent架构
去年年底我在调试一个多轮信息收集 Agent 的时候碰到了一个非常典型的现象:任务只进行了不到 20 轮,模型就开始把用户前面提过的关键约束忘得干干净净,回答里甚至出现前后矛盾。翻日志一看,上下文窗口已经塞满了原始对话记录,而真正重要的需求早就被挤到模型注意力够不到的位置。这个问题不是个例,凡是跑过长程 Agent 的人,大概都在某个时刻被“它明明答对了前面,怎么后面就乱了”这句话击中过。
这篇文章想把长程 Agent 上下文管理这件事一次性摊开说清楚。我会从场景倒推技术缺口,再把现在社区里比较主流的方案按“压缩、检索、缓存、架构”四条线拆开讲,结合 ICLR、ICML 2026 这个节点上大家正在争论的问题,最后给出一套可以直接照抄的配置思路和排查清单。不管你是正在搭 Agent 产品的工程师,还是准备做相关研究的同学,这篇文章应该能帮你省下一大段自己踩坑的时间。
1. 长程 Agent 为什么“记不住事”:从场景倒推技术缺口
1.1 长程任务到底包括哪些场景,上下文在哪一环失效
一说到长程 Agent,很多人第一反应是“窗口够大就行”。但真去跑几个任务就会发现,窗口长度只是最表面的一层。我实际接触到的长程场景大概有这么几类:
第一类是跨天甚至跨周的多轮助理对话。用户每天来问几句,Agent 要记住前几天的偏好、决定、未完成事项。这类任务的难点在于,不是所有历史都重要,但模型不知道哪些重要,只能把整段历史都塞进去。第二类是代码仓库级的重构任务。Agent 要浏览上百个文件,理解模块之间的依赖,然后在某个地方修改代码。这种任务里,上下文里可能只有 5% 的信息和最终修改相关,剩下 95% 都是背景噪声。第三类是数据分析类的长流程。Agent 要把取数、清洗、可视化、写结论串在一起,中间的中间结果如果不落盘,后续步骤就只能靠“猜”上一步做了什么。第四类是游戏或仿真环境里的探索型任务,Agent 需要长期记住地图结构、资源位置、已经尝试过的失败路径。
把这四类场景摆在一起,上下文失效的位置其实很一致:要么发生在输入阶段,模型窗口被塞满导致截断;要么发生在注意力阶段,信息虽然在窗口里,但模型根本没有关注到;要么发生在推理链阶段,早期的一个错误结论被后续步骤当成事实继续传播。这三层失效叠加起来,就会出现“看起来模型什么都记得,但回答就是不对劲”的诡异状态。
1.2 上下文管理是“存储”问题还是“决策”问题
很多团队遇到长程 Agent 记不住事,第一个想法是换更大的窗口模型,或者把所有历史不假思索地存进向量库。做过一轮之后会发现,换大窗口只是把问题往后推,塞向量库也只是从一个混乱变成另一个混乱。在我看来,上下文管理本质上不是存储问题,而是决策问题。
你可以把 Agent 的上下文理解成一个打工人的工作台。桌面太大会让人把所有文件都摊开,反而找不到最需要的那张;桌子小一点,反而会逼着你把重要文件放在手边,把不重要的归档。长程 Agent 的上下文管理,核心是回答四个问题:什么信息必须留在桌面上,什么信息应该被压缩成摘要,什么信息要到归档里临时翻出来,什么信息直接扔掉永远不回头。这每一个问题都是决策,不是存储。
理解了这一点,再看现在各种方案就会很清楚:压缩方案解决的是“哪些信息不值得占空间”,检索方案解决的是“哪些信息应该被临时找回”,缓存方案解决的是“哪些计算不应该重复做”,架构方案解决的是“谁来负责做这些决策”。所以别急着堆工具,先想清楚你的 Agent 在哪个环节最常犯错,再选对应方案。
2. 主流方案全景图:把长上下文拆成四种武器
2.1 压缩型方案:摘要与层级记忆怎么选
压缩是最直觉的思路。既然上下文太长,那就把历史对话或历史观察用一个摘要替掉。但摘要怎么做,差别非常大。
最简单的是“滚动摘要”,维护一个不断更新的 summary,每轮对话结束后把新的内容合进去。我给一个客户做过类似系统,最初方案就是每 10 轮对话触发一次摘要,把旧对话替换成 summary。跑了一阵发现两个问题:一是摘要模型本身会丢细节,用户之前提过“周二之前必须交付”,摘要里只剩下“尽快交付”;二是摘要会累积错误,如果某一轮摘要写错了,后面所有轮次都沿着这个错误走,而且非常难发现。
后来我把方案改成了“层级记忆”。第一层是原始对话,保留最近 20 轮;第二层是把每 10 轮对话压成一段事件摘要,保留最近 50 段;第三层再按主题把事件摘要聚合成主题档案。模型每次推理时,默认只加载第一层,需要追溯早期信息时才按需访问第二层和第三层。这个结构有点像人类的记忆,近事记得清,旧事记大概,重大事件单独存档。代价是实现复杂度高了不少,但信息丢失率明显下降。
还有一个容易被忽视的点:摘要里要保留“关键实体清单”。单纯让摘要模型“压缩这段对话”往往会写出流畅但空洞的概括,而如果你强制要求摘要输出时附带实体列表、数字和截止日期,后续检索和推理的可用性会大幅提升。
2.2 检索型方案:RAG 之外,Agent 记忆检索的技巧
提到检索,大家都会想到 RAG。但 Agent 的记忆检索和文档问答的 RAG 有本质区别:文档 RAG 检索的是静态知识,Agent 记忆检索的对象是动态的经历——对话、决策、结果、失败教训。这些记录之间有时间关系、因果关系,单纯靠向量相似度是抓不住这层结构的。
我在实践中比较常用的做法是“分桶存储加多路召回”。把记忆按类型分成几个桶:用户偏好、任务状态、常识事实、过往错误。查询时不是只做一次向量检索,而是针对当前意图,分别从不同桶里取候选,再做融合重排。举个例子,Agent 发现用户这次说的需求和一个小时前说的一模一样,那“用户偏好”桶里的记忆就应该比“常识事实”桶里的记忆加权更高。
另外两个技巧很实用。第一个是时间衰减权重。记忆检索不能只看相似度,时间越近的记忆应该默认加一点分,除非当前任务明确要求找回很久以前的约定。第二个是“检索结果必须带着来源标识”。我在设计记忆条目时,每条记录都会附上事件 ID 和时间戳,这样模型拿到检索结果时能知道这段记忆发生在哪个阶段,避免把旧状态当成当前状态。很多 Agent 出问题,就是因为模型分不清“用户曾经说过”和“用户现在的要求”。
2.3 缓存与 KV 优化:降低重复计算成本的正确姿势
长程 Agent 还有一个经常被忽略的问题——不只是“装不装得下”,还有“算不算得起”。每次多轮对话如果都要重新计算整段上下文的 KV(Key-Value)缓存,成本会随着轮次线性上涨。之前跑一个 50 轮的数据分析任务,光 token 费用就让项目经理脸色发青。
现在主流模型都支持 KV cache 复用,前缀不变的情况下,新的生成只需要计算增量部分。这就带来一个重要思路:尽量让 prompt 的前缀保持稳定。我在设计 Agent 的 system prompt 时,会把“模型总规则 + 工具定义 + 当前任务模板”放在最前面,把动态内容尽量放在后面。这样每次调用只要能复用前缀缓存,成本立刻降下来。
针对更极端的长上下文场景,社区里还有两类技巧值得关注:一类是滑动窗口加 attention sink 的做法,保持最近 N 个 token 的注意力完整,更早的内容以压缩表示参与计算;另一类是“关键 token 缓存”,把历史中反复被引用的实体、数字单独存成一小段固定表示。这些做法在具体模型上有不同的实现方式和使用约束,真要落地前务必先确认你用的模型 API 是否支持相关参数,别在文档没细看的情况下直接上生产。缓存方案最大的坑是缓存失效,prompt 任意一个前缀字节变动都会导致整段重算,所以 prompt 模板的改动要极其谨慎。
2.4 架构型方案:从单 Agent 到多 Agent 的记忆分工
单 Agent 负责所有事情,遇到长程任务就像让一个人既当前台又当会计还当仓库管理员,早晚要崩溃。多 Agent 架构把这些职责分开,是目前处理超长程任务最稳健的方向。
我在实际项目中用过一个三 Agent 结构:一个 Planner 负责拆解任务和记录全局状态,一个 Executor 负责执行当前步骤并返回结果,一个 Memory Keeper 负责读写长期记忆。Planner 的上下文里永远只放“当前目标 + 已完成步骤列表 + 下一步计划”,Executor 的上下文只放“当前步骤的输入”,Memory Keeper 不和用户直接交互,它只管把 Executor 返回的结果结构化地写进记忆仓库。这个分工让每个 Agent 的上下文都很短,而且各司其职,不会出现信息互相污染。
多 Agent 结构还有一个好处:可以给不同 Agent 配置不同的上下文管理策略。Planner 用压缩型方案就够了,因为它只需要知道“做了哪些事”;Executor 更适合检索型方案,因为它需要具体的事实和参数;Memory Keeper 则是纯粹的存储读写,不用参与推理。这种“按角色分配记忆策略”的思路,比让一个 Agent 什么都干要可控得多。
3. 从论文到落地:ICLR / ICML 2026 社区在关注什么
3.1 几个值得关注的研究方向
在 ICLR 和 ICML 这个方向上,长程 Agent 的上下文管理并不是一个全新话题,但 2026 这个节点上讨论的焦点明显更聚焦了。今年大家争论比较多的问题,我梳理下来大概是这几个:
第一个是评估基准的问题。现在很多工作还在用“窗口长度”作为卖点,但社区的共识正在转向“信息利用率”。也就是说,给你 128K 窗口,你能不能在这 128K 里准确定位那 3K 关键信息?如果模型只是把窗口撑大,但注意力还是集中在开头和结尾,这种能力就没有意义。围绕这个问题,ICLR 2026 有不少工作在做更细粒度的长程评测集,包括长文档里的跨段落推理、长对话里的潜伏信息召回、长代码里的跨文件修改等。
第二个是记忆结构的形式化。RAG 和向量检索更多是工程实践,但学术界想搞清楚:Agent 的记忆到底应该以什么粒度存储?是对话回合、事件、还是实体关系?不同的存储粒度对下游任务的成功率有什么影响?目前已经有工作尝试把记忆建模成带时间戳的有向图,让 Agent 在图上做条件检索,这个方向我觉得比简单的向量库有前途。
第三个是“上下文管理该前置还是后置”。换句话说,是让模型自己学会从长上下文里挑重点,还是在外围系统里先把重点挑好再喂给模型。前者是训模型的路线,后者是搭系统的路线。2026 年的趋势明显偏向后者,因为外围系统可控、可调试、可观测,而且不依赖未知的模型能力。
3.2 从 ICLR 流程看研究落地的话外音
ICLR 的审稿流程这几年越来越规范,但也越来越卷。如果你准备投稿相关方向,我有几点从工程视角出发的建议,不算学术方法论,但非常实用。
第一,实验里一定要报告“上下文管理模块本身的成本”。很多论文只报最终任务的成功率,完全不提为了管理上下文额外花了多少 token、多少延迟。审稿人现在很吃这一套,因为你做了一个检索增强或压缩方案,如果收益只有几个点而成本翻了一倍,落地价值就要打问号。
第二,长程 Agent 工作最容易翻车的地方是“baseline 太弱”。你拿一个完全没有记忆管理的模型做对比,证明自己的方案有效,这没有说服力。基本盘至少要包含“原始长上下文直接塞入”“滚动摘要”“朴素向量检索”这三个 baseline,不然审稿人会质疑你的增量。
第三,注意案例的可复现性。ICLR 现在要求代码和配置公开的比例越来越高。我在复现别人论文的时候最头疼的就是“记忆参数不公开”,存什么、索引什么、检索几个、阈值多少,这些不写清楚,论文基本就废了一半。你要是做研究,把这部分细节写透,反而会成为加分项。
4. 实操:为你的长程 Agent 做一套上下文管理配置
4.1 上下文预算清单怎么列
不管用什么方案,动手之前先列一份上下文预算清单。我一般把上下文分成五个部分:系统提示、工具定义、用户输入、运行历史、瞬时输出。前两部分相对固定,用户输入是硬要求,真正能优化的是后两部分。
以一个 128K 窗口的模型为例,我会这样分配:系统提示加工具定义控制在 4K 以内,用户当前输入预留 8K,瞬时输出(比如工具返回的结果)控制在 16K 以内,剩下大约 100K 给历史。历史里再细分:最近 20 轮完整对话占 40K,滚动摘要占 8K,关键实体清单占 2K,其余 50K 留给按需检索注入的记忆。这个预算不是死的,但它逼着你给每个模块设一个边界,而不是“有多少塞多少”。
做完预算清单之后,你还需要一个“超限预案”。我惯用的做法是:当历史超过预算的 80% 时,先触发一次摘要合并,把最老的 20% 历史压成摘要;如果还是超,再触发检索索引刷新;如果仍然超,才考虑截断。预案要写成代码逻辑,不能靠模型临场发挥。
4.2 参数选择的具体计算示例
配置上下文管理不能靠感觉,这里我给一个可复现的计算示例。
假设你用的是 128K 窗口模型,目标是跑一个 100 轮的长对话任务。每轮对话平均消耗 1.2K token,那么 100 轮就是 120K,超出窗口。你设滚动摘要策略,每 5 轮触发一次,将 5 轮原始对话(约 6K)压缩成一段事件摘要(约 0.8K)。那么 100 轮会产生 20 段事件摘要,总计约 16K,再加上保留最近的 5 轮原始对话(6K),总历史占用约 22K,相比 120K 节省了超过 80% 的空间。
检索参数怎么定?假设记忆库里有 500 条历史事件,你不能每次都把 500 条全部注入。我的经验是:初次召回用 30 条候选,经过重排后只注入 Top 5,相似度阈值设为 0.72(基于 embedding 模型的分布实测后调的)。如果 Top 5 里的最高相似度都低于 0.6,那就说明当前问题不适合检索历史,宁可让模型只依靠当前窗口作答,也不要强行塞入可能不相关的记忆。
成本上也要会算。如果完整历史是 120K,压缩后是 22K,而缓存命中率是 70%,那么每次请求的有效输入大概是 22K 加上少量系统 prompt,相比不压缩的 120K,成本大约能降到原来的五分之一到六分之一。这个账算明白之后,你就知道上下文管理不只是“让效果变好”,它同时是“让成本可控”。
4.3 评估指标体系不该只看任务成功率
给长程 Agent 做评估,只盯着任务成功率远远不够。我建议至少拉一套多维度指标,哪怕刚开始粗糙一点,也要把各个模块的贡献拆开看。
我习惯用这样一个表格来评估上下文管理模块:
| 维度 | 指标 | 观察方式 |
|---|---|---|
| 信息覆盖 | 关键约束召回率 | 人工检查摘要和检索结果是否包含必要实体 |
| 事实一致性 | 答案与历史事实矛盾率 | 对比模型输出与原始记录中的明确事实 |
| 上下文效率 | 有效信息密度 | 关键信息 token 数 / 总输入 token 数 |
| 延迟 | 单轮响应时间 | 从提交到返回的端到端耗时 |
| 成本 | 每任务 token 消耗 | 统计输入加输出的总 token 数 |
任务成功率是结果指标,但长程 Agent 失败的原因可能出现在任何一个环节。比如任务失败是因为记忆检索没召回关键信息,还是因为摘要把截止日期丢了,这两种情况在成功率上看起来一样,但修法完全不同。所以我会在每次失败时记录一条“失败归因”日志:是截断、检索、摘要还是模型推理导致的。积累一段时间之后,你就能看出自己的系统到底在哪一环最薄弱,对应的优化也更有针对性。
5. 常见问题与排查技巧实录
5.1 漂移:上下文逐渐偏离主题
长程 Agent 最常遇到的问题就是“漂移”。一开始还在正确轨道上,聊着聊着就跑偏了,而且这种跑偏往往是渐变式的,很难被及时发现。我排查过的一个案例里,Agent 在前半段还严格遵守“只使用内部数据源”的约束,后半段就开始自行上网搜索补充信息,原因是早期对话里的系统约束被后续大量的工具调用记录稀释了,模型渐渐忘了自己最初被赋予的边界。
排查这类问题,我建议加一个“主题对齐检查”步骤。每 N 轮对话后,让模型用一句话总结当前正在做的事,和最初任务目标做一次对比。如果偏差超过预设阈值,就触发一次“回到主线的修正”动作,把最新的目标摘要重新注入上下文。这个检查的成本很低,但能有效止损。
5.2 摘要失真:核心信息被抹掉
摘要模型把关键信息压缩没了,是压缩方案的经典坑。尤其是数字和限定词:“3 个候选方案”被压成“若干候选方案”,“用户明确拒绝方案 B”被压成“讨论了方案 B”。这种失真在单层摘要里几乎无法避免。
我的对策有两个。第一,摘要 prompt 里强制要求保留所有数字、专有名词、否决性结论,这些是最容易被压缩模型忽略却对下游最重要的信息类型。第二,给摘要条目加“指针”。也就是说,每段摘要后面附带对应原始记录的 ID 范围,当模型需要知道更细的细节时,可以通过指针回查原文。摘要不是替代原文,而是索引,这个思路非常关键。
5.3 检索噪声:把无关记忆拉回来
检索模块比想象中更容易“召回一些看起来相关、实际无关”的内容。比如用户这次问“帮我整理一下上周的项目进度”,向量检索很可能把一个月前跟这个项目相关但状态已经完全变化的旧记录拉回来,模型如果不懂区分,就会把旧状态当成当前状态。
我给检索模块加了两层过滤:第一层是时间窗口过滤,除非查询里明确提到“历史”或“之前”,否则默认只检索最近 N 天内的记录;第二层是状态过滤,记忆条目里如果包含“已完成”“已废弃”这类终结状态标签,检索命中的时候要额外提醒模型“这是过期信息”。这两层过滤之后,检索噪声引发的错误大幅下降。
5.4 成本失控:上下文越长越贵
如果只追求效果不管成本,长程 Agent 很容易变成一个烧钱机器。我见过最夸张的案例是某团队跑一个长文档分析任务,单次任务的输入 token 接近百万,成本高到完全无法产品化。成本失控背后往往是没有预算控制,也没有缓存复用。
解决办法是把预算控制写进代码而不是交给模型自觉。每次调用前算出当前上下文的 token 数,超过预算就走压缩和降级流程。同时,我强烈建议把成本监控做成可视化曲线,按“每轮对话成本”和“每个任务总成本”两个维度看。当你看到成本曲线在某个轮次突然跳升,大概率是某次检索注入的记忆太多,这时候就需要限制检索条数或加大相似度阈值。
结尾
长程 Agent 的上下文管理,做了这么久,我最深的体会是:它不是一个大一统的技术方案能解决的问题,而是要在“理解任务特征、拆解失败原因、组合管理手段”这个循环里不断调优的过程。我见过有人花大价钱买了超长窗口模型,结果任务成功率没涨多少;也见过有人用一个简单的滚动摘要加检索组合,把 100 轮任务的成本压到原来的四分之一,成功率反而提升了十几个点。差别不在于工具多高级,而在于是否理解自己的 Agent 到底在哪个环节丢信息。
最后再分享一个小技巧:项目上线初期,给你的记忆读写模块加上详细日志,记录每一次压缩、检索、缓存命中和失败。这些日志看起来不起眼,但当你排查“模型怎么突然答错了”的时候,它们就是唯一的破案线索。多数时候,问题不是模型变笨了,而是你的上下文管理策略在一处不起眼的细节上崩溃了。把这些细节看住,长程 Agent 才能真正担得起“长程”这两个字。