当 Chatbot 开始切换模型,为什么上下文压缩必须自己做?

在多模型成为标配之后,官方 compact 接口正在失去通用性。Chatbot 要跨模型继续长对话,就必须自己掌握上下文压缩和记忆管理。

多模型成为标配之后,一个原本可以交给厂商 API 的功能,正在变成 Chatbot 团队必须自研的基础设施。

据掘金开发者社区的一篇工程实践文章披露,某内部 Chatbot 团队在接入 Claude、Deepseek、Gemini、通义等多个模型后,放弃了原本依赖 OpenAI 官方 compact 接口的上下文压缩方案,转而自研一套跨模型可用的 /compact 机制。原因并不复杂:官方压缩能力往往只服务自家协议,一旦产品允许用户在不同模型之间切换,私有的压缩状态就无法继续传递。

这类问题并不只属于某一个产品。随着企业级 Chatbot、AI 助手和内部知识问答工具越来越普遍地采用多模型路由,长对话记忆、上下文压缩、以及厂商 API 边界,正在成为应用层必须正面处理的工程问题。

官方 compact 为什么在多模型场景里失效

在这支团队最初的实现中,用户输入 /compact 后,服务端会把当前会话消息交给模型网关,再调用 OpenAI 官方的 /v1/responses/compact 接口。返回结果中会包含一个 type 为 compaction 的加密块。按照 OpenAI 的要求,这个压缩块需要在下一轮请求中原样回传,且不能被应用层再次裁剪。

这一设计在单一模型环境下是成立的。只要用户始终使用 GPT 系列模型,官方 compact 可以帮助应用维持一个经过压缩、但仍可被模型理解的上下文窗口。

但问题出现在模型切换之后。

  • OpenAI 的 compact 机制绑定在 OpenAI Responses 协议之中;
  • Claude 的 compaction 同样属于 Anthropic Messages API 的私有状态;
  • 不同厂商对摘要块、签名信息和历史回放字段的定义并不一致;
  • 模型网关还可能把请求分发到不同的上游资源,导致上一轮的 itemId 在下一轮无法匹配。

换句话说,官方 compact 保留的,恰恰是跨模型场景下最难携带的部分。加密摘要对 Claude 没有意义,对 Gemini 也没有意义;即便用户仍然停留在 GPT 模型上,网关跨资源调度也可能让官方协议状态失效。

于是,原本用于降低上下文成本的压缩功能,变成了多模型产品中的一个断点。

Chatbot 需要的不是私有状态,而是可迁移的对话记忆

这支团队最终选择的方向,是不再依赖任何一家厂商的私有压缩协议,而是让所有模型共用同一套客户端压缩逻辑。

其核心思路是:压缩后的上下文必须是普通文本,而不是只有某一个厂商 API 才能理解的结构。

在具体实现上,/compact 会先对历史消息进行裁剪,再对较早的对话内容生成摘要,同时保留最近若干轮原始消息。压缩后的窗口由两部分组成:

  • 一条由当前模型生成的助手摘要消息;
  • 最近若干轮用户与助手的原始对话。

在默认配置中,系统会保留最近 8 条消息,约等于三到四轮对话;同时至少保留 1 条旧消息用于生成摘要,避免历史被近窗完全覆盖。若有效文本消息不足 4 条,系统则会提示没有足够内容可压缩。

这种设计更接近 LangChain 目前提供的 summarizationMiddleware 思路:旧上下文被压缩成一段文本表示,近期消息保持原样。相比简单滑动窗口,它能够保留此前已经确认过的信息;相比整段历史全部摘要,它又能避免最近几轮细节被过度压缩。

对于 Chatbot 产品来说,这种平衡很关键。用户执行 /compact 后,往往还会继续追问刚才提到的内容。如果系统把最近几轮也一并压成摘要,短期上下文虽然变小了,但连续对话体验会明显受损。

压缩不只是省 token,还涉及产品可见性

除了跨模型兼容,团队选择自研 compact 还有另一个原因:用户可见性。

在该产品中,/compact 是用户主动触发的指令,而不是后台自动执行的过程。用户能够看到压缩前后的窗口变化。如果直接使用厂商返回的加密 compaction 块,界面上很难展示究竟哪些内容被保留、哪些内容被压缩、哪些信息已经丢失。

这也是应用层压缩与厂商协议压缩之间的重要差异。

厂商 API 更关心如何在自身模型体系内维持上下文连续性,而 Chatbot 产品还需要回答另外几个问题:

  • 用户能否理解压缩结果;
  • 压缩后的历史能否在界面上展示;
  • 切换模型后,新的模型能否直接理解这段历史;
  • 压缩失败时,是否应该保留原始对话。

因此,这套自研方案对失败处理也采取了更保守的策略。如果摘要调用为空,或者模型返回错误,系统不会静默替换历史,而是保留原始消息并将错误返回给界面。文章作者写道,压缩失败固然不好,但悄悄丢掉用户刚刚聊完的内容更糟。

多模型时代,应用层必须补上记忆管理这一课

从行业角度看,这类问题正在变得越来越普遍。

过去,许多 AI 应用默认只接入一个模型,长对话管理可以依赖厂商提供的基础设施。但随着模型选择越来越多,企业产品往往需要同时支持 OpenAI、Anthropic、Google、阿里通义、Deepseek 等多家模型,甚至根据任务类型、成本和可用性动态切换。

在这种架构下,模型网关解决的是请求路由和资源调度问题,但对话记忆、上下文压缩、历史可移植性,仍然属于应用层责任。

目前社区常见的长对话管理方式大致包括几类:滑动窗口、整段摘要、保留近窗加旧段摘要、向量记忆检索,以及依赖厂商私有 compact 协议。不同方案适用于不同场景。

滑动窗口实现简单,但容易丢掉早期关键约束;整段摘要成本低,但会损失最近几轮细节;向量记忆能力更强,但系统复杂度明显更高;厂商私有 compact 则受限于协议边界。

对于需要频繁切换模型的 Chatbot 来说,最稳妥的做法反而是生成一种所有模型都能读取的普通文本历史。它牺牲了一部分厂商协议内部的状态优势,却换来了跨模型可用性。

这也意味着,Chatbot 的上下文管理正在从单纯调用模型 API,演变为一种独立的工程能力。模型可以替换,提示词可以调整,但会话历史如何保存、压缩、回放和迁移,正在成为产品稳定性的一部分。

从这个角度看,/compact 不再只是一个聊天框里的斜杠指令,而是多模型应用必须面对的一道基础题。

原创文章,作者:点点,如若转载,请注明出处:https://www.dian8dian.com/dang-chatbot-kai-shi-qie-huan-mo-xing-wei-shen-me-shang-xia

Like (0)
点点的头像点点
Previous 1小时前
Next 2024年9月17日 下午10:00

相关推荐