别再往提示词里塞原始数据:AI Agent上下文膨胀的真正解法

大多数「上下文窗口问题」其实是状态管理问题,把原始工具输出留在模型外即可解决。
文章指出,许多 Agent 表现变差并非模型能力问题,而是把聊天记录当成数据库、反复回放原始工具输出所致。作者主张将完整工具结果存储在模型之外的结构化状态中,仅向提示词传递简短摘要、下一步所需字段或验证用的精确切片。LangGraph、n8n 和 MCP 已分别通过检查点状态、记忆裁剪和工具 schema 提供了实现路径。文章同时澄清提示词缓存只对稳定前缀有效,无法弥补糟糕的上下文卫生,反而可能掩盖架构缺陷。核心规则是:用于推理的信息做摘要,用于检索的信息做存储,用于验证的信息传精确切片。
几个月前,我目睹了一个Agent做出令人匪夷所思的操作。它已经获取了数据,已经解析了数据,已经把有用的字段存好了。然后它还是把整个原始工具响应,原封不动地粘进了下一次模型调用里。
完整的JSON块、日志、元数据、无用字段,一样不落。下一步变慢了,再下一步更贵了。接着模型开始犯那种让人恼火的毛病:只回答任务里简单的部分,悄悄忽略重要的部分。
那一刻Bug变得很明显:大多数所谓的"上下文窗口问题",根本就不是模型问题,而是状态管理问题。一旦你意识到这一点,就会在n8n流程、LangGraph Agent、MCP工具循环以及各种自定义的OpenAI兼容编排代码里,到处看到同样的错误。

问题根源:把聊天记录当数据库用
很多人把两个概念混为一谈:模型"能"容纳长上下文,和模型"应该"接收长上下文。这两件事完全不同。
一个巨大的提示词,本质上只是一个伪装成对话的、管理糟糕的状态存储。即使模型在技术上能接受完整历史,随着陈旧内容的堆积,性能依然会变得模糊。延迟上升,成本上升,注意力被稀释。
这就是为什么长时运行的Agent往往在前5步显得很聪明,到了第20步就开始莫名地不稳定。
核心解法:停止回放原始工具输出
真正的修复方法简单到有点尴尬:把完整结果保存在模型之外的结构化状态里,只发送以下内容之一——一段简短摘要、下一步需要的精确字段,或者当验证很重要时的精确证据切片。
这一个改变对Agent质量的提升,通常比从一个前沿模型换到另一个前沿模型还要大。
三种模式的对比很能说明问题。把原始工具输出塞进提示词,提示词增长最快,干扰最大,延迟和成本每一步都在攀升。把工具结果摘要后放进提示词,通常是较好的平衡,但糟糕的摘要可能隐藏边缘情况。把结构化状态放在提示词之外,是多步骤Agent的最佳默认选择:反复出现的提示词很小,推理更干净,编排更好。
错误示范
下面这种写法直接把整个API响应倒进提示词,如果result包含200行每小時预报数据、提供商元数据、时间戳、调试字段和追踪ID,提示词瞬间变成杂物抽屉。模型不得不去寻找相关字段、忽略无关字段、记住先前步骤、规划下一步行动,还要不被噪音分心。模型能做到,只是效率不高。
正确示范
把完整结果存进应用状态,只传下一步需要的字段。同样的工作流,更小的提示词,更少的干扰,模型更可能聚焦于决策本身,而不是重新解析垃圾数据。
什么该放在哪里
这是我希望能有更多Agent构建者一开始就具备的心智模型:短期对话状态附着在线程上;长期事实和工具结果放在提示词之外的数据库或记忆存储中;下一次模型调用只获取该状态中最小的有用切片。不复杂,只是需要纪律。
实际框架怎么做
LangGraph:检查点状态,而非重放对话
LangGraph在这件事上做对了。它不把之前的工具输出塞回每个提示词,而是持久化图状态,按线程恢复。这才是成熟版本的记忆。模型拿到下一个节点需要的东西,Postgres保留其余部分。
n8n:有意裁剪记忆
n8n在这方面的做法相当务实。如果你在n8n里构建AI工作流,你已经有工具来避免上下文膨胀:Simple Memory、Redis、Postgres、Xata、Zep、Motorhead、Chat Memory Manager。Chat Memory Manager这个节点的存在本身就说明了一切——如果一个工作流平台专门发布一个节点来检查和减少记忆,那么"永远往聊天记录里追加"显然不是最佳模式。
MCP:工具输出首先是应用状态
MCP让这件事更干净,因为工具本身就有结构。工具定义里有inputSchema和outputSchema,这应该引导你采用简单模式:调用工具、存储完整的结构化结果、只把需要的字段传进下一个提示词。提示词变成工作笔记,而不是仓库。
MCP(Model Context Protocol,模型上下文协议)是由 Anthropic 于 2024 年底开源的一套标准协议,旨在统一大语言模型与外部工具、数据源之间的交互方式。在 MCP 出现之前,每个 Agent 框架或应用都需要自行定义工具调用的格式与生命周期,导致工具生态彼此割裂;MCP 则把「工具如何被描述、如何被调用、如何返回结果」抽象成标准接口。其中,工具通过 inputSchema 声明调用方可以传入哪些参数,通过 outputSchema 声明返回结果的结构。这种显式 schema 的意义不只是类型校验:它天然地告诉调用方「哪些字段是结构化的、可被单独取用的」,从而让「把完整结果存进状态、只挑出下一步需要的字段」变成顺理成章的操作,而不是靠开发者手动从一坨文本里抠数据。
理解「持久化状态」与「对话历史」的区别,是理解这一节的钥匙。对话历史是一串按时间顺序追加的消息,模型每次都要从头读到尾;而持久化状态是一个结构化的键值容器,允许按需读取、更新、删除任意字段。LangGraph 的 checkpointer 属于后者:每个线程(thread)对应一份可恢复的图状态快照,节点执行时只读取自己关心的字段,不需要把过往所有消息重新喂给模型。n8n 的各类 Memory 节点(如 Chat Memory Manager)也提供类似能力,允许在工作流中主动裁剪、总结或替换记忆。MCP 则把工具结果本身定义为结构化对象,天然适合作为状态的一部分。三者的共同思路是:状态是事实的存放地,提示词只是「本步推理所需的最小视图」。
提示词缓存救不了糟糕的上下文卫生
这一点经常被误解。Anthropic的提示词缓存(prompt caching)在重复使用相同稳定前缀时很有用,比如系统指令、工具定义、固定文档、重复的脚手架。但它不能神奇地让一个草率的提示词变好。
Claude缓存只在前缀完全相同时生效,缓存条目默认只持续5分钟。这对重复前缀很好,但它不会让一个巨大的原始工具转储变得更相关。如果有影响的话,缓存反而会在一段时间内掩盖糟糕的架构,因为账单没那么疼了,质量问题还没暴露出来。
用缓存来优化稳定前缀。不要用它当作继续往提示词里塞垃圾的借口。
提示词缓存(Prompt Caching)的核心机制是「前缀匹配」:服务端会把提示词从头开始的一段稳定内容缓存起来,下次请求如果前缀逐字节相同,就能跳过这部分的重算,从而降低延迟和成本。Anthropic 的缓存默认有效期为 5 分钟,每次命中会刷新计时;它要求前缀完全一致,任何改动都会导致缓存失效。这意味着缓存最适合的场景是「很长且几乎不变的前缀」,比如系统提示、工具定义、固定参考文档。但它对「中段或后段不断膨胀的内容」无能为力——原始工具输出往往出现在对话中后部,且每次不同,根本无法命中缓存。更微妙的是,缓存会降低那些本可避免的冗余前缀的账单成本,让开发者暂时感受不到疼痛,从而推迟了对上下文架构的真正修复。
重构前后对比
在一个普通Agent循环里,之前的写法是这样的:搜索文档和CRM数据直接以完整内容格式化进提示词。一开始能跑,然后search_results变大,crm_data变大,每一步都拖着更多包袱。
重构之后,完整的搜索结果和CRM数据存进state,提示词只包含用户请求、前三个文档标题、客户等级、未结工单数和账单状态。这个版本更不容易出错。当模型之后需要精确证据时,可以选择性地把原始状态拉回来。
什么时候该保留原始输出
确实存在真正的例外。有时候下一步确实需要精确的源材料。当你需要法律或合规引用、调试用的精确堆栈跟踪、完整diff的代码审查、从混乱文本中提取、对照原始证据验证时,应该把原始输出保留在上下文里。
但即使在这些情况下,也只传重要的精确切片,而不是整个上游宇宙。
我现在使用的规则
这个启发式方法清理了我的大部分Agent工作流:如果信息用于推理,就摘要它;如果信息用于检索,就存储它;如果信息用于验证,就传精确切片。
这个规则为我节省的延迟、成本和Agent质量,比换模型带来的提升还要多。
按Token付费时,这件事更关键
这个问题在生产环境里会迅速变得昂贵。如果你的Agent在n8n、Make、Zapier或自定义循环里24/7运行,每一个反复回放的额外数据块都会变成持续成本。这也是很多团队最终痴迷于Token使用仪表盘,而不是修复架构的原因之一。
更干净的状态设计从源头减少提示词膨胀。如果你使用的是OpenAI兼容端点加固定月费定价,这一点会更好,因为你可以针对Agent质量和吞吐量做优化,而不是不断担心多一次工具调用会不会让账单飙升。
作者特别提到了Standard Compute,它可以作为OpenAI API的即插即用替代品,让你保留现有SDK和Agent代码,同时不再以"按Token恐慌"的模式思考。架构修复仍然重要,只是你可以在没有Token焦虑的情况下实施它。
实用检查清单
如果你的Agent随着时间推移感觉更慢更笨,先检查这些:你是否把原始工具输出粘进了每一个后续提示词?你是否把规范结果存在模型之外?你是否在下一次推理步骤之前摘要工具结果?你是否只在需要验证时传递精确证据?你是否只对稳定前缀使用提示词缓存?你是否在n8n或编排层裁剪记忆?你是否把模型当作推理引擎而不是数据库?
只要修复这些,你获得的提升很可能比再做一次模型对比测试更大。
我原本在寻找一个模型层面的修复方案,最终找到的却是一个架构层面的修复方案。大多数"上下文窗口问题",其实只是我们把聊天历史当成了存储层。一旦你不再把原始工具输出塞回下一个提示词,Agent就会变得更快、更便宜,而且明显更少困惑。不是因为模型变了,而是因为我们终于不再让它们背负我们的状态管理错误。
相关推荐

零成本搭建AI超级员工系统:智能体自动工作流全解析
深度拆解B站演示的AI超级员工系统:Agent智能体编排、数字人口播、地图与企业获客、24小时智能客服及法务模块全覆盖。分析零成本开户背后的商业逻辑与合规风险,帮助创业者判断这套AI数字员工系统的真实投产比。

Chatbot与AI Agent的本质区别:从对话到执行的跨越
Chatbot和AI Agent有什么区别?本文基于Learn Tech频道的MCP系列讲解,用订机票、笔记摘要等实例说明:Chatbot只给答案,Agent通过思考-行动-观察循环真正完成任务,并拆解模型、工具、记忆、目标四大部件及MCP的桥梁作用,同时讨论Agent的适用边界与权限风险。

免费GitHub仓库:342小时AI课程,从数学到MCP服务器
一个免费GitHub仓库提供342小时AI课程,包含523节课、20个阶段,覆盖数学基础到Agent构建和MCP服务器。支持目标驱动学习,每节课产出可留存的prompt、skill或agent,已有近10万人开始学习。