Skip to content

上下文压缩

一、上下文压缩在解决什么问题

上下文压缩是在解决三个问题

  • 控制输入长度和推理成本
  • 提高当前轮的相关性,让模型看到真正有用的信息
  • 避免过期信息,重复信息和无关信息干扰当前判断

长上下文不一定等于高质量上下文,历史轮次多了之后,系统通常会同时混入几类噪音

  • 已经被覆盖的旧需求
  • 重复确认的信息
  • 与当前任务无关的对话
  • 模型之前自己生成但是后来已经无效的中间结果

事实上,不同的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更适合状态压缩而不是聊天摘要

  • 聊天系统关心语义的连续性,任务系统更关心可执行状态
  • 状态压缩更容易做冲突更新
    • 多轮任务中,用户经常会修改条件
    • 把上下文抽成字段,就能明确做更新策略

如果要做一个更现实的方案,可以按三层设计

  • 第一层,保留最近几轮原始信息
    • 这层主要是保留短期语义连续性
    • 比如用户说的修正、补充、否定, 可以解决当前轮和上一两轮的衔接问题
  • 第二层,结构化任务状态
    • 这层是核心,把长期有效且会被后续消费的消息沉淀成字段,比如
      • 指标、维度、意图、布局等
  • 第三层,历史摘要
    • 有些用户会先解释业务场景,再细化多轮需求,这种时候一段简明背景摘要是有价值的

最后更新于: