Agent 的上下文怎么管:塞满了反而变笨
数据截至 2026-07,规范与各项目能力以官方文档当前版本为准。
上下文不是越满越好。窗口能装下,不等于模型能用好——真正决定 Agent 表现的,是每一轮送进去的内容里有多大比例跟当前这一步的决策直接相关。把无关的东西塞进去,代价不只是多花钱,而是模型的判断质量会实打实地下滑。
常见的误解是把上下文管理理解成”省钱”:因为 token 要按量计费,所以能少发就少发。这个理解不算错,但它把因果搞反了。真正棘手的不是账单,而是一个已经跑了二十几轮的 Agent,突然开始重复调用刚调过的工具、拿着一份三轮之前就被推翻的结论继续往下推、或者干脆忘了用户最初要它做什么。这些症状看起来像”模型不行”,实际上大多是上下文组织的问题。省下来的钱只是顺带的结果。
一、先看清窗口里到底装了几类东西
调试之前得先知道自己在调试什么。一个典型 Agent 每轮请求送出去的内容,大致可以拆成四类,它们的裁剪逻辑完全不同:
- 系统提示与角色设定:相对固定,每轮都要带,但内容往往写得过长——很多人把用不上的规则、示例、边界情况全堆在这里。
- 工具定义:每个工具的名字、描述、参数 schema 都要序列化进上下文。工具挂得越多,这块占的比例越吓人,而且它是每轮重复付费的。
- 对话与执行历史:用户的原始请求、模型的每一次思考、每一次工具调用、每一次工具返回。这是增长最快的一块,而且是唯一会无限膨胀的一块。
- 检索与外部注入的内容:向量库召回的文档片段、数据库查询结果、网页抓取的正文。这块的特点是单条体积大,且相关性参差不齐。
先花十分钟把这四块各自占多少 token 打印出来,再决定动哪一刀。凭感觉优化几乎必然优化错地方——多数人以为问题出在历史太长,实测下来往往是工具定义和检索片段先把窗口撑爆的。关于上下文这个概念本身,可以先看 什么是上下文工程 Context Engineering? 打个底。
二、“塞满了变笨”具体是怎么发生的
把这件事说成玄学没什么帮助,拆开看其实是几个很具体的机制在起作用:
注意力被稀释。 模型对长输入里各个位置的利用并不均匀,夹在中段的信息比开头结尾更容易被忽略。窗口填得越满,关键指令被淹没在中间的概率越高。你在系统提示里写死的约束,可能就败给了后面三千个 token 的日志。
过期信息不会自动消失。 第三轮工具返回了一个报错,第五轮你换了参数已经成功了,但第三轮那条报错还老老实实躺在历史里。模型没有办法知道哪条已经作废,它看到的是两条互相矛盾的证据,然后自己挑一条信。Agent 反复重试同一个失败操作,很多时候就是这么来的。
工具太多导致选择困难。 挂十几个功能相近的工具,描述又写得含糊,模型选错的概率显著上升。这跟人一样,选项越多越容易挑错,尤其是选项之间边界不清的时候。
目标漂移。 长任务跑到后半段,最初的用户需求已经被埋在几十轮交互的最底下,模型开始围绕最近几轮的局部问题打转,忘了整件事是为了什么。
认清这四条的价值在于:它们对应四种完全不同的修法,不能指望一招通吃。
三、第一刀砍在工具定义上
这是性价比最高的一刀,因为它每轮都在重复计费,而且减下去几乎没有副作用。
按阶段挂载工具,而不是全程全挂。 一个”调研—写作—校对”的流程,写作阶段根本用不到搜索工具,校对阶段用不到写文件工具。把工具集合做成随状态变化的,每一步只暴露这一步可能用到的那几个,既省 token 又降低选错概率。
合并语义重合的工具。 search_docs 和 search_faq 如果底层是同一个检索服务,就合成一个带 source 参数的工具。工具数量下降带来的判断质量提升,通常比多留一个专用工具的收益大。
参数 schema 别贪多。 把十几个可选参数全暴露给模型,它大概率只用得上两三个,剩下的全是纯开销。用不到的参数在服务端设默认值就行。
工具描述写清楚”什么时候不该用它”。 一句”仅在用户明确要求最新数据时调用”,比三行功能描述更能减少误调用。
四、历史消息的三种裁法,各有代价
历史是唯一会无限增长的部分,必须有明确的处置策略。常见的有三种,没有哪种全面占优:
滚动窗口(只保留最近 N 轮)。 实现最简单,代价是早期信息硬性丢失。适合上下文依赖不强的任务,比如逐条处理独立工单。用在需要回溯的任务上会很难受。
滚动摘要(老的部分压成摘要,新的保留原文)。 能保住主线,代价是摘要本身要额外调用一次模型,且必然有损——被摘掉的细节找不回来了。实践中的关键是想清楚”摘要里必须保留什么”:通常是用户的原始目标、已经确认为事实的结论、已经排除的方向。把这三样写进摘要提示里,比让模型自由发挥靠谱得多。
结构化状态(把结果从对话里抽出来,单独维护一份状态对象)。 不再让模型从对话历史里”回忆”进展,而是每轮把一份结构化的当前状态渲染进提示。这是最工程化、也最稳的做法,代价是要为每类任务设计状态结构,前期投入大。第三方对比里提到 LangGraph 的做法就是让带类型的状态在图的节点之间传递,控制粒度更细;具体能力以项目官方文档当前版本为准。
选哪种取决于任务长度和回溯需求。一个可行的组合是:短任务用滚动窗口,长任务用结构化状态,摘要只作为状态之外的补充说明。Agent 记忆的整体思路可以参考 AI Agent 的记忆是怎么实现的?短期与长期记忆。
五、检索结果别直接倒进上下文
RAG 和 Agent 结合的时候,最容易出问题的地方是:召回十条,十条全塞进去,指望模型自己分辨哪条有用。
更稳的做法有几个方向。先过一道相关性筛选,把明显跑题的丢掉,宁可少给几条也别凑数量。只送片段不送全文,一份长文档里真正回答问题的往往只有一两段,把整篇塞进去是在用无关内容稀释有关内容。把检索变成工具调用而不是前置注入,让模型自己决定什么时候需要查、查什么,查回来的内容用完可以从后续轮次里移除。这也是 Agentic RAG 是什么 讨论的思路。
还有一条容易被忽略:给注入的内容标注来源和时间。模型分不清哪条新哪条旧,标注之后至少它有依据做取舍,你排查问题时也能看出它是被哪条误导的。
六、把状态挪到窗口外面去
上下文窗口不该被当成数据库用。一旦任务要跑几十轮甚至几小时,正确的架构是让窗口只承载”这一步需要看到的东西”,其余全部放在外部存储里,需要时再取。
具体来说:中间产物写文件或写数据库,上下文里只留一个路径或 ID;执行进度存成检查点,恢复时从检查点重建而不是重放全部历史;长期知识放进检索层,用的时候按需捞。
这么做还有个附带好处:状态一旦落到窗口外面,断点续跑就变得可行了。第三方对比提到 LangGraph 提供了 checkpointing、streaming 和 human-in-the-loop 这几个原语,支持持久化的长时运行工作流;这块的具体接口以项目官方文档当前版本为准。展开可以看 长时运行的 Agent 怎么做断点续跑。
七、多智能体不是上下文的万能解药
一个常见的期待是:既然单个 Agent 上下文会爆,那拆成多个 Agent,每个只管自己那摊事,问题不就解决了?
部分成立。职责拆开之后,每个 Agent 的上下文确实更聚焦。但多智能体会引入新的开销——Agent 之间要传递信息,传递的内容本身又要占上下文,编排层还要维护全局状态。第三方实测对比给出的 token 效率排序是 LangGraph 最好、AutoGen 开销最大;这是第三方口径,不同任务上的实际结果会有出入,建议在自己的场景里实测。这笔账怎么算,Agent 框架的 token 开销差多少 里有更细的拆解。
选型上还有两件事值得先知道。一是有实践者反馈微软已把重心转向更大的 Agent Framework,AutoGen 的主要新功能开发停了下来,仍有 bug 修复和安全补丁——存量项目不必急着迁移,但新项目起步前值得把这个情况纳入考量。二是 CrewAI 在 2025 年加入了 Flows 这种事件驱动的 pipeline 模式,面向更可预测的生产负载,不少较早的对比文章没有覆盖到,别照搬旧结论。以上均为第三方口径,各框架的当前能力以官方文档为准。
还有一条更该前置的提醒:如果你的 Agent 只调一两个工具,多智能体框架很可能是过度设计。有观点认为这种情况下直接用 OpenAI Agents SDK 或 Anthropic Claude Agent SDK 是更快的路径。上下文管理的问题,优先从裁剪和外部化下手,架构复杂度是最后才该加的。相关权衡见 Agent SDK 和多智能体框架怎么选。
八、先量出来,再动手改
优化上下文最忌讳凭感觉。几个可以立刻做的动作:
把每轮请求的 token 构成按前面说的四类分别统计并打印出来,跑几十轮之后画个曲线,看哪一块增长最快。在任务失败的那一轮把完整输入 dump 下来,人工读一遍——很多时候一眼就能看出模型是被哪条过期信息带偏的。做改动时一次只动一个变量,改完用同一批任务重跑对比,否则分不清是哪一处起了作用。
诚实地说一下局限。第一,上述做法能明显改善长任务的稳定性,但改不好一个本身就没想清楚的任务拆解——上下文再干净,目标含糊照样跑偏。第二,摘要和裁剪都是有损的,一定存在”裁掉了本来有用的东西”的情况,只能靠回归用例去兜。第三,各框架的能力和默认行为一直在变,本文引用的对比结论来自第三方实测,不同版本、不同任务上未必复现,最终以你自己的实测和各项目官方文档为准。
小结
上下文管理的核心不是压缩,而是让每一轮送进模型的内容尽量只包含这一步需要的东西。动手顺序建议是:先把窗口构成量出来,再砍工具定义,再定历史裁剪策略,最后才考虑把状态外部化。检索结果要过筛选、标来源,不要整篇倒进去。多智能体能让单个 Agent 更聚焦,但会带来通信和编排的额外开销,不是所有场景都划算,工具很少时甚至不需要框架。所有涉及具体框架能力的判断,都建议在自己的任务上跑一遍再下结论。