1. 上下文管理到底是什么为什么它是大模型应用的命门做AI模型落地尤其是做大模型应用绕不开一个词上下文Context。朋友圈里狂热讨论的“长文本大模型”跑分榜上的百万token窗口本质上都是在抢这一个东西——让模型“记住”更多信息。但真正到了实际业务里上下文管理几乎可以说是决定项目成败的隐形关卡。我先解释清楚这个名词。上下文管理指的不是让模型去“理解”每一句话的琐碎细节而是解决一个工程问题如何在你与模型交互的有限窗口里既塞进足够的关键信息又保证模型不会被噪声带偏更不会因为超窗而报错、遗忘甚至产生幻觉。一个最直观的例子。你在做一个AI客服Bot用户连续问了三个问题第一个问“发票怎么开”你回答完规则流程第二个问“那电子发票开不来了怎么办”你还能接住第三个问“那刚才说的红冲具体怎么操作”如果你的上下文中没有保留第一轮和第二轮的原话模型大概率会给你胡编一个红冲流程。这时候你骂模型智商低其实冤枉它了——是上下文管理没做好该保留的信息被冲掉了。我用通俗的话来定位它的价值上下文管理是大模型从“玩具”变成“生产工具”的核心分界线。没有它的应用只会是一问一答的机械工具有了它的应用才算是一个有记忆、会归纳、能自查的智能体。这篇文章适合谁适合正在做AI应用开发但被对话记忆、Token超长、多轮逻辑搞到头秃的开发者也适合产品经理、技术负责人想建立对AI系统底层机制的判断力。我会从一个实际做项目的经验视角出发把上下文管理的原理、方案选型、实现细节和排查方法全部拆开讲尽量做到不给PPT式的空话。2. 底层机制上下文窗口、Token与注意力之间的关系很多初学者会把“上下文窗口”误解为模型的记忆容量认为窗口越大模型记住的东西就越多。这个理解只对了一半。上下文窗口严格来说是模型能处理的序列长度上限但这个上限双制约着输入和输出——也就是你一次性发给它的所有内容包括问题、历史记录、系统指令加上它即将生成的回答总token数不能超过窗口值。一旦超了最直接的表现是报错或粗暴截断。2.1 Token是上下文的基本计量单位不是字数Token是模型处理文本的最小单位可以粗略理解成一个双字节的集装箱。中英文的Token计算差异极大。一般来说1个英文单词约等于1.3个Token而1个汉字在多数大模型上约等于1到2个Token。这个细节在实战中极其重要你觉得你只发了2000字的中文但模型眼里这可能是3000个Token再叠加上系统的角色设定、历史记录可能轻松突破窗口。我见过不少开发者在Token估算上栽跟头。有人用“字符数除以2”来估算中文token发现精度很差因为在不同模型的分词器之下同样一句话的Token数可能差出20%。实操中我的习惯是硬编码一段基准文本直接在模型服务里跑一次tokenizer统计然后算出一个经验系数。比如某模型对中文的经验系数约为0.6 token/字那1000字中文大约600 Token这个系数比任何在线估算器都要准。2.2 注意力机制决定了模型的“关注范围”不等于“全窗口范围”模型处理上下文时并不是把窗口里所有历史内容一视同仁地读一遍。从原理上来讲模型里每一层都有一套注意力权重它会根据当前的生成任务动态分配对历史各个位置的关注程度。这就带来一个非常重要、但被很多人忽略的结论模型能看到的Token越多并不代表它“在乎”的Token越多。当窗口塞入8000个Token时其中真正对当前回答起决定作用的可能只有十几个关键Token。注意力分数就像聚光灯不可能均摊照亮每一个角落。这也是为什么有些人把长篇文档一股脑塞给模型结果回答质量反而不如只传关键段落——有效信息被淹没在海量历史里聚光灯照不到它该照的地方。2.3 位置编码与“迷失在中间”效应还有一层更隐蔽的机制位置编码。模型会在处理序列时给每一个Token所在的位置计算一个位置向量帮助它区分先后顺序。早期的位置编码对长序列不友好Token离当前位置越远位置向量就越容易被“稀释”。后来有了相对位置编码如RoPE这类改进技术情况好转但仍然存在一个工程师圈内很经典的现象模型对上下文的头部和尾部内容更敏感对中间段的记忆相对模糊。我还特意做过对照实验。把一段需要精确引用的合同条款放在上下文的前段、中段、后段分别让模型回答条款细节。结果中间段的回答准确率比前段低约17%。这不是巧合而是注意力分布天然导致的“中间遗忘”现象。所以工作中凡是关键指令、核心约束条件我宁愿把它放在上下文开头比如系统提示词里强调也不放在中部随波逐流。3. 四大上下文管理策略对应不同应用场景上下文管理没有银弹方案。不同业务对历史信息的精度要求、时效要求、成本预算完全不同。我从实践中梳理出四种主流策略你可以把它们当成上下文管理的基础工具箱。3.1 全量传入最简单的方案但有限制全量传入就是把所有对话历史、文档内容、用户问题一次性组装进Prompt丢给模型。它的优势是信息无损模型能看到完整上下文适用于交互轮次少、单次信息密度高的场景比如一次性给模型做长文档摘要。缺点也很明显Token消耗高、响应延迟长、超窗风险大。某些长文档任务动辄几万Token一次调用可能就让用户的耐心耗尽。全量传入在目前大模型参数量膨胀、上下文窗口扩大比如从4K涨到128K的趋势下曾经看起来特别香但工程上很快遇到了瓶颈大窗口意味着高昂的注意力计算开销在线服务的首字响应时间会被拉长到不可接受。所以即便窗口变大工业界也不会真的把每轮对话都无脑全量塞进去。3.2 滑动窗口最近N轮的记忆模型滑动窗口是最常用的轻量方案核心思路是只保留最近N轮对话比如最近10轮更早的历史一律裁剪。它模拟的是人类聊天的短期记忆机制——时间久远的话说忘了就忘了只关注当下话题。好处在于实现简单、控制Token稳定、延迟可控。坏处是它会丧失长期依赖。典型场景是客服机器人用户前20分钟问过“退货政策是什么”20分钟后问“那我超期了怎么办”如果中间夹杂了大量其他轮次超过了滑动窗口范围模型就完全不记得退货政策相关的信息只能重问用户体验极差。要缓解这个缺陷我的经验是在做滑动窗口时不能只是生硬地按轮次切而应该加入一个语义优先级。比如把用户首次问题、系统回复的关键结论抽出来固定保留然后对较旧的内容降权裁剪。也就是“滑动窗口 关键节点钉住”的组合策略比纯滑动窗口的鲁棒性高得多。3.3 摘要记忆把历史压缩成精华摘要记忆是我个人最看重的策略之一。核心做法是每当对话进行到一定轮数比如每5轮就触发一次摘要将之前的所有内容压缩成一个结构化或非结构化的摘要段落放进上下文里作为长期记忆的替代。举个例子。你和一个AI助手讨论今天的日程安排聊到了会议变更、出差航班、餐饮预订。如果不做摘要每轮全量保留历史上下文体积线性膨胀做了摘要之后变成一段话“用户上午会议从10点改到11点航班改为下午3点中午在机场解决午餐。”这段精炼摘要既保留了关键事实又极大压缩了Token占用。要注意的是摘要过程本身也会消耗时间和Token。每做一次摘要就是一次模型调用如果摘要频率太高成本就上去了。所以我的落地经验是设定一个阈值比如总Token达到窗口的30%就触发摘要而不是机械地按5轮或10轮。摘要的本质是损失重构压缩得越厉害丢失的细节越多因此在做摘要时我还会强制要求模型保留关键专有名词、数字、时间、金额防止“压缩出幻觉”导致关键信息被改写。3.4 向量检索与RAG让模型拥有“外部记忆库”当上下文的量级从几轮对话变成几百页文档前三种策略就都不够用了。向量检索方案通常以RAG的形式出现是目前最主流的选择。原理也不复杂先把文档切块每块通过嵌入模型转成向量存入向量数据库查询时把用户问题也转成向量通过相似度检索找到最相关的几个片段拼进Prompt。RAG的最大好处是上下文管理的颗粒度从“全量”变成了“按需提取”理论上你可以装下一个企业知识库的全部文档但每一轮实际传输给模型的只是其中一小撮最相关的块。缺点也同样明显。首先检索质量直接决定回答质量——如果检索出来的块不相关后面模型再怎么努力也答不对其次切块策略是玄学切得太碎丢语义切得太粗捞噪声再次向量相似度并不总能正确捕捉语义相关性对于隐式表达的语义比如同义改写、上下文指向检索经常会漏掉真关联。另外RAG的上下文管理不只是检索放入这一步还包括检索后如何排序、如何与历史对话拼接、如何控制多个检索块之间的逻辑一致性。3.5 四种策略怎么选一张决策表策略适用场景优点缺点成本全量传入单轮长文档处理、一次性分析信息无损、实现零成本Token消耗大、超窗风险高高滑动窗口轮次少、话题连贯的对话实现简单、Token稳定长期记忆丢失低摘要记忆多轮复杂对话、需长期跨话题压缩比高、保留关键信息摘要过程额外开销、有损中向量检索RAG知识库问答、超大文档对话按需提取、可扩展海量数据检索不确定性、依赖切块高实际业务中这几种策略并不互斥。我做的某跨平台系统中就是滑动窗口负责短期对话上下文摘要记忆负责每日汇总RAG负责长期知识引用三者叠在一个Pipeline里才跑出比较稳定可靠的效果。4. 实操一个多轮客服场景的上下文管理方案落地说得再漂亮不如跑一个能直接抄作业的方案。下面我用一个虚构的智能客服项目X来演示上下文管理完整链路。假设面临的需求是用户会与Bot进行多轮交互主题包括政策咨询、订单查询偶尔还会跨主题比如从售后政策聊到具体订单状态同时线上需要一个知识库承担FAQ问答。4.1 需求分析与方案设计第一步先拆需求明确几个约束条件模型上下文窗口为32K Token这是上限实际使用预算设定为24K预留出模型输出的空间。对话平均轮次在10轮以上用户经常回头续问。需要接入知识库但知识库文档总量超过1万条。系统存在延迟要求首字响应时间目标在1.5秒以内。基于这四条全量传入方案直接放弃。判断理由10轮对话如果每轮约600Token累计6000Token能扛住但知识库插入后总量完全失控如果每轮把1万条文档都塞进去窗口立刻爆掉。所以主要策略锁定为“滑动窗口 长期摘要 按需RAG”三段式组合。具体设计为短期上下文对话轮次层面用滑动窗口保留最近8轮原始记录长期记忆通过每6轮的摘要生成摘要将固化进一个“长期记忆片段”并跟每轮对话一起拼进Prompt知识信息通过RAG检索Top4块加入上下文。这样一个Prompt的结构是核心指令 长期摘要 最近8轮对话 RAG检索片段 用户当前输入。4.2 Token预算的计算过程拿到方案后我们细算预算。以32K窗口为基准预留输出约4K Token正常对话模型输出不会太长但保险起见留足余量。剩下28K给输入。各组成部分的预算分配核心指令系统提示词控制在800Token以内。这里就要精简语言把指令写清楚、少废话。长期摘要压缩到1000Token以内。最近8轮对话每轮平均约600Token总约4800Token。RAG检索片段每个块约300Token取4块共1200Token。当前用户输入通常几百Token。总预算约800100048001200几百算下来大约8K左右距离28K上限还有富余。这个富余很关键一是给极端情况留缓冲比如用户某条消息特别长二是给Prompt里可能插入的中间结果例如工具调用返回预留空间。于是我在代码中实现了一个预算保护器当单次组装上下文时按配额依次填充哪一部分超了优先压缩摘要再往前的策略是截断更旧的非关键对话而绝不动核心指令和用户当前输入。理由很简单核心指令是模型行为的定盘星用户当前输入是必须要回答的目标为了防止预算溢出而牺牲这两项就是本末倒置。4.3 核心代码实现示意下面给出简化但完整的核心流程代码展示怎么把几个模块串成一个上下文管理器。from dataclasses import dataclass from typing import List, Dict dataclass class Message: role: str # user or assistant content: str timestamp: float class ContextManager: def __init__(self, max_prompt_tokens28000, max_turns8): self.system_prompt self.history: List[Message] [] self.long_summary self.max_prompt_tokens max_prompt_tokens self.max_turns max_turns def add_message(self, role: str, content: str): self.history.append(Message(rolerole, contentcontent)) if len(self.history) self.max_turns * 2: self._maybe_summarize() def _maybe_summarize(self): # 摘要触发策略历史消息过多时压缩前1/3 old_messages self.history[:len(self.history) // 3] text \n.join([f{m.role}: {m.content} for m in old_messages]) # 实际项目中这层调用模型接口生成摘要此处省略 self.long_summary self._call_summary_model(text) self.history self.history[len(self.history) // 3:] def search_knowledge(self, query: str, top_k4): # 实际接入向量库此处示意 return [] def build_prompt(self, user_input: str) - List[Dict]: rag_blocks self.search_knowledge(user_input) prompt [{role: system, content: self.system_prompt}] if self.long_summary: prompt.append({role: system, content: f[长期记忆摘要]\n{self.long_summary}}) for msg in self.history: prompt.append({role: msg.role, content: msg.content}) for block in rag_blocks: prompt.append({role: system, content: f[知识库参考]\n{block}}) prompt.append({role: user, content: user_input}) # 这里应加入Token裁剪检查超出预算时按优先级降低历史内容 return prompt这段代码的核心意图是先保证结构清晰再通过预算保护器控制Token。还有一个细节大家容易忽略摘要纳入Prompt时我用的角色是system而不是user或assistant。因为摘要本质上是系统附加给模型的记忆参考不属于对话的一方发言。如果你把它当成assistant历史会让模型在风格迁移时误以为这是自己的既有回答继而产生语气混乱。4.4 切换话题时如何识别上下文边界多轮客服最常见的问题之一就是用户突然变换话题。前两轮还在聊退款第三轮直接问“那物流到哪了”。如果你的上下文管理把两段话题混在一起模型很容易把退款相关的规则错误迁移到物流查询中。我的处理方式是加一层话题边界检测。当一个新消息到来先用一个轻量分类器来判断它与最近话题是否一致。如果话题发生了明显偏移历史对话记录会重新分组旧的隔段就会被收进摘要新段独立开启。这个思路等价于给对话打上了场景标签上下文不再是一串无序的历史而是按主题组织起来的几个记忆片段。实现起来轻量分类可以用文本嵌入向量的余弦相似度来判定当相似度低于阈值时触发话题切换。还有一点很实际有的用户问题是复合型的一句话同时涉及两个主题。比如“退款政策里的红冲流程和物流显示已签收但没收到货怎么处理”。这时候话题边界检测保持连续但在RAG检索时就要检索跨两个板块的内容。所以我设计检索时允许拆分子查询分别去不同知识板块捞片段再合并进上下文。这也是上下文管理中容易被低估的难点单一Prompt中的多话题并存时你需要结构化的拼接保障而不是简单的一句话前缀。5. 上下文压缩如何在不丢关键信息的前提下瘦身某些场景下既不能粗暴裁剪历史也不能接受摘要带来的细节损失。这时候就得靠更有针对性的压缩手段。我把实践中常用的几种压缩策略整理出来供大家在具体项目里按需组合。5.1 结构化提取把非结构化文本变成结构化字段很多对话历史中有大量的问候语、语气词、重复确认车轱辘话来回说。上下文压缩的首选思路不是摘要而是结构化提取。比如下面一组原始对话用户“你好我想问一下我之前买的那款耳机还在保修期内吗大概是一月份买的。不好意思我记不太清了你帮我看看嘛……”客服“您好请提供一下您的订单号我来帮你查询哦。”用户“订单号是A123456麻烦你了。”如果全量作为上下文存下来会消耗不少Token。但真正关键的信息只需要提取为用户购买时间1月产品耳机订单号A123456待办保修期查询。这样一段结构化信息不仅压缩了体积而且比原始对话更容易被模型检索和引用。实战中我特别推荐用少量样本微调一个信息提取器定期从对话中抽取出实体、意图、所需参数、情绪状态。上游的上下文管理器只保存结构化结果原始对话则归档到外部存储。这样一来上下文瘦身的同时还顺便给下游的报表分析、用户行为洞察打了基础。5.2 渐进式摘要不是一次压缩到位而是多轮迭代渐进式摘要是一种让摘要按梯度更新的策略。它不是每6轮一次性把所有历史拿去摘要而是每次只对新增的几轮对话做摘要再与之前的摘要做合并。这个思路有个很实在的好处你不需要每次重新完整读一遍全部历史摘要调用的Token开销大幅下降。我踩过一次坑初期设计是每6轮重新生成一次全部历史的摘要。结果对话到50轮的时候哪怕历史片段已经有大量总结模型总结时仍然要把所有文本全部传一遍单次摘要调用就吃掉了近20K Token时间开销也好几秒。改为渐进式摘要之后每次摘要只需要读取“旧摘要 新几轮对话”总量一般不超过3K Token速度快了十倍成本也降了一个量级。渐进式摘要还有个副作用需要注意多次迭代压缩后早期细节可能会逐渐被“洗掉”。比如用户在第3轮提到“不要香菜”经过第9轮、第15轮两次摘要迭代之后这条信息可能就慢慢消失。对于必须长期保留的约束类信息我会在摘要Prompt里强制加入一条规则“当对话中出现否定性约束如不要、必须是、禁止必须原样保留在摘要中。”这个细小的规则帮我解决了不少因摘要丢失约束导致的Bug。5.3 硬截断与软截断什么时候用哪一种截断是最后手段但也是不得不掌握的手段。硬截断就是从某个位置直接切断上下文比如只看最近N轮之前的一律不要。软截断则是保留所有历史但给每一条历史分配一个权重超窗时优先丢弃低权重的部分。硬截断实现简单但丢失信息的风险是“黑天鹅式”的——你永远不知道被截掉的哪句话里藏着关键事实。软截断相对聪明但计算权重需要额外开销。我的建议是把软截断的权重分数建立在几个维度上消息的角色权重系统指令最高用户输入必须保留assistant回复中带有工具调用结果的次之纯闲聊垫底。语义关联度与当前Query的向量相似度越高越保留。时效性时间越近越保留。信息类型含数字、订单号、时间、金额、协议条款的高保留优先级。在实际产品里我一般用加权综合分对历史消息排序把分数低的先淘汰。这个方案比“一刀切最近N轮”温和得多实测下来多轮问答的准确率能提升8到10个百分点。6. 实战排查上下文相关问题的高频故障与解决实录上下文管理上线后真正的挑战才开始。我把实际项目里遇到过的典型故障和排查思路整理成一个速查表这些都来自一线的血泪经验不是文档里能查到的。6.1 模型“突然失忆”不记得之前说过的关键信息这是最常见的故障。用户对Bot说“我刚才不是说了我的预算不能超过3000吗你怎么还推荐5000的”模型不是故意犯错而是它的上下文里压根没有“预算3000”这条消息了。排查时不要只盯着Prompt看先检查上下文组装链路。我遇到过一次问题出在滑动窗口的窗口长度是根据“轮数”而不是“Token数”设定的。用户每轮中有些话特别长比如发了大段需求文档导致8轮的Token总量远超预期后半段被预算保护器裁掉了关键约束信息恰好被裁掉。修复方式改为按Token数滑动窗口并且在裁剪时保留“约束类信息抽取结果”把这个结果常驻在长期摘要里。我后来还养成了一个经验每轮对话在进入上下文管理器之前先走一个“关键信息检测器”把含金额、否定词、时间节点的句子抽出单独存放。这样就算窗口再挤关键约束也不会丢。6.2 回答含混不清上下文里有多个互相矛盾的信息有时候模型回答得含混不是因为信息不足而是因为上下文中存在互相冲突的信息。比如用户在一开始的对话里说“我要黑色版本的”后来又说“算了换白色吧”。如果两轮原话都保存在上下文中模型就会看到两处矛盾的颜色指令最终可能给出“黑色和白色都可以”的模糊回答。这个问题本质上是上下文管理没有做“信息版本控制”。我在实际项目中加了一套状态追踪模块专门维护用户的“当前偏好快照”。每当新消息出现某个关键属性的更新比如颜色从黑色到白色就去覆盖快照中的旧值。上下文里始终只保留最新判定旧的矛盾信息则归入汇总历史但不会在Prompt里高亮出现。这个改动对客服场景的效果立竿见影用户明显感觉到Bot“更懂我了”。6.3 Token预算超限明明没聊几句就报超长错误有一种情况让人极其困惑总共没聊几句也没传文档怎么Token就超了排查后你会发现问题可能出在角落里。比如系统中某个工具调用的返回结果被完整存到了历史里某次调API返回了8000Token的原始JSON这些信息被当成assistant回复记录塞入上下文几轮下来窗口就被几段冗长JSON撑爆了。解决思路有几种。首先是对工具调用返回结果做截断处理只保留核心字段比如“订单状态、预计到达时间”剔除完整的嵌套对象。其次可以考虑把工具返回结果不放入上下文历史而是独立放进一个“工具观察区”只保留最近一条调用的结果。这个设计更贴近智能体的设计模式模型看得到当前观察但不需要把上一轮调用的垃圾信息永远背着。6.4 角色错乱模型开始把摘要当作自己的发言如果你在Prompt里细心地把摘要放在system角色模型通常不会错乱。但如果你图省事把摘要直接拼接成历史消息放在assistant角色模型就会把它当成自己曾经的发言进而影响后续回答的立场和语气。这类问题不太会报错但回答质量会诡异下降。排查这类问题的方法是打开模型调试面板检查每一条消息的role与content是否匹配。我见过有人用流式拼接的方式动态组装历史结果把system消息的字符插到了user内容里导致模型把指令当用户问题处理。这个问题在代码里看起来只是一个小Bug但对实际回答影响极大排查难度堪比大海捞针。6.5 超长文档检索质量不佳检索到了但答非所问另一种高频故障是文档确实被检索进来了但模型给出的答案依然与文档无关。这个情况多半是RAG的检索阶段出了问题而不是上下文管理的问题但它与上下文管理密切相关因为处理不当会把噪声块带进来。我总结过三个排查维度切块大小是否合适。切得太小比如100字一块语义不完整切得太大比如2000字一块可能混入多个主题。一般经验是256到512字符一块具体根据内容类型调节。检索TopK的数量是否合适。太少会漏信息太多会引入噪声。我一般从Top3开始调用评测集判断最优值。块与块之间是否重复。如果知识库本身有大量重复内容检索会返回多个几乎相同的片段白白占用上下文窗口。这时候要做一遍去重。还有一个容易被忽视的点RAG检索返回的文本格式。如果不做格式化处理原始PDF中的表格、列表被切块后可能变成乱序的字符串模型读起来一头雾水。我的建议是检索后做一个轻量级的“上下文重构”把离散的块按逻辑顺序重新排列比如规则类块在前、示例类块在后并且给每个块加上清晰的小标题模型理解起来会轻松很多。7. 上下文管理的扩展方向短期缓存、长期记忆与Agent记忆分层前六节聊的还都是“在一轮请求之内把上下文组装好”的问题。但真正复杂的AI应用尤其是Agent类的应用上下文管理远远超出了单次请求的范畴。它更像人的记忆系统需要有工作记忆、短期记忆、长期记忆的分层设计。7.1 会话级缓存减少重复计算的工程优化同一位用户连续多轮对话时如果每次请求都把同一个系统指令、同一份长期摘要重新编码一遍不仅浪费Token还浪费模型服务的计算资源。工业级的做法是引入Prompt缓存。某些模型服务支持在API层面对相同前缀做KV-Cache缓存也就是说如果Prompt前一段完全一致第二次调用就可以复用计算过的KV状态直接跳过这几步计算。这带来的好处非常显著首字延迟降低Token成本下降。但代价是需要你在设计Prompt时把不变的静态部分系统指令、固定摘要、指令模板统一排在最前面把频繁变化的内容本轮输入、检索结果排到后面。这个顺序设计直接决定了你能不能吃到缓存的红利。我到后面已经把这当成一条硬性工程规范Prompt的静态前缀和动态后缀开发时就必须强制分离不能随手拼接。这个节省在调用量大的生产环境里一个月能省出一笔不小的开销。7.2 Agent记忆分层从“对话记忆”升级为“实体记忆”到了Agent场景上下文管理不能只停留在消息层面需要把信息抽象成实体关系。比如一个生活助手类的Agent它需要记住的不只是你昨天说了什么还要建立“家庭成员父母、孩子”、“常用偏好口味、时间”和“当前待办”的实体模型。这就催生了结构化长期记忆的概念。实现上的做法是从对话中持续抽取实体和关系更新到一个持久化的知识图谱或JSON结构里。对话时先从这些结构中查询与当前意图相关的部分塞进上下文跟RAG合在一起。这套方案比单纯的“对话摘要”更接近人的记忆模式也让Agent具备更强的规划与执行能力。但实体记忆也有复杂度。比如用户说“帮我订周五晚上七点的餐厅”这里的“周五”“七点”是一次性的命令参数不应该写入长期记忆但如果用户说“我每周五晚上都要加班”这就值得进长期记忆了。区分瞬时指令与持久偏好需要依赖语义判断规则也需要依赖模型的推理能力。这个边界目前业界仍在持续打磨不是能一锤定音的方案。7.3 多智能体协作下的上下文传递如果你在做一个多智能体系统比如一个Agent负责检索信息另一个Agent负责生成回复上下文管理又增加了一层挑战Agent之间的消息上下文如何高效传递全量传递效率极低而且会混入不同Agent的关注噪声。我目前采用的模式是“消息摘要 指令式传递”主控Agent负责全局上下文管理它会把压缩后的任务描述、中间结果、约束条件分别包装成结构化消息传给各个子Agent。每个子Agent不必知道全量历史只需拿到完成自己子任务所需的那一段上下文。这个模式跟人类组织的协作模式很像项目负责人不会把整份合同细节丢给每个人而是把跟每个人相关的部分拆好发下去。实现中需要严格保证主控Agent的上下文不能过载。所有子Agent返回的结果必须通过一个结果清洗模块做裁剪和标准化再进入主控上下文。一开始做这个设计时我也图省事让所有子Agent完整返回日志结果主控上下文很快就塞满了冗余调试信息。后来强制规定每个Agent的返回字段只有两条——“完成状态”和“结果摘要”上下文体积一下子小了一半以上。7.4 上下文管理与评测用一套测试集持续度量最后分享一个容易被忽略但极其重要的经验上下文管理要可评测。很多团队改完上下文管理方案的逻辑只靠几个手工样例验证一下就觉得OK了这是大忌。我做项目时一定会在早期构建一个上下文评测集包含至少上百个模拟对话场景覆盖多轮连贯、话题切换、长距离依赖、矛盾信息更新、长文档检索等典型情况。每次改动上下文管理逻辑后都跑一遍评测集看回答准确率、上下文命中率、Token平均消耗等指标变化。这个习惯帮我避开了不少“看似优化实则退化”的改动。很多时候你以为自己加了更复杂的上下文逻辑系统会更好评测数据却告诉你它负优化了。没有数据帮你兜底就只能靠玄学调参。8. 关于上下文管理我个人还在践行的几条心得上下文管理做得越久越觉得它不只是技术层面的问题而是对整个AI应用架构观的重塑。每次看到有人兴致勃勃地说“我们模型窗口很大不用做上下文管理”我都觉得他们大概率还没经历过生产环境的毒打。窗口大只能降低管理频率不能抵消管理的必要性——因为Token成本、响应延迟、注意力稀释、信息版本冲突这些问题不会因为窗口变大而消失。我个人把上下文管理的能力归纳为四个层面能控制控制Token在预算内、能筛选筛选值得进入窗口的信息、能演化能随着对话动态更新记忆、能度量能持续评估方案效果。这四个层面越往后越困难也越是拉开普通应用与顶尖应用差距的地方。如果你正在从零搭建一个基于大模型的应用我建议你从最朴素的滑动窗口开始不要一上来就上高深的RAG和多级记忆。把基础的对话流跑通用真实数据看看出现什么样的上下文问题再逐步引入摘要、检索和结构化管理。上下文管理是演进式的工程不是一步到位的方案。最后再分享一个小技巧也是我每次做架构评审时都会提的在Prompt里用角色名称暗示上下文中的信息性质。比如用“知识库参考”而不是直接丢进System或User里用“历史摘要”而不是跟在User问题后面。这不仅仅是为了模型理解更是为了可观测和可调试。当你需要排查问题的时候清晰的角色结构能让你一眼定位是哪一段上下文出了状况。这个习惯替我省下过数不清的排查时间。
阅读完成 · 觉得有帮助?