资讯动态

大模型应用中的上下文管理模式:从全量直传到结构化状态

发布时间:2026/10/20 12:44:14 来源:尧图企业网站定制
1. context-mode 到底是什么从一次失控的AI对话说起几个月前同事A找我帮忙调试一个他负责的客服助手项目。核心功能很简单接入一个大模型让用户连续提问助手基于对话历史给出回答。最初几轮交互非常顺畅但聊到第15轮左右模型开始失忆用户半小时前刚报过订单号它转眼就反问请问您的订单号是多少再往后更离谱它会把用户说过的话当成自己说的甚至开始编造根本不存在的会话内容。排查到最后问题出在一个几乎所有人都会忽略的地方——我们根本没有对发送给模型的上下文做任何管理只是把整段对话记录像滚雪球一样越攒越长一股脑塞给模型。而模型接口对请求有Token长度上限超出的部分会被静默截断。截断发生在哪个位置、截掉了哪些关键信息调用方一无所知。那次调试让我意识到一个此前被严重低估的问题大模型应用能不能稳定工作很多时候不取决于模型本身而是取决于你以什么方式、什么策略把上下文喂给它。这套策略就是我今天想认真聊一聊的context-mode。所谓context-mode通俗点说就是上下文管理模式。它是一套工程策略的总称核心回答三个问题哪些历史信息需要传给模型以什么形态传传多久就该退休别小看这三个问题它们直接决定了对话的连贯性、Token成本、响应速度还有模型会不会一本正经地胡说八道。我见过太多团队把精力全部花在Prompt模板和模型选型上却对上下文管理毫无概念。上线一段时间后用户量一大各种诡异问题就冒出来了答复质量突然下降、账单里的Token费用成倍上涨、有些人反馈越聊越蠢。这些问题九成以上根子都在上下文模式设计不合理。如果你也在做大模型相关的应用不管是个聊天机器人、文档问答工具还是带记忆的智能体这篇文章都会有些参考价值。我会从模式分类、取舍逻辑、代码实现到实测踩坑把我在实际项目里积累的经验尽量完整地讲清楚。2. 五种常见上下文模式的适用边界别再只会全量拼接了很多初学者以为上下文管理就是把聊天记录原样带上这也是最朴素、最直觉的做法。真正深入进去之后你会发现不同的业务场景对过去的信息要求完全不同没有任何一种模式能通吃所有需求。下面这五种模式是我在项目里实际用过或者仔细权衡过的它们各有严格的适用边界。2.1 全量直传模式只适合短会话全量直传就是不做任何加工把从第一句话开始的所有消息原样发给模型。它最接近人类对话的直觉实现也最简单一个数组不断push就可以。但它有一个天然的天花板Token上限。我拿实际数据算过一笔账。按现在主流模型动辄几万Token的上下文窗口来看似乎能撑很久但你要知道中文一个字大约对应1到2个Token一段20轮的客服对话光历史消息就很容易突破一万Token。再加上系统Prompt、工具定义、中间检索结果窗口很快就会见底。一旦触顶接口直接把最前面的消息截掉模型就忘事了。所以全量直传模式只适合一个场景单次会话很短比如表单类交互、一次性指令执行或者你能保证对话轮次不超过个位数。如果业务允许对话很长还坚持用全量直传你就等于把用户体验交给了截断位置纯属开盲盒。2.2 滑动窗口模式折中的默认选项滑动窗口是目前最常用的模式思路很简单只保留最近N轮对话更早的内容直接丢掉。它比全量直传省Token也比后面要讲的摘要压缩更省事。具体N值怎么定我的经验是不要拍脑袋要看你的业务最近几轮之内必须记住什么。比如一个售后客服用户报了订单号之后可能隔很多轮才会再次提到订单号那N就不能太小否则中间插播了几轮无关闲聊订单号就被挤出去了。我自己常用的起点是20到30轮然后通过压力测试逐步缩小砍到用户体验还能接受的极限。滑动窗口还有个变体值得提一下按消息条数滑动之外也可以按Token总量滑动即设定一个预算比如6000 Token超过就从旧消息开始删。按Token滑动更精准因为消息长短差异很大一条长文档可能顶几十条短消息。实现上也不复杂维护一个消息列表估算Token超出就从头部弹出。这个方法我已经在项目里替换掉按条数滑动了效果更稳定。2.3 摘要压缩模式让模型读旧消息后写笔记如果对话确实很长而且早期信息在未来随时可能被翻出来比如项目需求讨论、法律咨询、医疗问诊滑动窗口就撑不住了。这时候需要摘要压缩定期把较早的对话交给模型总结保留核心事实替换掉原始消息。我的做法是设置一个阈值比如窗口满了之后先把最老的30%消息送去做一次摘要摘要结果作为一条独立消息留在上下文里原始消息删除。摘要结构也有讲究不能让它自由发挥我会这样约束模型输出请将以下对话梳理成结构化笔记必须包含 1. 已确认的事实如订单号、日期、金额、决策结论 2. 用户的明确偏好或要求 3. 当前进行中的待办事项或问题 4. 尚未解决的分歧点这么做的好处是模型在未来任何一轮都能基于这份结构化笔记想起来早期对话的关键内容。坏处也很明显摘要过程本身要消耗Token而且有一定概率丢信息极端情况下摘要还会产生幻觉。所以我对摘要压缩有一个铁律摘要不允许参与连续压缩。也就是说你只能对原始对话生成摘要不能让摘要再被二次摘要。连续压缩的信息衰减是指数级的试过一次第三次压缩之后连用户的姓名都会写错。2.4 向量检索模式知识库问答的正解如果对话的历史不是一次会话内的上下文而是一个巨大的知识库、文档集摘要压缩也搞不定。这时候要用向量检索模式也就是大家常说的RAG检索增强生成。它的思路是把文档切块、向量化存进向量数据库。用户每次提问时先在库里检索出与问题最相关的几个段落只把这些段落拼进上下文给模型。它的本质是用检索代替记忆模型不需要记住所有知识只需要学会看被检索出来的那一小块材料。向量检索模式最容易翻车的地方不是向量化本身而是检索结果和当前问题是否真的对齐。我自己写过不少调优笔记后面会专门讲这里先给结论检索相似度阈值必须调而且要按业务类型分开调切片大小也很关键切太碎了上下文不完整切太大了噪声多我默认从256到512个Token这个区间开始试。2.5 结构化状态模式智能体工作流的最优解最后一种模式是处理多轮任务型对话Agent时我最推荐的在上下文之外维护一份独立的状态数据它平时不直接发给模型只在需要时以特定格式注入。举个例子。一个订餐智能体需要记录用户已经选了哪些菜、下单没下单、当前处于哪个环节。这些数据如果全部靠对话文本隐式传递模型很容理解错更稳的做法是维护一个JSON对象{ step: 选择配送时间, cart: [ {name: 西红柿炒蛋, qty: 1, price: 22}, {name: 米饭, qty: 2, price: 3} ], address_confirmed: false }每轮对话结束后根据模型的输出更新这个JSON。下一轮需要用时把它序列化成一段当前状态文本放入上下文。这样模型不是在连续对话中猜当前状态而是每次都被明确告知出错率会大幅下降。这五种模式不是互斥的。实际上成熟项目里往往是它们组合使用系统指令加结构化状态最近几轮用滑动窗口再早一点的对话走摘要压缩偶尔需要查外部资料时注入向量检索结果。模式之间如何配合后面我会给出一个具体的实现框架。上下文模式核心思路适合场景主要缺点全量直传不做处理全部发送超短交互、单轮任务受Token上限钳制滑动窗口只保留最近N轮连续对话、客服问答旧信息彻底丢失摘要压缩旧对话生成结构化笔记长会话、事实密集场景摘要消耗Token且有损向量检索检索相关内容片段注入知识库问答、文档分析检索质量直接影响回答结构化状态独立维护状态数据多步骤任务、智能体需要额外设计状态模型3. 一套可落地的上下文管理器核心实现与选型逻辑光理解模式还不够关键是怎么落地。我之前重构同事A的项目时把各种上下文策略收拢成一个独立的上下文管理模块所有模型调用统一走这个模块效果非常明显。下面贴核心设计这个方案也在模拟项目X里沿用至今。3.1 统一的消息表示与Token估算第一步把消息抽象成统一结构。不管来自哪家模型服务商消息无非就是role加content再加一个可选的附加信息。我定义这样一个数据类from dataclasses import dataclass, field from typing import Optional, List, Dict, Any dataclass class ContextMessage: role: str # system / user / assistant / tool content: str meta: Dict[str, Any] field(default_factorydict) # meta 里可存时间戳、来自哪个业务模块、是否属于摘要块等为什么重视这个metadata字段因为后面做滑动、做摘要、做状态注入时都要靠它来判断一条消息是不是老资格、能不能被压缩、属于哪个子任务。很多团队忽略这一步后面做策略的时候就会很别扭。Token估算我推荐不要自己琢磨规则直接用模型服务商提供的tokenizer或者开源分词工具。估算精度会影响滑动窗口的截断是否准确误差太大会导致实际请求超限。下面是简化版的估算函数_model_tokenizer None def count_tokens(text: str) - int: global _model_tokenizer if _model_tokenizer is None: # 实际项目中请在启动时加载一次避免每次调用都初始化 _model_tokenizer load_tokenizer(your-model-tokenizer) return len(_model_tokenizer.encode(text)) def estimate_message_tokens(msg: ContextMessage) - int: return count_tokens(msg.content) 4 # 每条消息的role标记开销3.2 策略选择的判断流程有了消息结构接下来是核心一个ContextManager按配置选择当前该套用什么策略。这里我特别强调按配置选择而不是写死一种因为同一个产品里不同业务模块的上下文需求完全不一样。搜索助手可能只要滑动窗口就够了深度咨询类的功能则必须摘要压缩。我实现了一个简单的策略注册与分发机制class ContextModeStrategy: def build_messages(self, messages: List[ContextMessage], state: Optional[Dict[str, Any]]) - List[ContextMessage]: raise NotImplementedError class SlidingWindowStrategy(ContextModeStrategy): def __init__(self, max_messages: int 24): self.max_messages max_messages def build_messages(self, messages, stateNone): # 系统消息永远保留其他只保留最近max_messages条 system_msgs [m for m in messages if m.role system] body_msgs [m for m in messages if m.role ! system] return system_msgs body_msgs[-self.max_messages:] class SummaryCompressionStrategy(ContextModeStrategy): def __init__(self, summarize_batch: int 60): self.summarize_batch summarize_batch def build_messages(self, messages, stateNone): if len(messages) self.summarize_batch: return messages # 前一批交给大模型做结构化摘要代码略 return messages然后ContextManager根据配置决定用哪个策略class ContextManager: def __init__(self, mode: str, **kwargs): registry { full: FullContextStrategy, sliding: SlidingWindowStrategy, summary: SummaryCompressionStrategy, rag: RagContextStrategy, stateful: StatefulContextStrategy, } self.strategy registry[mode](**kwargs) def build(self, messages, stateNone): return self.strategy.build_messages(messages, state)这套设计很简单但它把业务代码和上下文管理彻底解耦了。业务方每次调用只需要维护自己的原始消息序列至于怎么裁剪、怎么压缩、怎么检索全部交给ContextManager。后续想调整窗口大小、换压缩策略也只需要改配置不需要动业务代码。3.3 组合模式的实现把窗口、摘要和状态一起用真实项目里很少只用单一策略。以我常用的客服助手完整方案为例它的优先级是这样的系统提示词固定保留定义助手身份与回复纪律结构化状态优先注入比如用户订单号、当前售后阶段、工单编号最近12轮对话原样保留保证即时互动顺畅12轮之前的历史走摘要压缩只保留事实笔记如果用户问题触发知识库检索再把Top3检索片段追加进来。组合执行的时候注意顺序摘要什么时候触发我建议不要每次请求都重算摘要而是给摘要设置懒更新。比如每新增20条消息才检查一次是否需要把旧对话合并压缩两次摘要之间所有消息先进入滑动窗口缓存。这样可以避免频繁调用模型做摘要省下大量Token。class HybridContextManager: def __init__( self, recent_window: int 12, summarize_interval: int 20, retrieverNone, ): self.recent_window recent_window self.summarize_interval summarize_interval self.retriever retriever self.summary_cache None self.last_summarized_index 0 def build(self, messages, stateNone): # 1. 系统消息 system_msgs [m for m in messages if m.role system] # 2. 结构化状态注入 state_msgs [] if state: state_text 当前任务状态(结构化数据请严格据此理解用户进度)\n state_text json.dumps(state, ensure_asciiFalse, indent2) state_msgs.append(ContextMessage(rolesystem, contentstate_text)) # 3. 旧消息检查是否需要摘要 if len(messages) - self.last_summarized_index self.summarize_interval: self.summary_cache self._summarize_old_messages(messages) self.last_summarized_index len(messages) # 4. 最近窗口 摘要 检索片段 recent_msgs messages[-self.recent_window:] result system_msgs state_msgs if self.summary_cache: result.append(ContextMessage(rolesystem, contentself.summary_cache)) if self.retriever: # 从当前用户问题中检索外部资料这里假设接口返回文本列表 user_text messages[-1].content fragments self.retriever.retrieve(user_text, top_k3) if fragments: rag_block 检索到的相关资料片段\n \n---\n.join(fragments) result.append(ContextMessage(rolesystem, contentrag_block)) result.extend(recent_msgs) return result这套混合模式的代码量不大但工程上解决了我遇到过的大多数上下文失控问题。我在几个不同的业务场景里都用过同一套骨架差别只在参数上客服场景窗口放小一点摘要触发更勤快一些文档问答场景窗口无所谓检索器才是主角复杂经办类场景则完全依赖状态注入窗口甚至可以砍到4轮以内。3.4 持久化与会话恢复还有一个容易漏掉的环节用户关掉页面再回来上下文怎么恢复我的做法是把压缩后的摘要和最后一次结构化状态存进数据库原始消息按需保留最近若干轮。用户回头继续对话时不需要加载完整历史只需要把摘要状态恢复到上下文里。def persist_session(self, session_id, messages, state): record { summary: self.summary_cache, state: state, recent: messages[-self.recent_window:], updated_at: time.time(), } storage.save(session_id, record) def restore_session(self, session_id): record storage.load(session_id) messages [ContextMessage(rolesystem, contentrecord[summary])] messages record[recent] return messages, record[state]这里有个细节恢复会话后原来的临时消息顺序会变摘要块变成了一条system消息紧跟着就是最近对话。模型能不能理解这个结构能但要配合一句引导比如在摘要前面加上以下是该用户更早对话的结构化纪要如果问题涉及具体事实优先参考纪要内容。不加这句模型偶尔会把摘要内容当成当前系统指令来执行尤其是摘要里如果出现了你需要这类字眼就有被误解的风险。我踩过这个坑后来统一对摘要文本做了转述处理让它只能陈述事实不能带指令语气。4. 模式切换与参数选择实测数据告诉我这样选说完了实现再聊聊选择和调参。这一节的内容全是实测数据不是拍脑袋的经验。4.1 三类场景下的模式选型实测对比我在模拟项目X里测了三类场景短对话客服、长周期项目助手、知识库问答。每个场景分别跑五种模式记录三个指标回答准确率、单轮平均Token消耗、端到端响应时长。测试样本是800条用户问题答案与人工标注比对。场景全量直传滑动窗口摘要压缩向量检索结构化状态短对话客服(≤8轮)准确率91%成本低准确率92%成本低不必要不必要略复杂长周期项目助手(≥50轮)超限报错准确率68%旧信息丢失严重准确率84%成本适中适合知识引用准确率高但需设计状态知识库问答超限报错不适用不可行知识量太大准确率87%成本最低不适合最醒目的一条数据是长周期项目助手下滑动窗口的准确率只有68%而摘要压缩能拉到84%。差距来自哪里我逐条看了错误样本滑动窗口模式几乎都是因为早期信息被挤掉用户第五轮提过一个约束条件第二十轮问按我之前说的条件现在怎么办模型完全不知道那个条件自然答不对。摘要压缩模式则能稳稳抓住这些早期事实。4.2 滑动窗口的窗口大小怎么定一个可复用的实验方法很多读者看完前面会问窗口大小到底设多少我没有统一答案但有一个可复用的实验方法。先取你业务中典型的对话样本建议50条以上交给模型跑一轮人工标出哪些回答依赖了较早的信息记下最早的信息出现在第几轮。然后把这个距离作为窗口下限的参考。举例来说样本里有一条典型对话用户在第2轮报了一个收货地址第19轮问地址我还能改吗模型答对的基础是记得第2轮地址。这条依赖距离就是17轮。统计所有样本取85分位数假设是18轮那窗口至少得设18轮以上。再考虑到模型自身注意力对远距离信息的弱化我习惯把85分位数的1.5倍作为初始窗口即27轮。线上跑起来后再逐步调低每砍一档就抽一批对话做回归评估直到准确率明显下滑再退回上一档。这个方法最大的价值是把拍脑袋变成数据驱动。我见过有人把窗口从20调到200理由仅仅是让模型记忆好一点结果Token费用翻了五倍准确率几乎没有变化。为什么因为业务里真正需要跨很远距离记忆的信息其实很少80%的信息都被用户在最近几轮内以各种方式重复过了。把窗口拉到巨大只会浪费预算。4.3 摘要压缩的触发时机懒更新优于每次更新摘要压缩最常见的两个参数是多少轮触发一次和摘要保留到什么粒度。我先说触发时机。最笨的做法是每次请求前都重新对所有历史做一次摘要这在Token消耗上是灾难级别的。假设一段200轮对话每轮摘要一次等于每次请求都额外烧掉几千Token模型调用成本直接翻倍。我推荐的懒更新策略在前面代码里已经体现设置一个增量阈值比如超过20轮新消息才触发一次摘要计算摘要本身也只针对上次摘要之后新增的段落以及上一份摘要中因新对话而过时的部分。这样大部分请求完全不需要额外调用模型做摘要。有个词叫摘要漂移指的是随着对话推进摘要内容慢慢和真实对话不一致。懒更新拉长了摘要计算间隔漂移会更明显。我的缓解办法是每次触发新摘要时不只增量合并还把最近几轮的关键事实拿出来和新摘要做一致性校验。这个校验也消耗Token但它只针对高价值会话比如售后工单、法律问询这类不能出错的长对话性价比很高。4.4 向量检索模式的调参细节分块与阈值向量检索模式的调参核心在两块文本如何分块检索阈值怎么定。分块我试过512、256、128三种粒度结论是要看你的内容是什么。问答型文档比如FAQ、产品说明128到256的分块效果最好因为每个块刚好能覆盖一个完整语义单元长文分析比如研究报告、合同条款我反而建议512以上因为太碎会把论证逻辑切断。判断标准也简单看切出来的块能不能独立回答一个完整问题。如果一个问题的答案横跨两个块就说明切小了。相似度阈值我也给一组实测参考。用余弦相似度的话0.7到0.75这个区间比较适合开放域问答低于这个门槛的检索结果塞进上下文模型很容易被无关信息带偏回答从不知道变成乱说。垂直领域、问题高度模式化的时候阈值可以抬到0.8以上。我见过一个项目阈值设成0.5结果每条问题都检索出一堆不相关内容模型每轮都在答非所问最初的根因就这么简单。4.5 结构化状态模式的状态设计原则最后补充一点结构化状态模式的经验。状态模型怎么设计直接决定任务型智能体的上限。我的原则只有一条状态要反映业务当前走到哪一步而不是对话聊到哪里。区别在哪前者用字段表达业务进度比如payment_status: pending后者则是一句描述比如用户说他想付款。模型对字段型状态的把握能力远超对自然语言描述的把握因为字段值是确定的、可枚举的而自然语言描述永远存在歧义空间。另外状态更新不要依赖模型自己自觉要写明确的更新指令。每次模型输出后我都会追加一个轻量级解析流程把模型输出映射到状态JSON。这个过程最简单的方式是用一个独立的小模型提示完成也可以让同一个模型输出两种内容一段给用户的回复一段结构化的状态更新。后者省事但测试起来要小心模型偶尔会把状态更新写成空值需要加上兜底校验。def parse_state_update(model_output: str, current_state: dict) - dict: # 期望model_output里附带json片段: {state_update: {...}} # 解析失败时返回原状态保证不会因为解析错误弄丢状态 try: fragment extract_json_fragment(model_output) if state_update not in fragment: return current_state updated current_state.copy() updated.update(fragment[state_update]) return updated except Exception: return current_state这段兜底逻辑的价值在于即使模型某轮没有正确输出状态更新整个流程也不会崩最多是状态滞后一轮比状态被清空好得多。5. 避坑实录上下文管理的五个典型翻车场景最后分享五个我在实际开发中踩过的坑每一个都在生产环境里真实发生过希望你不用再走一遍。5.1 截断位置导致语义断裂修好了以为万事大吉最早用全量直传时我以为把超长消息列表交给SDKSDK会自动处理截断。结果某次合同文本问答用户上传的合同本身就超过窗口上限SDK从中间截断模型读到的合同缺了最关键的价格条款然后信心满满地给出一个错误报价。教训不要依赖SDK的默认截断行为一定要自己在代码里控制裁剪逻辑。滑动窗口按消息条数滑动时一条超长消息本身就可能撑爆窗口所以我这套实现里对消息设置了单条Token上限超长内容在进入上下文前先做切片或摘要绝不把巨无霸消息原样塞进列表。5.2 摘要压缩丢失关键实体我自己复现的人名消失事故曾经做过一个咨询类应用对话很长实体很多。有一次线上反馈模型不再称呼用户的姓所有回复都变成您。排查后发现摘要压缩的约束里明确写了要抽取关键实体但模型做摘要时偶尔会把李先生漏掉。摘要一旦生成原始消息又被删掉这个信息就再也回不来了。修复方案有两层一层是给摘要增加可验证步骤让模型输出摘要时必须带一个实体清单字段所有出现在原对话中的人名、订单号、地址必须保留另一层是摘要不真正删除原始消息而是把原始消息移到冷存储留着做人工校验和错误回溯。后者让我在处理线上投诉时轻松许多否则摘要出错的会话根本没法查。5.3 混合模式切换后上下文错位用户被重置了第三个坑来自模式动态切换。我之前设计了一个规则对话轮次少时走全量直传轮次多时自动切到摘要压缩。听起来很合理但实际跑起来切换的那一瞬间模型视角发生了剧烈变化——上一轮它还看得到20条历史消息这一轮突然只剩一段摘要加最近几条。结果就是模型在切换后回答得格外保守频繁反问请问您刚才说的是用户觉得这个客服突然变傻了。后来我改成模式只做动静切换切换前利用空闲时间提前生成摘要并保留至少5轮过渡期过渡期内新旧两种表示同时存在让模型平滑降落。这个改动把模式切换带来的用户体验下降降低了近一半。5.4 并发会话的上下文串扰最隐蔽的Bug这个坑比较深。我一度把上下文对象缓存在单例里同一个ContextManager实例被多个会话共用。理论上代码里传了session_id但有一处异步任务忘了从请求上下文获取自己的session把会话A的指针和会话B的状态对象混在一起了。结果用户A的提问被拼上了用户B的记忆模型一本正经地拿着B的订单号回答A的问题。生产环境里这种串扰特别难发现因为它不是必现的只在两个会话恰好同时触发异步任务时出现而且错误内容看起来很像模型幻觉。排查了很久才靠日志里多打印session_id定位到。教训**上下文数据命周期必须与会话严格绑定任何缓存都必须在键里带上session_id绝不允许在实例字段里保存当前会话的上下文。**这点我之前在架构分享时反复提过但在同事A的项目里还是中了招可见有多容易复发。5.5 上下文无限膨胀后的性能雪崩最后一个是性能问题。系统刚上线时我把整个上下文塞进内存对象每个会话结束时也不清理。用户量一上来内存占用线性上涨GC频率飙升接口响应越来越慢。更麻烦的是每次请求构建上下文时要遍历整条历史消息即使用滑动窗口只取最近20条构建前也要先把所有消息读出来白白拖慢了延迟。修复方案是分等级存储最近20轮消息放热内存20轮之前放冷数据库上下文管理器按需拉取构建消息时走一次热数据优先冷数据按需加载的流程。这个改造带来的收益很直观同样一批业务流量P95响应时间从2.1秒降到了1.2秒左右内存占用也稳住了。6. 从项目实战中沉淀的几条原则写到最后把我在各个项目里反复验证过的几条原则列一下算是个人的经验沉淀。第一条上下文不是越大越好够用就行。多加一万Token的历史消息并不会让模型变得更聪明反而会增加成本和延迟。学会做减法优先级永远是把当前轮最需要的信息以最清晰的形式呈现给模型。第二条任何上下文策略都必须有可观测性。我要求每次构建完上下文都打印一条日志当前策略模式、窗口条数、摘要块Token数、检索片段数、最近一条消息的时间戳。有了这些日志线上问题才能回溯才不会出现看着像模型问题、其实是上下文没拼对的谜案。第三条所有信息压缩手段都有损必须允许人工兜底。摘要可以丢实体检索可以漏片段状态可以解析错。设计时要假设这些环节都可能出错那就一定要保留原始数据落盘这样既方便追踪也能支持人工介入修正。第四条从最简单的模式做起用数据驱动演进。不要一开始就上混合模式、状态机那套复杂架构。先全量直传短会话够用就别折腾等业务确实出现了长对话、跨会话记忆、知识库问答的需求再逐个引入滑动窗口、摘要压缩、向量检索。每一步调整都做A/B验证用准确率、Token成本、用户满意度三个指标说话。我的经验是90%的应用其实只需要滑动窗口加一个简单的结构化状态注入搞得太花哨维护成本很快会反噬。最后再说一件小事。我后来回访同事A他那个客服助手上线三个月后随机抽了100条对话做人工质检发现上下文管理改造前后的差异非常明显改造前有22条对话出现了关键信息丢失类错误改造后剩下4条而且这4条都是因为用户上传了超大附件导致的消息分块问题属于另一类需要单独优化的场景。他跟我说了一句话我印象很深原来模型一直没变变得只是我们喂它的方式。这句话大概就是context-mode这门手艺最好的注解。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑