Appearance
一、上下文压缩在解决什么问题
上下文压缩是在解决三个问题
- 控制输入长度和推理成本
- 提高当前轮的相关性,让模型看到真正有用的信息
- 避免过期信息,重复信息和无关信息干扰当前判断
长上下文不一定等于高质量上下文,历史轮次多了之后,系统通常会同时混入几类噪音
- 已经被覆盖的旧需求
- 重复确认的信息
- 与当前任务无关的对话
- 模型之前自己生成但是后来已经无效的中间结果
事实上,不同的agent理论上应该采用不同的策略
在任务型Agent里,这些噪音尤其致命,因为系统不是在陪聊,而是在逐步完成一个任务
LangGraph的Graph API明确把State当作应用当前快照,nodes消费state决定下一步行为
在开放聊天场景里,保留大量历史可能只是带来一点冗余,但是在任务型的agent里,错误的上下文会直接把流程带偏
比如用户前面说看销售额,后面改成不要销售额,改看利润,如果只是简单的拼凑原文,没有压缩和更新机制,就很容易同时看到销售额和利润,最后输出不稳定
二、为什么把历史全塞进prompt不是好方案
- 相关性会快速下降
- 如果一个系统把所有历史消息原样放进去prompt,越往后,真正和当前轮强相关的信息占比就越低,模型不知道哪些历史是已经作废的旧需求,哪些是当前必须遵守的约束,除非额外设计结构和优先级
- LangChain的messages模型虽然支持系统消息、人类消息、AI消息等不同角色,但如果只是线性堆叠,它并不会自动帮你完成任务级别的压缩和筛选
- 时延和成本会持续上升
- 上下文失控会直接放大调试难度,官方文档里,LangGaph把durable execution,debugging,stateful agent左右核心能力之一,恰恰说明复杂Agent系统需要显示管理状态,而不是把所有信息都藏进一长段提示词里
- 旧信息会污染当前决策
三、上下文压缩常见做法
- 截断式压缩:只保留最近N轮
- 比如系统只保留最近3轮、5轮、10轮,把更早的消息直接丢掉
- 优点是实现简单、可控
- 缺点也比较明显,一旦轮次里仍存在有效的关键信息,系统就可能忘掉它
- 摘要式压缩:把历史写成一段summary
- 第二种方式就是让模型把前面多轮历史总结成一段摘要,再把这段摘要作为后续prompt的一部分
- 但是有一些问题
- 摘要本身可能丢失字段
- 摘要语言往往偏概括,不适合后续节点直接消费
- 如果摘要错了或者偏了,后面所有的节点都可能被错的summary污染
- 所以摘要压缩适合“需要保留长期上下文主线”的场景
- 结构化压缩:把历史沉淀成任务状态
- 尤其适合任务型agent
- 不是总结聊天,而是保留对当前任务真正长期有效的信息
- 比如在智能工坊场景里,对用户主题、指标、维度、页面风格、大纲、布局约束等
- 这些信息以字段形式存在,后续节点就不用从原始聊天记录猜,对于任务型Agent,结构化的压缩比自然语言摘要更符合执行逻辑
- 混合式压缩:最近几轮+结构化+摘要
- 真实工程里,最好用的通常是混合方案
- 保留最近几轮原始消息,维持短期语义连续
- 把长期有效的信息沉淀成state
- 对特别长但是可能还有价值的历史,补成摘要
四、为什么任务型Agent更适合状态压缩而不是聊天摘要
- 聊天系统关心语义的连续性,任务系统更关心可执行状态
- 状态压缩更容易做冲突更新
- 多轮任务中,用户经常会修改条件
- 把上下文抽成字段,就能明确做更新策略
如果要做一个更现实的方案,可以按三层设计
- 第一层,保留最近几轮原始信息
- 这层主要是保留短期语义连续性
- 比如用户说的修正、补充、否定, 可以解决当前轮和上一两轮的衔接问题
- 第二层,结构化任务状态
- 这层是核心,把长期有效且会被后续消费的消息沉淀成字段,比如
- 指标、维度、意图、布局等
- 这层是核心,把长期有效且会被后续消费的消息沉淀成字段,比如
- 第三层,历史摘要
- 有些用户会先解释业务场景,再细化多轮需求,这种时候一段简明背景摘要是有价值的