
1. 上下文工程是什么为什么突然成了Agent开发的命门前阵子我和几个做Agent应用的朋友聊天发现大家都在同一个坑里打转代码写得挺漂亮工具调用也接得挺顺但一跑复杂任务就开始“精神错乱”——对话稍长就忘记最开始的要求资料一多就开始编造答案多步推理动不动就断片。后来排查了一圈问题几乎都出在同一个地方上下文。上下文工程说白了就是管理“你给大模型看了什么、以什么顺序看、以什么形式看”。这句话听起来稀松平常但实际做起来它是Agent类应用能不能从“Demo”走向“能用”的分水岭。我见过太多团队把精力全扑在提示词技巧上今天学一个“CoT”明天抄一个“Few-shot模板”结果换个场景就失灵。原因很简单在真正的Agent系统里模型不仅要理解你的指令还要在动态变化、持续增长的信息流里保持稳定发挥。这个信息流——用户输入、历史记录、工具返回结果、外部检索资料、系统预设规则——你不知道怎么调度编排提示词写得再花哨也没用。上下文工程就是解决这一层的学科它管的是“信息怎么进、怎么存、怎么取、怎么排”让模型始终在最优的信息环境里做决策。这篇文章我准备从底层失效原因一路拆到可落地的解决方案最后给出一套可以直接抄走的配置框架。不管你是刚开始接触Agent开发还是已经被上下文问题折磨了一阵子这篇文章应该都能给你省下不少试错时间。适合谁来读呢三类人正在做Agent应用、RAG系统、智能客服、AI编程助手这类产品的开发者负责大模型应用调优的算法工程师或技术负责人以及那些“提示词写了不少但效果就是不稳定”的实践者。2. 上下文失效的四大典型症状你对号入座了没有先说症状再说病因。因为很多团队其实已经遇到了上下文失效的问题只是没意识到这是个系统性问题还以为是自己选的模型不够聪明。2.1 多轮对话越长模型越“健忘”最典型的现象用户和Agent聊到第十几轮的时候Agent开始重复问已经问过的问题或者不再遵守第一轮对话里交代的约束条件。比如你做了一个数据分析Agent开场告诉它“所有结论必须附数据来源”前几轮它能记住聊到后面它就开始干巴巴地甩结论完全忘了还有这个要求。2.2 检索内容一多模型反而“答非所问”这是RAG系统最常见的翻车现场知识库召回了一堆相关文档你兴冲冲地把Top-20条全部塞进上下文结果模型输出质量急转直下——不仅没有综合多个来源的信息反而被某一段不相关的细节带偏了。甚至在信息互相矛盾的文档面前它不知道听谁的最后给出一个“融会贯通”的幻觉答案。2.3 复杂任务多步推理模型“走一步丢一步”让Agent执行一个五步任务先查库存、再算成本、然后比价、接着生成采购单、最后发审批通知。它第二步做得好好的到第三步可能就忘了“我在做什么”莫名其妙开始生成最终报告。2.4 幻觉率居高不下模型开始“一本正经地胡说八道”这个问题最隐蔽。模型在信息不足或者信息过载的时候都会倾向于“补全”自己不知道的部分。上下文里没写清楚的知识空白、有歧义的定义、缺失的前置约束都会成为幻觉的温床。如果你见过上面任何一种情况恭喜你你已经正式进入上下文工程的深水区了。3. 失效根因拆解为什么模型“记住了”却又“忘了”要解决问题不能停留在“症状”层面。我尽量用大白话把底层机制讲清楚——不需要你懂Transformer的全部细节但至少要知道它为什么会有这些毛病。3.1 注意力机制的信息稀释效应大模型在处理文本时核心机制是“注意力”——它会计算当前要生成的内容和之前看到的所有内容之间的相关性权重。问题在于当输入内容越来越长注意力权重会被“摊薄”。打个比方你让一个实习生同时盯住50块屏幕每块屏幕上都有信息还告诉他“第三块屏幕上的内容最重要”。刚开始他还知道多看第三块时间一长眼睛一花注意力自然被其他屏幕吸引走了。模型是一样的它在长上下文里会“分心”关键信息虽然还在上下文窗口里但它已经不“关注”了。3.2 位置偏差开头和结尾的内容更容易被“记住”实验和工程实践都验证过一个现象模型对上下文开头和结尾的内容更敏感中间的内容容易被“糊弄过去”。这个现象和人类阅读习惯还挺像——你记一篇文章往往是开头和结尾记得最清楚中间细节模模糊糊。这意味着什么如果你的系统指令写在上下文最前面但用户的历史消息不断地“插入”在中间随着对话增长你的核心指令实际上被越挤越“靠后”效果自然越来越差。3.3 信息冗余带来的“信号淹没”人在嘈杂的房间里听不清别人说话模型也一样。上下文里塞了太多低价值信息真正重要的信号就会被淹没。RAG场景尤其严重——你塞进去的检索结果可能有一半是“相关但不是关键”的模型需要花费大量计算去筛选和判断判断错了输出就跑偏。3.4 窗口截断式遗忘很多工程团队其实忽略了最基础的一点上下文窗口是有上限的。当一个超长对话超过了模型支持的窗口限制比较粗暴的处理方式就是“掐头去尾”——丢掉的往往是时间最早的对话也就是最初的系统设定和用户的核心需求。这就好比你让一个人记住一段长篇对话但只给他一张小纸条他只能记住最后几句话。前面交代的事情不存在的。3.5 指令服从的“边际递减”还有一个很微妙的现象模型对指令的服从度会随着指令在上下文中出现的频次和密度变化。如果你在系统指令里一口气列了50条规则模型能真正执行的可能只有前10条后面的全部“免疫”了。这和人的注意力资源有限是同一个道理。了解了这些根因之后你会发现一个关键事实上下文工程本质上是“注意力管理”工程。它要解决的问题不是“怎么把更多信息塞进去”而是“怎么让模型有限的处理资源始终聚焦在最关键的信息上”。4. 从根因到对策为什么“加大窗口、加长提示词”救不了你很多团队的天然反应是模型健忘那我换个上下文窗口更大的模型检索效果差那我召回更多文档全塞进去。结果呢花了大价钱问题一个没少。4.1 更大的窗口不等于更好的效果上下文窗口从4K扩大到128K能装下的信息更多了但注意力的稀释效应也更严重了。就像给实习生加了更多屏幕但他一天只有8小时工作时间——屏幕多了每一块屏幕分到的注意力反而更少。实测效果常常是窗口变大之后模型不仅没有更聪明反而更容易被无关信息带偏推理速度也变慢了。4.2 无限的上下文存储不等于无限有效的上下文真正有效的“工作上下文”应该被限制在一个黄金范围内。这个范围取决于模型的注意力容量和任务的复杂度但经验值可以作为参考对于多数Agent任务有效上下文在几K到十几K tokens时效果最好超过这个区间每增加一倍的输入质量下滑和成本上升的速度都很快。4.3 指望“提示词魔法”不如做“信息治理”上下文工程和提示词工程的根本区别在于提示词工程假设“信息都在怎么让模型注意它”上下文工程则认为“信息这么多怎么让该被注意的信息出现在它该在的位置”。这两个思路没有好坏之分但针对Agent这种复杂系统只靠提示词是不够的。你需要的是信息治理思维把上下文当成一个需要持续优化、动态管理的资源池而不是一个“什么都往里装”的垃圾桶。5. 核心对策一上下文分层管理让Agent轻装上阵理解了我上面说的注意力稀释、位置偏差、信号淹没你就能自然推导出第一个核心方案不要把所有信息一股脑塞进同一个上下文里而是把信息分成不同层次按需调度。5.1 上下文的分成结构指令层、工作层、记忆层、知识层我实践下来比较成熟的分层模型是四层层级内容典型token占用更新频率核心作用指令层系统提示词、角色设定、全局约束、输出格式500-2000极少更新让模型始终知道“我是谁、我要做什么、我的底线是什么”工作层当前任务的中间状态、临时变量、最近几步推理结果1000-5000持续更新让模型专注于当前任务记忆层用户偏好、历史关键信息、对话摘要、长期事实1000-3000按需更新让模型“记得”重要信息不受窗口限制知识层外部检索内容、知识库片段、工具返回的参考数据0-8000按需加载提供任务所需的事实依据5.2 指令层的核心地位和“定海神针”设计指令层是所有层里最不能省的。它决定了模型的行为底线。设计时要注意几条一是稳定性。指令层的内容在整段对话里尽量保持不变。如果经常改动模型会产生困惑到底哪条规则算数二是精简。把规则提炼到最低数量避免长篇大论。我的经验是以“必要且充分”为标准逐条审查每条指令凡是“可能有用”的规则一律砍掉只保留“必须有”的规则。规则太多注意力摊薄等于没有规则。三是前置。指令层永远放在上下文的开头位置确保它在模型的注意力“黄金区”内。如果你发现某个系统的指令有效性越来越差第一件事就是检查是不是有别的动态内容插到指令前面去了5.3 工作层的实时更新机制工作层是用来装“当前正在发生什么”的。它的设计要点是“只保留当前步骤需要的信息”。比如一个电商Agent它正在做第三步“计算运费”那工作层就应该只保留当前订单内容、收货地址、商品重量、物流方案选项。至于用户昨天问过什么、上个订单是怎么回事全部不该出现在工作层。实现上通常是在每轮推理前用代码动态构造工作层内容而不是简单地把历史消息全部追加进去。我见过太多团队偷懒直接把最近N轮消息全塞进去最后模型被一堆过期状态干扰进入了“追忆模式”而不是“执行模式”。5.4 记忆层的摘要化与结构化记忆层解决的是Agent的“长期记忆”问题。很多Agent“聊着聊着忘了用户的需求”根子就在记忆层没做好。实践中最可靠的方案是滚动摘要机制每一轮对话结束后利用模型生成当前状态的简短摘要把新摘要和旧摘要合并超过阈值的部分压缩精简每条摘要带着时间戳和关键词方便按需匹配。这样模型永远不需要接触全部历史对话它拿到的是一份不断更新的“会读记录”——既没有原始信息的噪音又能保留关键上下文线索。5.5 知识层的按需加载原则知识层就是RAG检索出来的内容。核心原则就四个字按需加载。每次检索出来的内容必须和当前任务强相关且总量受到严格控制。具体做法我在后面实操篇里展开这里先说结论宁要3条高质量信息不要20条“可能相关”的信息。信息过载和上下文失效之间的正相关性在几乎所有场景下都成立。6. 核心对策二信息密度与优先级把最该让模型看的内容放在最正确的位置分层管理解决了“信息分类存放”的问题接下来要解决的是“每一层里的信息怎么排布”。6.1 上下文中的“黄金位置”开头和结尾前面说过模型对上下文开头和结尾的内容更敏感。做上下文工程要主动利用这个特征把最高优先级的信息放在这两个位置。具体来说上下文的基本排布应该是[系统指令] [当前任务核心指令] [工作层信息] [知识层补充] [对话末尾的即时指令]开头放置的是指令和任务描述结尾放置的是“下一步要干什么”的即时引导。中间区域谨慎使用只放“模型必须看到但不希望它过度聚焦”的背景资料。6.2 用“信息金字塔”给每条内容定权重结构上排好位置还不够每条信息本身的权重也要有区别。我习惯用三层金字塔模型来思考塔尖决策性信息。比如“必须输出JSON格式”“遇到歧义必须追问确认”——这类信息你要确保模型100%执行。塔身支持性信息。比如任务背景、用户偏好、历史摘要——帮助模型理解为什么这么做。塔基参考资料。比如检索文档、工具返回结果——模型用来查证和引用但不希望它过度依赖。在编码层面这三层信息的呈现方式还可以进一步区分。决策性信息用明确的祈使句必要时用格式标记比如XML标签、JSON结构强化存在感支持性信息可以用结构化字段存储参考资料则要以“按需检索”的方式动态取出而不是一次性堆叠。6.3 时效性管理信息会“过期”很多上下文失效问题其实是因为过期信息还赖在上下文里。用户的需求在变系统当前的状态也在变一条一小时前的关键任务可能现在已经无足轻重了。我建议的设计原则是每条信息带上时间戳或优先级标记在每次构造上下文时做一次“新鲜度过滤”与当前任务直接相关的信息保留最新版本删除旧版本对话过程中产生的中间结论保存摘要删除明细用户已经明确“放弃”或“修改”的需求彻底清除防止模型“记错账”。这个机制可以做成一个简单的状态管理器代码逻辑不复杂但对中长期稳定性的改善极大。6.4 格式化输出的另一个隐藏作用很多人觉得“让模型输出JSON”是一种表演性的结构化要求其实它在上下文工程里有一个特别重要的功能它是模型内部推理和外化对话之间的“锚点”。当上下文里遍布“输出JSON格式的思考过程”“把结果解析为结构化数据”这类指令时模型在内部生成内容时也会更倾向于结构化的中间表示这能让它在冗长的信息流中保持逻辑一致性。我在多个场景里实测过加了结构化输出约束之后模型在长对话里的“失忆”率明显降低。7. 核心对策三检索增强与动态提取让Agent学会“按需查资料”检索增强这一节我想重点讲三个落地细节召回策略怎么定、检索结果怎么重写、以及怎么把外部知识“无缝粘贴”进Agent的工作流程。7.1 召回策略别迷信“Top-K越多越全”很多RAG初期的失败不是检索器不好而是“召回后处理”没做对。我的参数经验如下参数常用配置说明Top-K3-8条宁少勿多业务简单时3条就够复杂推理任务最多8条相似度阈值0.55-0.75低于阈值的直接丢弃宁缺毋滥重排序开关开启用重排序模型重新计算相关性效果提升明显摘要合并按需开启多文档答案冲突需要融合时使用这套配置的核心逻辑就一句话先把“可能相关”的信息收窄到“确定相关”再交给模型。你往上下文里塞的每一条低相关文档都是在和你的系统指令抢注意力。7.2 检索结果的“上下文重写”让模型读起来更省力从数据库或知识库检索出来的原始片段通常是“信息不全”的——可能是一段带引用的表格片段也可能是一段上下文不完整的摘要。原样丢给模型它需要自己脑补上下文很容易脑补错。我的做法是在检索之后加一步“上下文重写”用一轮轻量模型调用把检索片段改写为自包含的上下文快照改写要求 1. 补全背景信息让片段无需再看其他资料也能理解 2. 保留关键事实数字、名称、结论必须原样保留 3. 去掉冗余删掉无关铺垫直接给核心结论 4. 标出置信度如果片段中有不确定的推断用“可能”“未确认”标注。 输入片段 [检索到的原始片段] 输出 [重写后的自包含上下文]这一步看起来多花了一次模型调用但它能显著减少模型在最终生成时对检索信息的“二次推断”从而降低幻觉率。在很多场景里这一步带来的收益比换一个更大的模型还要明显。7.3 动态提取工作记忆把长文档变成“当前任务需要的那几个数字”还有一种常见情况Agent需要在很长很长的文档比如几十页的产品手册、技术文档里定位和使用极少量的关键信息。这时候直接塞全文是下策用一次检索提取Top-K条片段效果也一般——因为关键信息可能分布在不同段落里彼此之间还隔着大段无关内容。我推荐的做法是“任务导向的复盘式提取”针对当前任务让模型针对性地从长文档里抽取信息表存入工作层。这个信息表以“任务行动”为驱动只提取“完成任务需要知道的事实”不提取“有趣但无关的细节”。比如任务是把某个新产品的卖点生成营销文案提取的信息表就应该是核心功能点、目标用户、差异化优势、技术参数限制、官方口径的禁忌表述。而不是让模型“看到什么记什么”。8. 实操篇一套可以直接抄走的上下文工程配置方案理论讲不少了这一章我直接给一套框架级的实现思路。每个Agent项目都可以在这个基础上微调适配。8.1 总体工作流先画一下整体流程系统收到用户请求后Agent的执行路径不是“一股脑儿把历史检索指令全塞进提示词然后等待输出”而是分阶段“构造上下文”解析用户意图判断任务类型读取指令层载入系统设定和全局规则加载记忆层检索与该用户/该任务相关的历史摘要准备工作层从状态管理器获取当前任务执行进度和中间结果按需检索知识层根据当前步骤的诉求检索外部信息然后做重写/提取组装上下文按“黄金位置”原则排序模型输出后更新状态管理器生成或刷新摘要进入下一步循环。8.2 上下文组装函数的核心逻辑这里用一个简化示例展示组装逻辑。我只给关键伪代码Pyhton风格方便从头实现时参考def build_context(request, state, memory_store, retrieval_fn): # 1. 指令层固定不变 instruction_layer load_system_instruction() # 2. 工作层只保留当前步骤需要的状态 work_layer state.get_active_variables(steprequest.current_step) # 3. 记忆层按需检索限量返回 memory_layer memory_store.recall( user_idrequest.user_id, max_items3, freshness_hours24 ) # 4. 知识层与当前步骤强相关的检索结果 retrieved retrieval_fn(request.query_for_current_step, top_k4) knowledge_layer rewrite_retrieved(retrieved) # 上下文重写 # 5. 组装指令优先工作其次记忆参考知识最后 context assemble_context( instructioninstruction_layer, workwork_layer, memorymemory_layer, knowledgeknowledge_layer ) return context这个结构的核心优势是每轮推理的上下文大小基本保持稳定不会随对话轮次无限膨胀每类信息的相对位置和占比都被控制模型的注意力被锁定在最关键的信息上。8.3 系统指令的设计模板系统指令层是最难写对的部分。我给出一个“最小可用”模板框架你是[角色]服务于[任务目标]。 核心原则 1. [最重要的行为准则不超过3条] 2. [次级约束不超过5条] 3. [输出格式要求] 当前任务背景工作层会动态更新 [由外部代码填充不作为静态指令] 执行规范 - 遇到信息不足时清楚说明缺口并继续基于已有信息完成能完成的部分 - 不确定的知识明确标注“未确认”不得编造 - 中间推理过程使用结构化的内部表示逐步推进 - 每轮只输出[下一步执行内容]不提前输出最终结论。实际项目里我会额外定义一个“强制项”当上下文长度超过预设阈值时系统要主动触发“摘要压缩”而不是继续追加。这个规则要写在指令层里并配合外部代码实现。否则模型自己是不会主动“遗忘”的它会硬着头皮消费所有输入。8.4 记忆更新策略什么时候写什么时候删记忆层的更新策略我总结为“三写三删”该写入记忆的情况用户明确提出了偏好、禁忌或长期目标任务有了关键进展比如“确认了采购方案”出现了影响后续决策的新事实比如“库存只剩3件”。该删除或修改记忆的情况用户后续消息明确推翻了之前的说法记忆内容已被当前任务步骤消化吸收不再需要独立保留记忆条目已严重过期与当前业务冲突。这套策略要落到代码里可以做成一个简单规则引擎也可以在某些场景里让模型自己决策。我建议初期用手写规则手动控制因为模型的自我记忆管理能力还不够可靠容易“过度保存”导致上下文污染。8.5 上下文质量的量化评估不量化就没法优化。建议每个Agent项目建立一组上下文质量评估指标指标说明目标值上下文占用率每轮输入token / 模型窗口上限建议低于40%指令守约率关键约束在输出中被遵守的比例≥95%信息溯源率关键结论能在知识层找到对应来源的比例≥90%幻觉标注率不确定信息被明确标注的比例≥80%对话轮次有效性超过20轮的对话中任务完成率≥60%给个经验数字在多数场景里上下文工程优化之后模型的指令守约率能从60%-70%提升到95%左右幻觉率能降一个量级。标题里说的“性能提升90%”不是某一个指标提升了90%而是综合算下来可用Agent比例提升了约一个量级这是能达到的。9. 常见问题与排查技巧实录实践里踩过的坑集中在这里说。每个问题我都给了排查思路和根因。9.1 上下文失效排查速查表症状可能根因排查方法解决方案聊了10轮就开始违反指令指令层被历史消息“挤”出注意力黄金区打印每次构造的上下文检查指令位置固化指令层位置禁止动态内容插入前半段检索内容越多、回答越差知识层信息过载不过滤对比Top-K3和Top-K15的效果收紧召回数量加相似度阈值过滤和重排序多步任务中间步骤丢失工作层没有按步骤动态更新查看每步推理时的状态变量是否被正确传递用结构化状态管理器每步只读当前步骤的变量模型出现过期信息导致的错误记忆层没有删除过期条目检查对话中是否有“旧结论”残留在上下文里实现记忆更新时间戳机制过期自动淘汰输出格式不稳定输出格式指令被埋在长文章中间确认格式指令在系统指令里的显眼位置把格式约束放在指令层最前面并用示例强化大量“可能”“吧”等模糊输出知识层信息不完整模型在“脑补”检查检索结果是否自包含、是否缺失关键背景加入检索结果的“上下文重写”步骤9.2 实战排查中的三个原则先说第一个原则看到失效问题先打印上下文再猜原因。90%的上下文问题只需要你把每次请求的完整输入打印出来看一眼立刻就能定位。很多团队不重视这个靠猜浪费大量时间。第二个原则先隔离变量。如果一个Agent项目同时存在失效率高、幻觉多、延迟大三个问题千万不要同时调整三处配置。一次只改一个变量然后用评估集跑一轮对比看效果变了没有。我就是靠这个习惯把很多莫名其妙的“玄学问题”变成“技术问题”的。第三个原则以评估集为准不以个例为准。上下文工程的优化很容易出现“改好了A场景搞坏了B场景”的情况。准备一组覆盖典型场景的评估集每次改动都全量跑一遍避免“修好一个坑又踩了一个坑”。9.3 一些容易掉进去的隐藏坑模型的“上下文窗口不是边长越好”这个前面说过。总结成一句话以任务完成质量为唯一指标窗口够用就好。不要在系统指令里列太多负面清单。“不能做这个不能做那个”写多了模型反而不知道该做什么。可以把负面约束转化为正面指引比如“应该优先给出有据可查的答案”就比“不要编造”好用得多。上下文压缩别只做一次。对话越复杂越需要多轮压缩每完成一个子任务就做一次局部摘要任务切换时做一次全局摘要。单次压缩能撑到的对话长度很有限。以“成本换效果”不总划算。多塞信息、多用复杂提示词确实在个别场景有效但整个项目的延迟和成本都在涨。上下文工程的目标是“在可控成本内达到可用水平”不是“无限逼近最优效果”。10. 我的真实体感与最后建议上一篇踩坑记写完之后这几个月里我又在不同的Agent项目上实践了这套上下文工程的方法论有几个感受特别想补充。第一个感受是上下文工程不是一次性工程而是持续运营工程。你的业务在变、用户在变、知识库在变上下文的管理策略也需要跟着迭代。我建议每个Agent项目在发布之后都保留一个“上下文观察仪表盘”持续看上下文占用率、指令守约率、检索命中率这些指标而不是上线就完事。第二个感受是上下文工程和产品设计是深度耦合的。好的Agent产品在设计交互流程时就会考虑上下文压力。比如主动引导用户一次只提一个核心目标在关键节点让用户确认信息这些产品层面的设计其实比任何技术优化都更省成本。如果你的Agent在高压力长对话下总是崩可能不仅仅是技术问题也可能是产品流程设计上有问题。第三个感受是别指望一个“万能上下文模板”通吃所有场景。每个业务的指令层设计、记忆命名法、检索策略都不一样。我个人的方法是每接手一个新Agent项目前两周不做别的就是买不同的真实对话场景往里怼观察上下文失效点总结出该业务特有的“上下文失效地图”。有了这张地图后面的优化思路会清晰得多。最后再分享一个小技巧每次跑完一轮上下文工程优化把优化前的badcase和优化后的输出对比存档。攒上两三个月回头翻一翻你不仅能看到问题的推移轨迹也能更准确地判断下一轮优化应该往哪个方向投入。这件事花的时间不多但价值远超预期。上下文工程的方法论还在快速演进但这些底层的注意力管理原则、信息分层方法、失效排查思路短期之内应该不会过时。希望这篇文章能帮你少走一些弯路早点把Agent从“勉强能跑”推进到“稳定可靠”的状态。