上下文工程实战:从Prompt到Agent记忆管理的系统指南

发布时间:2026/10/8 11:08:10
上下文工程实战:从Prompt到Agent记忆管理的系统指南 1. 先搞清楚上下文工程到底在解决什么问题过去两年我前后搭了二十多个AI Agent项目从简单的客服问答机器人到多工具协同的自动化工作流都摸过一遍。踩过的坑多了之后我越发确定一件事绝大多数Agent翻车不是模型能力不行而是上下文工程没做好。这里说的上下文工程不是单指Prompt Engineering那套“怎么把指令写得更好”而是更底层的系统级问题——你塞给大模型的那段上下文到底是怎么组织、怎么筛选、怎么更新、怎么预算的。它决定了Agent能不能在长流程中记住该记的、忘掉该忘的也决定了Token消耗是可控还是失控。用个生活化的比喻大模型像个只有几分钟工作记忆的专家你一次性给他看的信息越多他越容易抓不住重点但你要是把资料整理成带目录的文件夹、按需抽取给他看他就能高效干活。上下文工程就是替Agent做好这套文件夹的管理工作。这篇东西适合谁看正在用LangChain、AutoGen、Dify这类框架搭Agent的开发者或者自己做Agent架构设计、在做技术选型的人。我会把上下文工程拆成系统级的设计思路、资源管理策略、落地实操三个层面来讲最后附上我真实调试中遇到的故障案例。全程用我实际跑过的项目来讲不搞理论堆砌。2. 上下文工程的核心给Agent一个大脑不如给它一套记忆管理办法2.1 从“单轮对话”到“Agent循环”上下文为何成为瓶颈先说个最朴素的观察单次调用大模型接口时你只需要写好一个Prompt把用户问题一塞拿回结果完事。但Agent不一样它有“计划—执行—观察—再计划”的循环。每一轮循环模型都要基于之前的决策结果来做下一步判断。这时候上下文就不是一段静态文本了而是一条不断累积的动态状态流。我见过不少团队的第一版Agent就是简单粗暴地把所有历史消息、工具返回结果、用户原始需求全部拼接进Prompt每次调用都全文塞给模型。效果怎么样前两轮还行到第四五轮开始出现各种诡异行为模型忽然忘了原始目标、重复调用同一个工具、在无关分支里越走越远。原因很简单上下文被无关信息污染了。所以上下文工程的第一条原则是不是所有信息都该进上下文。大模型的注意力是有限资源挤占了关键信息的空间决策质量就断崖式下跌。这和人类开会差不多会议纪要里全是琐碎争吵记录真正要拍板的结论反而没人记得住。2.2 上下文窗口的本质约束Token不是越多越好很多人有个误区觉得上下文窗口越大越安全。模型支持128K、256K上下文我就把一整个项目文档库都塞进去总够了吧实测下来效果非常不理想。先看数据规律。我用同样的任务在上下文负载不同的情况下去跑大致是这么个趋势上下文占用比例模型任务完成质量典型表现低于20%很好指令遵从度高逻辑清晰20%-50%良好主要任务能完成细节偶有遗漏50%-70%一般开始出现遗忘、跑题、重复调用70%以上较差频繁忽略指令输出质量明显下降这个规律跟模型本身的注意力机制有关系。Transformer的注意力分布是稀疏的窗口越长关键信息在Attention矩阵里的权重越容易被稀释。所以上下文工程的核心任务不是把窗口填满而是在尽量小的窗口里装下尽量关键的信息。另一个被低估的点是成本。Token是实打实计费的上下文越长每次调用的成本和延迟都同步上升。如果你做一个高频调用的Agent上下文体积差3倍意味着单次调用成本差3倍一个月下来云账单的差距能让你老板瞳孔地震。所以上下文工程做得好不好直接反映在成本报表上。2.3 把上下文当成“四级缓存”来管理我自己在系统设计时会把Agent的上下文拆成四个层级参考了计算机体系结构里CPU缓存的分层思路。这套模型后来帮我在设计阶段就规避掉了大量后期返工。第一层是核心上下文包括用户当前指令、系统级角色设定、本轮执行必须的关键变量。这部分永远在Prompt的最前面占用尽量少的Token空间相当于L1缓存。第二层是工作记忆指Agent当前任务执行过程中产生的中间状态比如已经完成哪些步骤、工具返回了哪些关键结果、下一步计划的候选方案。这部分要持续更新每轮迭代后把过时信息清理掉。第三层是场景背景包括项目相关的领域知识、业务规则、历史偏好。这类信息不是每轮都用得上需要业务侧有一个检索层只在相关时动态注入。相当于L3缓存按需加载。第四层是长期记忆存储存在外部数据库或向量库里Agent不直接感知需要通过检索工具主动查询。有些信息不是当下任务需要但后续某个环节会用到。拿到一个Agent项目我会先画清楚这四层分别放什么再考虑每一层的更新策略。很多人的Agent一到大窗口就乱就是因为把所有东西都堆在了一二层三四层完全没建。2.4 状态管理的三个关键设计决策上下文里的“状态”指的是Agent当前对世界的认知。状态管理做不好上下文工程就失去了地基。我总结了三个关键设计决策。第一个决策状态是集中式保存还是跟随执行流传递。我推荐用一个独立的状态存储模块所有Agent步骤之间通过读取/写入这个模块来同步信息而不是把信息层层嵌套在工具参数里传递。集中式状态的好处是排查问题的时候一目了然且便于做回滚和审计。第二个决策状态的更新是追加式还是覆写式。追加式保留完整历史方便追溯但Token增长太快覆写式只保留最新值省空间但丢掉了过程信息。实际项目中我通常做折中关键节点的过程信息追加保留非关键状态覆写。这个折中策略能省下将近一半的Token消耗同时关键步骤的排查能力没有明显缺失。第三个决策状态的持久化粒度。每一轮Agent循环都持久化一次完整状态会拖慢流程且浪费存储我一般只持久化里程碑节点比如一个子任务完成、一次工具调用返回关键结果。出问题时恢复到里程碑状态重跑比从头跑代价小得多。3. 有限窗口里的信息博弈压缩、筛选与召回3.1 上下文压缩该扔的扔该缩的缩上下文压缩是我认为投入产出比最高的优化项。同样是做长流程任务不压缩的Agent跑10轮大概要爆掉小窗口模型做了压缩的Agent能稳定跑30轮以上而且效果更稳定。最基础的压缩手段有三类截断、摘要、结构化重写。截断最简单超过长度就丢最旧的消息。但直接截断的副作用是可能丢掉关键决策依据。我一般会在截断前加一道判断看这段消息里有没有被后续步骤引用的实体信息或者结论有就先抽出来放到状态模块里再丢原文。摘要压缩是性价比最高的。用一次附加的小模型调用把最近几轮冗长的工具返回、中间推理过程压缩成三十字以内的要点替换进上下文。这里有个经验摘要不是每轮都做而是设一个阈值比如原始内容累计超过上下文上限的30%时触发一次摘要避免频繁调用影响速度。结构化重写是针对工具返回结果的处理。一个工具返回5000字的JSON文档直接塞进上下文很浪费。我会提取成一句“xx查询返回3条结果其中第1条匹配度最高xxx”把非关键字段全部丢掉。这个过程可以用模型做也能用规则抽实测规则抽取的性能开销最低、延迟最小。3.2 动态检索与临场注入上下文是拼出来的说完压缩再讲上下文从哪来。对于有知识库的Agent不做检索就直接把全部文档塞进上下文的操作我劝你一次都不要试。正确做法是建立一个动态检索与注入层每一轮执行前根据当前任务目标和已有上下文从外部存储里检索最相关的内容片段生成候选筛选去重后注入当前Prompt。这里有个我刚做Agent时踩过的坑。第一次做知识库问答Agent我也知道要做RAG检索但只是简单地把“用户问题”拿去做了向量检索。结果一问到复合问题比如“对比某两个方案的优劣”检索回来的片段全是A方案的B方案一条没召回模型只能凭残缺信息瞎编。后面改成拿“用户问题 当前推理方向 未决问题清单”作为检索Query召回质量一下好了很多。检索筛选的具体策略上我现在用的是两层召回。第一层用向量相似度招回Top30候选片段第二层用一个轻量级的重排模型或者让主模型对候选做相关性打分选Top3到Top5进入上下文。第二层重排虽然多一次调用但对长文本场景的提升非常明显。如果你不想多调一次模型可以退化成用规则重排比如优先选择跟当前任务关键词重叠度高的片段。3.3 Token预算管理把上下文当成一根水管调用大模型接口Token就是你的水费单。上下文工程做得越糙水龙头就开得越大。我的做法是在Agent引擎层加一个Token预算控制器。进入每一轮执行前先估算当前Prompt的Token占用对照上限预算做四件事确认核心上下文不超限、压缩冗余的工作记忆、减少或替换低价值的背景信息、决定是否需要触发外部检索。这套预算控制逻辑跑起来之后Agent的所有Token消耗变得可预期不会出现某轮忽然超限的惊吓。具体估算Token时我用过一个简易规则中文字符每字约1.2到1.5个Token英文按4字符一个Token估算再加10%的余量。框架层面LangChain的get_num_tokens方法、Tiktoken库都能帮你做更精确的计算不过线上环境每次都调计算接口也有开销我一般只在关键节点做精确估算平时用粗略预估就够。再分享一条个人心得把上下文组件化之后我给每个组件标了一个“Token成本标签”开发调试模式下会在日志里打印每一轮“核心上下文多少Token、工作记忆多少Token、背景注入多少Token”。这样一眼就能看出哪个模块把预算吃掉了不用闷头猜。这个标签有个学名叫“上下文可视化”做法不复杂但效果非常好。4. 实操落地在主流Agent框架中实现上下文工程4.1 一个生产可用的上下文组织模板空谈设计太虚直接给一套能抄的模板。我自己做Agent时Prompt的上下文区域固定分成六块每块之间用明确的标记符隔开模型一眼就能分清哪段是什么。[系统设定] 你是...你的职责是...禁止做的事是... [当前目标] 用户本次请求要达成的目标... 成功标准... [已完成的步骤] 1. 已调用xx工具结果为... 2. 已确认yy信息... [未决分支] 1. 需要进一步确认... 2. 备选方案... [外部信息] 从知识库检索到的相关内容... [约束与注意] 本轮必须遵守... 不得重复...这六块的顺序我调了很多次为什么这样排有必要说清楚。系统设定放在最前面因为模型对开头信息的注意力权重最高这里放最核心的行为约束当前目标紧跟其后让模型时刻锚定任务不跑偏已完成的步骤放中间给模型提供历史依据未决分支放在倒数第二段提醒模型还有哪些悬念要处理这也是控制模型“自己脑补”的关键约束与注意放最后作为本轮的临门一脚提醒模型避免重复踩坑。这套模板最核心的思想是把“应该做什么”和“已经做了什么”分离。很多初版Agent之所以中途跑偏就是历史消息和目标混在一坨模型分不清哪个是用户的最新诉求、哪个是已经过时的临时操作。4.2 在LangChain里改造Context的实战记录以LangChain为例我的常用改造点有三个SystemMessage的组装、中间过程的摘要、工具返回的清洗。LangChain默认把每轮对话记在ChatMemory里直接塞给模型不做压缩。这就导致多轮后记忆爆炸。我改造的思路是自定义一个Memory类接管读写逻辑。写入时超过阈值就触发摘要模型把旧消息压缩成SummaryBuffer读取时只返回系统设定、摘要Buffer和最近两轮完整消息。代码层面其实不复杂核心就几十行from langchain.memory import ConversationSummaryBufferMemory from langchain.llms import OpenAI memory ConversationSummaryBufferMemory( llmOpenAI(modelgpt-4o-mini, temperature0), max_token_limit2000, memory_keychat_history, return_messagesTrue )这样改造后同样的长对话任务Token消耗降了接近60%。代价是每触发一次摘要压缩会多一次小模型调用延迟增加200到400毫秒左右。对大多数场景来说这个代价完全值得。工具返回的清洗我一般用回调函数处理。拿搜索工具举例原始返回是一大段网页正文我会在回调里提取标题、URL、关键段落摘要拼成结构化结果再进入上下文。这个提取逻辑可以用正则写关键词上下文也可以用模型摘要我推荐在工具侧用规则清洗毕竟回调里再多调一次模型延迟和成本都会double。4.3 长流程任务的分段上下文刷新五轮一清、阶段一结多步Agent跑长任务后必遇上下文污染问题。我总结了一个有效模式分段上下文刷新。具体操作是把任务拆成若干阶段每个阶段结束时做一次刷新。刷新做三件事把已完成阶段的详细过程摘要压缩成几行状态记录、清理掉阶段内的临时性中间变量、更新当前目标为下一阶段的目标。这个刷新动作可以手工触发也可以在框架里做成定时或按步骤数触发——我一般是每五轮强制触发一次轻量刷新每个大阶段完成时做一次深度刷新。用这个模式跑过一个类似行业调研的Agent任务要完成从资料收集、归纳分析、生成报告大纲、逐节写稿到格式整理整个流水线。如果不做刷新跑到写稿阶段上下文里还堆着大量检索原文模型输出质量明显下降做了阶段刷新后写稿阶段上下文里只剩分析结论、大纲和风格约束模型输出质量稳定很多。这个模式的原理也简单上下文应该反映Agent当前的“工作台面”工作台面上放的是当前阶段要用的工具和材料而不是整个车间的库存。车间库存放到长期记忆里需要时再调。4.4 永续运行的Agent上下文定时清零重建还有一种更极致的场景——让Agent长期运行比如监控类、自动化排班类的常驻Agent。这类Agent理论上要跑很久上下文不可能一直累积。更要命的是长跑之后上下文里会混入越来越多的过时判断模型对自己的历史错误会出现“路径依赖”。我在做这类常驻Agent时采用一个简单粗暴但有效的策略定期会话重建。每跑完一个完整任务周期就把当前状态持久化到一个紧凑摘要里然后清空对话上下文用“摘要 新任务指令”作为新的起点。看起来丢了历史但换来的是每一轮决策都在干净的工作台面上进行不会背着沉重的历史包袱。有个监控型Agent之前每跑两个小时就开始出现误判排查后发现是上下文累积了太多旧告警的处理记录模型被旧信息干扰了。改成每处理完一批告警就重建上下文后连续跑了两周误判率下降了七八成。这里也说明一个道理Agent的状态持久化不等于上下文全量保留该断舍离的时候要果断。5. 我踩过的那些上下文工程的坑故障实录与排查速查5.1 真实故障一模型“失忆”问题竟然出在消息顺序有一次做一个客服工单分类Agent用户聊到第4轮的时候模型忽然不再理会用户最开始说的“我是一个新手请用通俗语言解释”这个约束输出变得特别专业术语化。我一度怀疑是模型抽风后来分析了完整请求日志才发现我的代码把最新用户消息拼接在Prompt最末尾但系统指令和用户原始偏好放在了最前面中间隔着几轮历史往来消息Token一长模型把开头那段偏好给“注意力稀释”了。排查后我把用户的持久化约束比如“新手友好”、“喜欢简洁回答”抽出来放到系统设定里并每次请求都固定在上下文前部。效果立竿见影第4轮、第8轮、第20轮这个约束都稳定生效。后来我做了一个通用规则凡是用户在一次会话里明确表达的偏好都应该提升为持久化约束而不是放在对话流里随波逐流。这是一条非常实用、但很多人不会主动去做的经验。5.2 真实故障二Retry导致上下文翻倍每次重试都在叠buff另一个让我印象深刻的坑发生在联调阶段。Agent调用某个外部API偶发超时我加了一个Retry机制最多重试3次。结果我发现每次重试不仅重新调用了API还把上一次失败的工具调用记录留在了上下文里。到第3次重试时上下文里已经堆了3份几乎一样的工具调用记录模型甚至开始尝试分析“为什么前两次失败了”完全偏离了原本的任务。修复方法很直接重试前先把上轮失败的工具调用记录从上下文里剔除只留一条“该工具曾返回超时将重试”的状态。更通用的经验任何试图“从错误中学习”的机制前提是错误信息是经过提炼的而不是原始堆叠。我也见过团队为了解决这个问题给上下文加了一套“消息去重器”凡是相似度高于阈值的消息自动合并效果也不错。5.3 真实故障三把几万字报告拆成几百个片段反而召回失焦这个坑属于检索侧的经典翻车。我给一个法律文书分析Agent接入了知识库为了追求“不遗漏”把一份几万字的报告拆成了几百个小片段每段只有一百多字向量相似度检索后取Top3召回。结果发现模型拿到的三个片段全都是细枝末节核心结论一个没召回到。排查后发现问题出在切分方式上。固定字符数切分把完整的章节语义切碎了单独看每个小片段都缺少上下文。后面我改成按语义块切分用标题层级和段落含义做分割边界小片段保底三百字以上再配合刚才说的两级召回与重排。同一份文档召回相关性评分提升了近一倍模型输出的准确率也明显改善。切分粒度必须跟下游检索和模型阅读方式匹配贪细反而吞掉语义这条经验对所有知识库类Agent通用。5.4 上下文工程常见排查项速查表搞一套排查清单遇到Agent行为异常先过一遍能省下大量时间。排查项可能原因处理方式模型忽略开头约束约束被过长历史淹没把约束固定进System消息保持前置模型重复执行某步骤工具结果未清理或状态未更新检查该步骤结果是否已写入状态并移出工作记忆模型回答跑题上下文混入无关背景检查检索注入逻辑收紧相关性阈值多轮后Token暴涨历史消息未压缩接入摘要压缩阈值机制重试后行为异常Retry记录叠加入上下文重试前清理失败记录检索结果相关但无用切分粒度不匹配改为语义块切分增加重排环节上下文重置后丢设定持久化约束被清空把用户偏好持久化到外部存储重建时恢复模型编造历史结论历史摘要过度压缩丢结论摘要时保留实体与关键结论字段这张表我打印了一份贴在工位每次Agent调试不顺都会先过一遍把问题定性清楚了再动代码比无头苍蝇式调参高效得多。5.5 一个偷学来的高级技巧上下文“审计日志”最后分享一个从一次架构评审里学到的高级技巧。当时评审老师建议给Agent加一套“上下文审计日志”每次请求发出前把当前Prompt的结构占比、各区域的Token占用、检索来源记录全部打成结构化日志。看起来只是多打了几行日志但实际价值巨大。有了这套日志线上出问题时你不需要去猜模型“为什么这么想”而是可以直接还原“模型当时看到了什么”。有一回Agent在线上出现了一次罕见的错误判断我靠审计日志的Prompt快照百分之百还原了当时的上下文全貌定位到到底是哪段旧消息干扰了判断。这比反复复现、加日志调试省了至少一天时间。实现上也不复杂在请求拦截器或框架的中间件里把组装好的Messages数组镜像一份存到日志存储带上trace_id和会话id。对性能的影响可以忽略但排查问题时的体验提升是一整个量级的。6. 上下文工程与架构选型框架、语言与未来方向6.1 主流Agent框架对上下文工程的原生支持差异很多人选框架时只盯着模型能力看忽略了一个维度——框架对上下文管理的原生支持这直接决定你在工程上要补多少轮子。我用过的框架里LangChain的Memory体系最灵活但默认配置几乎等于裸奔需要自己改造AutoGen的多Agent对话模式天然会产生巨量历史消息它在上下文压缩上内置了一些机制但策略偏简单只适合短流程Dify这类偏应用层的平台把知识库检索和上下文管理封装成了可视化配置适合快速搭建但深度定制空间小比较新的生产级框架如LangGraph已经开始把状态管理当作一等公民来设计它那个State对象和节点间的显式状态传递思路和我前面讲的集中式状态管理很接近做复杂Agent时省掉不少自己造的轮子。我的建议是如果你的Agent要做超过两个以上的工具协同尽量选有显式状态管理能力的设计或者自己实现一个状态层别硬靠对话历史来隐式承载Agent状态。6.2 为什么有人用Rust写Agent上下文工程视角的观察热搜词里有“基于rust语言ai agent”这个方向最近讨论度挺高。从上下文工程的角度看我理解这个趋势的动因Agent一旦进入生产环境上下文管理涉及大量的字符串处理、缓存管理、并发控制而这些恰恰是Rust的强项。相对Python方案Rust实现Agent时对内存和CPU的控制更精细处理大上下文时的吞吐和延迟表现更稳定对成本敏感的高频调用场景有明显价值。不过要泼一盆冷水Rust Agent框架生态成熟度跟Python差距还不小而且上下文工程的核心难点更多在策略设计上语言层面只能优化执行效率不能替代策略本身。技术选型时团队熟悉度应该排在第一位不要单纯为了“潮流”去换语言赛道。上下文工程的思路是语言无关的你完全可以用Python先把策略打通再考虑性能优化是否值得换语言重写。6.3 上下文工程的下一步从手动策略走向自动化管理最后聊聊我对发展方向的理解。现在上下文工程在多数项目里还是靠人肉经验和手动配置断言该压缩了、该检索了、该重置了全靠开发者的设计水平。下一步的演化方向是让上下文管理策略本身变得更加自适应比如根据当前任务的复杂度自动调整压缩强度、根据上下文拥挤度动态决策是否触发检索或摘要。这类能力的早期形态在一些框架里已经在很雏形地出现了比如自动Message历史剪裁。我认为未来成熟的Agent框架会把上下文工程内置成一个类似“内存管理器”的组件开发者只需要声明任务的记忆需求和预算上限由框架层自行决定如何组织与更新上下文。到那个阶段Agent开发者的核心工作会进一步上移到业务逻辑和目标拆解而不是整天跟Token较劲。但这不意味着你现在可以不学上下文工程。恰恰相反在框架还没帮你做这些事之前谁先把这套能力吃透并沉淀成工程规范谁在Agent落地的效率上就领先一个身位。这项能力是理解Agent系统工作原理的基石之一花时间投入一定值得。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询