1. 长程 Agent 上下文管理为什么成了顶会硬骨头如果你最近在跟 Agent 相关的项目大概率会有一种感觉模型能力本身已经不是最卡脖子的环节了真正让人头疼的是长程任务里上下文怎么管。一个 Agent 跑三步五步没问题一旦任务链条拉到几十步甚至上百步上下文窗口就开始爆炸——要么塞不下要么塞下了模型也抓不住重点要么成本高到离谱。ICLR、ICML 这类顶会近两年关于 Agent 的投稿里上下文管理几乎是绕不开的核心议题2026 这一届更是集中爆发了一批系统性工作。先把概念说清楚。所谓长程 Agent 上下文管理指的是 Agent 在执行一个跨越很多步骤、涉及很多工具调用和中间状态的任务时如何组织、压缩、检索、丢弃和复用上下文信息的一整套机制。它跟单纯的“长上下文模型”不是一回事。长上下文模型解决的是“窗口能装多少 token”而上下文管理解决的是“装什么、怎么装、什么时候换掉”。你可以把它类比成一个人的工作台桌面再大如果不会整理照样找不到东西桌面小一点但收纳有序反而效率更高。这套东西为什么重要因为 Agent 的本质是在循环中做决策。每一步它都要读历史、看当前状态、决定下一步动作。历史越长决策的信噪比就越低。我见过太多项目模型换了一版又一版效果提升却卡在某个瓶颈上最后发现问题根本不在模型而在上下文里塞了一堆无关的中间结果把关键信号淹没了。ICLR、ICML 2026 上那些被反复讨论的工作本质上都在回答同一个问题如何让 Agent 在长程任务中保持“记得住关键、忘得掉噪音”。这篇文章我打算把这条线捋清楚。从整体设计思路到核心机制拆解再到可落地的实操方案和踩坑记录尽量讲透。适合正在做 Agent 开发、被上下文问题折磨过的同学也适合想系统了解这个方向研究脉络的人。不管你是刚入门还是在调优阶段应该都能拿到能直接用的东西。2. 长程上下文管理的整体设计思路拆解2.1 从“塞满窗口”到“分层记忆”的范式转变早期做 Agent 的人有个朴素想法既然模型上下文窗口越来越大那就把所有历史都塞进去不就行了。这个思路在短任务里能跑通但长程任务里很快撞墙。原因有三层。第一层是成本token 是要花钱的每一步都把全部历史重新喂一遍成本随步数线性甚至超线性增长。第二层是注意力稀释就算窗口装得下模型对长上下文的注意力分布是不均匀的中间部分容易被忽略这就是常说的“lost in the middle”。第三层是状态污染历史里包含大量已经过时、已被推翻的中间结论模型分不清哪些还有效容易基于旧信息做错误决策。所以顶会里主流的设计思路已经从“塞满窗口”转向分层记忆架构。典型做法是把上下文拆成几个层次工作记忆当前步骤直接相关的少量信息、短期记忆最近若干步的摘要、长期记忆跨任务沉淀的知识或事实、以及外部检索层按需拉取的相关片段。这个分层不是拍脑袋来的它对应的是人类处理长任务的认知模式——你不会记住每一步的所有细节但你会记住结论、记住关键约束、记住还没解决的问题。分层带来的直接好处是每一层可以用不同的策略管理。工作记忆要求高保真、低延迟那就原样保留短期记忆可以压缩成摘要长期记忆可以向量化存起来按需检索。这种“分而治之”的思路是 ICLR、ICML 2026 上很多工作的共同底色。你在设计自己的 Agent 时第一步就该问自己我的上下文里哪些是必须逐字保留的哪些是可以摘要的哪些是可以丢到外部存储按需取的。把这个问题想清楚架构就成型了一半。2.2 压缩、检索、遗忘三条技术路线的取舍具体到实现层面长程上下文管理基本围绕三条技术路线展开压缩、检索、遗忘。这三条路线不是互斥的实际系统里往往是组合使用但每条路线的侧重点和适用场景不同选型时要想清楚。压缩的核心是把冗长的历史信息浓缩成更短的表示。常见手段包括摘要生成、关键信息抽取、状态向量化等。压缩的优点是直接降低 token 占用缺点是会丢信息而且摘要本身可能引入偏差。我个人的经验是压缩适合用在“过程性信息”上——比如工具调用的原始返回你不需要记住返回的每一个字符只需要记住“调用成功了、拿到了什么关键字段”。但涉及精确数值、ID、约束条件这类信息压缩要非常小心最好原样保留。检索的核心是不把所有信息都放在上下文里而是存到外部需要时再拉回来。向量数据库、关键词索引、图结构检索都是常见方案。检索的优点是理论上可以管理无限长的历史缺点是检索质量直接决定效果检索错了比不检索还糟。检索适合用在“事实性、知识性”信息上比如用户之前提过的偏好、项目里定义过的术语。这里有个坑检索的粒度很关键切得太碎会丢上下文切得太粗会引入噪音需要根据任务特点调。遗忘是最容易被忽视但可能最重要的一条路线。主动遗忘不是bug是feature。一个 Agent 如果什么都不忘历史会越来越脏。遗忘策略包括基于时间的衰减、基于相关性的淘汰、基于任务阶段的清理等。比如一个任务阶段结束后这个阶段的中间过程就可以整体丢弃只保留结论。遗忘做得好能让上下文始终保持“干净”这对长程任务的稳定性影响巨大。路线核心手段适用信息类型主要风险压缩摘要、抽取、向量化过程性信息信息丢失、摘要偏差检索向量库、关键词、图事实性、知识性信息检索错误、粒度难调遗忘时间衰减、相关性淘汰过时、阶段性信息误删关键信息2.3 为什么顶会工作都在强调“主动管理”而非“被动承载”把上面这些串起来你会发现一个共同点顶会里被认可的工作几乎都在强调主动管理。什么叫主动就是系统要有一套明确的策略决定每一步该保留什么、压缩什么、丢弃什么、检索什么而不是被动地让上下文自然堆积。被动承载的思路是“模型自己会处理”主动管理的思路是“我来帮模型减负”。这个转变背后有个很实际的考量Agent 的可靠性。被动承载的系统行为随任务长度增加而快速退化你很难预测它在第50步会出什么幺蛾子。主动管理的系统因为每一步的上下文都是被策略筛选过的行为更可控出了问题也更容易定位——你可以检查是压缩策略错了还是检索没召回还是遗忘误删了。这种可调试性在工程上价值极高。我在实际项目里的体会是主动管理带来的最大收益不是效果上限的提升而是下限的抬升。它让 Agent 在长任务里不至于崩得太难看。ICLR、ICML 2026 上那些关于鲁棒性、一致性的讨论很多都指向这一点。所以如果你现在正在设计 Agent 的上下文模块别想着“先跑起来再说”一开始就把主动管理的框架搭好后面会省很多事。3. 核心机制解析与实操要点3.1 工作记忆的保真策略与边界划定工作记忆是整个上下文管理里最不能省的一层因为它直接支撑当前决策。我的做法是给工作记忆划一条硬边界只放当前步骤和最近一到两步直接相关的信息。具体包括当前任务目标、当前步骤的输入、上一步的输出、以及还没解决的约束。超出这个范围的一律不进工作记忆。为什么边界要划这么死因为工作记忆的保真度要求最高它基本是原样保留的token 成本最贵。如果边界模糊工作记忆会迅速膨胀把短期记忆和长期记忆的空间挤掉。我见过一个项目工作记忆里塞了最近十步的完整历史结果每步的 token 消耗是设计值的五倍成本直接失控。实操上工作记忆的维护可以用一个简单的滑动窗口加显式状态对象。滑动窗口保留最近N步的原始记录N一般取2到3显式状态对象则记录那些必须跨步骤保持的信息比如任务目标、已确认的事实、待办事项。状态对象要定期和滑动窗口做同步确保两者不冲突。这里有个细节状态对象的更新要有明确的触发条件不能每步都改否则会引入抖动。我通常设定为“当且仅当出现新的确认事实或任务目标变更时”才更新。注意工作记忆里绝对不要放未经确认的中间推测。推测性内容一旦进入工作记忆很容易被后续步骤当成事实使用这是长程任务里非常隐蔽的错误来源。3.2 短期记忆的摘要生成与信息密度控制短期记忆承接的是“最近一段时间发生了什么”它的核心任务是在保留关键信息的前提下压缩体积。摘要生成是主流手段但摘要怎么做很有讲究。直接让模型“总结一下”往往效果一般因为模型不知道你后面要用什么信息容易总结得过于笼统。我的做法是面向用途的摘要。在生成摘要时明确告诉模型这个摘要将被用于什么场景需要保留哪几类信息。比如“请总结最近五步的操作重点保留调用了哪些工具、每个工具的关键返回字段、是否出现错误、当前进度”。这样生成的摘要信息密度高得多后续步骤用起来也更顺手。摘要的更新频率也需要控制。每步都重新生成摘要成本高且容易累积偏差间隔太长摘要又会过时。我一般设定为每3到5步更新一次或者当累积的原始记录超过某个 token 阈值时触发更新。更新时采用“增量摘要”而非“全量重写”即把新内容合并进旧摘要而不是从头总结所有历史。增量摘要的好处是保留了历史摘要的稳定性避免每次重写带来的信息漂移。信息密度控制还有个技巧用结构化格式代替自然语言。比如把摘要写成“工具X结果成功关键字段YZ”这样的键值对比一段散文式的描述更省 token也更容易被模型准确解析。这个技巧在工具调用密集的 Agent 里效果特别明显。3.3 长期记忆的存储结构与检索触发条件长期记忆解决的是“跨任务、跨会话的知识沉淀”。它的存储结构直接决定了检索质量。常见的方案是向量数据库但纯向量检索有个问题它擅长语义相似不擅长精确匹配。而 Agent 的长期记忆里往往既有需要语义检索的比如“用户之前表达过的偏好”也有需要精确匹配的比如“项目里定义的某个ID”。所以我的建议是混合存储向量索引加结构化字段。每条记忆同时存一份向量表示和一份结构化元数据时间、类型、来源、关联任务等。检索时先用结构化字段做过滤再用向量做排序。这样既能保证精确性又能利用语义相似度。ICLR、ICML 2026 上有工作专门讨论这种混合检索在 Agent 记忆里的应用思路基本一致。检索的触发条件同样关键。不能每步都检索那样成本高且容易引入噪音也不能只在开头检索一次那样后续步骤拿不到新信息。我的做法是事件驱动检索当出现特定事件时才触发比如任务进入新阶段、遇到未见过的问题、需要引用历史信息时。触发条件要写得具体比如“当当前步骤涉及用户偏好判断时检索长期记忆中的偏好类条目”。这种精确触发比无差别检索有效得多。记忆层保真度更新频率存储方式主要用途工作记忆最高每步内存当前决策短期记忆中每3-5步内存/轻量存储近期上下文长期记忆低事件驱动向量库结构化跨任务知识3.4 上下文预算分配与动态调整机制前面讲的都是“怎么管”但还有一个绕不开的问题预算怎么分。上下文窗口是有限的工作记忆、短期记忆、长期记忆检索结果、当前输入这几块都要占地方。如果平均分配往往每块都不够用如果全给一块其他块就废了。我的经验是动态预算。给每一层设一个基准配额然后根据任务阶段动态调整。任务初期工作记忆和当前输入占大头因为要理解任务任务中期短期记忆占比上升因为要维持连贯性任务后期长期记忆检索占比上升因为要复用历史结论。这个调整可以基于简单的规则也可以用一个小模型来预测看你的工程复杂度承受能力。动态调整的触发点可以绑定到任务阶段识别上。比如当 Agent 完成一个子目标时就是一个调整信号。这里要注意预算调整不要太频繁否则上下文结构频繁变化模型反而难以适应。我一般设定为每个子目标完成后调整一次粒度适中。提示预算分配一定要留出余量。我通常预留总窗口的15%到20%作为缓冲用于应对突发的长输入或检索结果过多的情况。没有缓冲的预算分配在长程任务里几乎必然会在某个点崩掉。4. 实操过程与核心环节实现4.1 从零搭建一个分层上下文管理模块光讲原理不够我把一个可落地的分层上下文管理模块的搭建过程拆开讲。假设你用的是主流的 Agent 框架语言是 Python整体结构分四个组件工作记忆管理器、短期记忆管理器、长期记忆管理器、预算调度器。先定义数据结构。工作记忆用一个字典加一个双端队列字典存显式状态队列存最近N步原始记录。短期记忆用一个字符串加一个计数器字符串是当前摘要计数器记录自上次更新以来的步数。长期记忆用向量库加一个元数据表。预算调度器维护各层的当前配额和总缓冲。class WorkingMemory: def __init__(self, window_size3): self.state {} # 显式状态目标、约束、确认事实 self.recent deque(maxlenwindow_size) # 最近N步原始记录 def update_state(self, key, value, confirmedFalse): if confirmed: self.state[key] value def add_step(self, step_record): self.recent.append(step_record)工作记忆的关键在于confirmed参数。只有确认过的信息才进状态字典推测性的只进队列队列满了自动淘汰。这个设计能有效防止推测污染。短期记忆管理器的核心是增量摘要。每次触发更新时把队列里新增的记录和旧摘要一起喂给模型生成新摘要。class ShortTermMemory: def __init__(self, update_interval4): self.summary self.steps_since_update 0 self.update_interval update_interval def maybe_update(self, new_records, llm): self.steps_since_update len(new_records) if self.steps_since_update self.update_interval: prompt f旧摘要{self.summary}\n新增记录{new_records}\n请生成更新后的摘要保留工具调用、关键字段、错误和进度。 self.summary llm.generate(prompt) self.steps_since_update 0长期记忆管理器负责存取。写入时同时存向量和元数据读取时先过滤再排序。class LongTermMemory: def __init__(self, vector_store, metadata_store): self.vector_store vector_store self.metadata_store metadata_store def write(self, content, meta): vec embed(content) self.vector_store.add(vec, content) self.metadata_store.add(meta) def retrieve(self, query, filtersNone, top_k3): vec embed(query) candidates self.vector_store.search(vec, top_k * 3) if filters: candidates [c for c in candidates if match(c.meta, filters)] return candidates[:top_k]预算调度器最简单也最容易被忽视。它维护一个配额表根据任务阶段调整。class BudgetScheduler: def __init__(self, total_budget): self.total total_budget self.buffer int(total_budget * 0.18) self.allocations { working: 0.35, short: 0.25, long: 0.22, } def get_budget(self, layer): return int((self.total - self.buffer) * self.allocations[layer]) def adjust(self, phase): if phase early: self.allocations {working: 0.45, short: 0.20, long: 0.17} elif phase late: self.allocations {working: 0.25, short: 0.25, long: 0.32}这套结构搭起来大概两三百行代码但覆盖了长程上下文管理的核心环节。你可以根据自己项目的复杂度增减但四个组件的职责划分建议保留。4.2 关键参数的计算与调优过程参数调优是实操里最花时间的部分。我拿几个关键参数讲讲怎么算、怎么调。工作记忆窗口大小N。这个参数取决于任务的“决策依赖跨度”也就是当前决策最多需要回溯多少步。你可以做个简单实验在验证集上把N从1调到10看任务成功率的变化。通常N在2到4之间会有一个明显的收益拐点超过之后收益递减甚至为负因为引入了过时信息。我一般从3开始根据拐点微调。短期记忆更新间隔。这个和任务的“信息产生速率”有关。如果每步产生的信息量大致相当间隔可以设为固定值比如4步。如果信息产生不均匀比如某些步骤产生大量工具返回那就改成基于 token 累积量触发。计算方法是设单步平均 token 为T短期记忆的目标容量为C则间隔约为 C/T。C 一般取总预算的25%左右。长期记忆检索的 top_k。这个参数直接影响引入的噪音量。top_k 太大噪音多太小可能漏掉关键信息。我的调法是在验证集上固定其他参数把 top_k 从1调到8观察“检索命中率”和“任务成功率”两条曲线。命中率随 top_k 单调上升但成功率往往在某个点后下降那个下降点就是最优 top_k。经验值通常在2到4之间。缓冲比例。前面提到预留15%到20%这个数字不是随便定的。它应该覆盖“最坏情况下的单步额外开销”。你可以统计验证集里单步 token 消耗的分布取95分位数减去中位数再除以总预算就是缓冲比例的参考值。我实测下来18%左右能覆盖绝大多数情况。调参的顺序建议是先定窗口大小再定更新间隔再定 top_k最后定缓冲。因为前面的参数会影响后面的最优值顺序反了会反复返工。4.3 一次完整长程任务的上下文流转实录我拿一个实际跑过的任务来演示上下文怎么流转。任务是一个多步骤的信息整理任务从若干来源收集信息交叉验证最后生成一份结构化报告。整个任务跑了大概40步。第1到5步任务初期。工作记忆占主导配额45%。这几步主要是理解任务、拆解子目标。工作记忆里存了任务目标、拆解出的子目标列表、以及每个子目标的验收标准。短期记忆还没触发更新长期记忆只在第1步检索了一次拉取相关的历史任务模板。这几步的 token 消耗很低因为输入本身不长。第6到20步任务中期。开始大量调用工具收集信息。工作记忆窗口保持3步状态字典里累积了已确认的事实。短期记忆每4步更新一次摘要里记录了“已从哪些来源收集了哪些字段、哪些字段还缺、哪些来源出现了冲突”。长期记忆在这个阶段被触发了两次一次是遇到一个之前处理过的数据格式检索了历史解析方案一次是发现一个来源的可信度存疑检索了历史可信度评估记录。第21到35步任务后期。进入交叉验证和报告生成阶段。预算调度器把长期记忆配额提到32%因为需要大量复用历史结论。工作记忆配额降到25%因为当前决策更多依赖已沉淀的结论而非原始记录。短期记忆的摘要在这个阶段被反复引用成为报告生成的主要素材。这里有个细节报告生成时我没有让模型直接读所有原始记录而是让它读短期记忆摘要加长期记忆检索结果token 消耗降低了约60%效果反而更好因为摘要已经过滤掉了噪音。第36到40步收尾。清理阶段。工作记忆的状态字典里只保留最终结论队列清空。短期记忆生成最终摘要写入长期记忆作为本次任务的沉淀。整个任务的峰值 token 消耗出现在第20步左右约为总预算的82%没有触及缓冲上限说明预算分配是合理的。这次实录里最关键的一点是上下文流转是有节奏的不是均匀的。初期重理解中期重收集后期重复用收尾重沉淀。你的管理策略要跟着这个节奏走而不是一套参数用到底。5. 常见问题与排查技巧实录5.1 上下文管理高频问题速查表长程 Agent 的上下文问题症状往往很隐蔽排查起来要有章法。我把踩过的坑整理成一张速查表按症状、可能原因、排查方法、解决方向四个维度列出来。症状可能原因排查方法解决方向任务后期突然跑偏工作记忆被过时信息污染打印每步工作记忆内容看是否有已推翻的结论收紧状态字典的确认条件token 消耗异常高短期记忆未及时压缩统计各层 token 占比缩短更新间隔或改增量摘要重复调用同一工具长期记忆检索未命中检查检索触发条件和过滤条件放宽过滤或调整 top_k关键信息丢失遗忘策略误删回溯被删记录看是否含关键字段对关键字段设保护标记摘要越来越笼统增量摘要累积偏差对比摘要与原始记录定期全量重写一次摘要检索引入大量噪音top_k 过大或过滤太松人工检查检索结果相关性收紧过滤、降低 top_k上下文结构频繁变化预算调整过于频繁统计调整次数绑定到子目标完成事件这张表基本覆盖了我遇到过的八成问题。用的时候先对症状再看排查方法最后按解决方向试。大部分问题不需要改架构调参数就能解决。5.2 三个最容易被忽视的隐蔽陷阱除了上面这些显性问题还有几个隐蔽陷阱不踩一次很难意识到。第一个陷阱是“摘要的自我强化”。增量摘要如果一直基于旧摘要生成偏差会累积。比如第一次摘要漏了一个细节后面每次都在漏的基础上更新这个细节就永远丢了。更糟的是模型可能会在摘要里“脑补”出一些原始记录里没有的内容然后后续步骤把它当真。我的应对方法是定期全量重写每更新5到6次增量摘要后强制从原始记录重新生成一次全量摘要把累积偏差清零。这个操作成本略高但值得。第二个陷阱是“检索的时间盲区”。向量检索擅长语义相似但对时间不敏感。如果长期记忆里有一条很旧的信息和一条很新的信息语义相似检索可能把旧的排在前面。而 Agent 任务里新信息往往比旧信息更相关。解决办法是在检索排序里加入时间衰减因子让新信息有加权。具体做法是在相似度分数上乘以一个随时间衰减的系数衰减率根据任务的时间敏感度调。第三个陷阱是“预算的静态假设”。很多人设好预算比例就不动了但任务的实际 token 分布可能和假设差很远。比如你假设工具返回都很短结果某个工具返回了超长文本直接把工作记忆撑爆。我的做法是加一个实时监控每步结束后检查各层实际占用如果某层超过配额的120%就触发一次紧急压缩或淘汰。这个监控逻辑很简单但能避免很多突发崩溃。注意这三个陷阱的共同点是“不会立刻出问题但会在长任务里慢慢累积”。所以排查长程问题时不要只看当前步要往回看几十步的趋势。5.3 从失败案例里总结的排查思路我讲一个真实的失败案例。一个跑了60步的任务在第45步左右开始出现重复劳动——Agent 反复调用同一个工具拿到的结果也一样但就是不停。排查过程分三步。第一步看工作记忆。发现状态字典里有一条“待确认X字段的值”但队列里最近几步明明已经拿到了X字段的值。问题定位到状态字典没有及时更新。原因是X字段的值是通过工具返回的而我的更新逻辑只处理了模型显式确认的情况没处理工具返回的隐式确认。第二步看短期记忆。摘要里确实记录了“已获取X字段”但摘要更新间隔是4步而问题出现在更新之前。也就是说摘要还没来得及反映这个信息工作记忆又没更新Agent 就“不知道”自己已经拿到了。第三步看检索。长期记忆里没有相关记录因为这是本次任务的新信息还没沉淀。根因清楚了信息确认的路径有两条模型显式确认、工具隐式确认但更新逻辑只覆盖了一条。修复方法是把工具返回的关键字段也纳入状态字典的更新触发条件。修复后重跑问题消失。这个案例的教训是上下文管理的更新逻辑要覆盖所有信息进入系统的路径不能只考虑最明显的那条。排查时按“工作记忆→短期记忆→长期记忆”的顺序看基本能定位到问题在哪一层。5.4 性能与成本的平衡技巧最后聊聊成本和性能的平衡。长程 Agent 的上下文管理本质上是在“效果”和“成本”之间找平衡点。几个实用的技巧。分层用不同模型。工作记忆的维护需要高保真可以用强模型短期记忆的摘要生成可以用中等模型长期记忆的检索排序甚至可以用小模型或纯规则。这样整体成本能降不少效果损失有限。我实测下来摘要生成换成中等模型效果差异在可接受范围内成本降了约40%。缓存高频检索结果。长期记忆里有些条目会被反复检索比如任务模板、常用术语定义。把这些缓存起来避免每次都走向量检索。缓存的有效期可以设为任务级别任务结束就清。按需启用长期记忆。不是所有任务都需要长期记忆。短任务、独立任务完全可以关掉长期记忆层省下检索开销。判断标准是任务是否需要复用跨任务知识。不需要就关掉。监控 token 效率。定义一个指标任务成功率除以总 token 消耗。定期看这个指标的变化如果下降说明上下文管理效率在退化需要调优。这个指标比单纯看成功率或成本更有指导意义。我个人在实际操作中的体会是上下文管理的调优是个持续过程没有一劳永逸的参数。任务类型变了、模型换了、工具集改了最优参数都可能变。所以与其追求一套完美参数不如把监控和调优的机制搭好让它能跟着变化自动调整。这套机制搭起来之后你会发现长程 Agent 的稳定性上了一个台阶很多之前莫名其妙的问题都不再出现了。