跳转到主要内容

那个‘总结’掉用户原始提问的压缩策略

阅读需 1 分钟Tian PanTian Pan

一位用户询问我们的支持智能体:“为什么发票 INV-2025-08-44719 在 4 月 3 日被扣了两次款?”45 分钟和 18 次工具调用之后,智能体自信地回复道:该账户在该季度没有任何重复计费的证据。用户理所当然地投诉了。当我们回放追踪记录(trace)时,答案变得显而易见。智能体在第九轮对话时对内容进行了压缩(compacted)。摘要显示用户“在询问 4 月初的一笔重复收费”。其中并不包含字符串 “INV-2025-08-44719”。随后的每一次工具调用——账本查询、退款 API 查询、审计日志扫描——都是针对转述后的意图发出的,而不是用户输入的字面意义上的发票编号。

Bug 不在工具里,也不在模型的推理中。问题在于我们的上下文管理器(context manager)与每个下游组件之间都有一个契约,但没有人把它写下来。契约写着:“我会保留语义。”而组件需要的是:“我会保留字符串。”

这是自动摘要在生产环境智能体中不断产生的失效模式,它比那些更出名的压缩失败案例更具隐蔽性。我们经常听到摘要丢失了重要事实或压缩掉了推理步骤。我们较少听到的是,摘要保留了所有事实,完美地维持了对话脉络,却悄悄地改变了确定性下游查询所依赖的精确表述。智能体并不会感到困惑,它只是充满自信地搜索了错误的字符串。

压缩悄然破坏的两个契约

大多数压缩策略都是隐含地围绕一个假设设计的:在智能体上下文中流动的是语义,而语义是需要保留的东西。摘要捕捉意图,智能体根据意图进行推理,工具为推理服务。压缩语义,不会丢失任何重要的东西。当上下文管理器下游的每个组件本身都是 LLM 时,这个模型运作良好,因为 LLM 对转述(paraphrase)具有鲁棒性。模型可以读取“询问 4 月初的重复收费”并生成一个形状大致正确的查询。

但只要管道中的任何组件执行字面查询——例如 SQL 的 WHERE invoice_id =、哈希表查找、正则表达式匹配、针对 BM25 索引的精确字符串向量检索、Webhook 签名验证、幂等键(idempotency-key)检查——该组件与上下文之间就有了不同的契约。它不需要语义,它需要用户输入的精确字符。而在摘要提示词中,没有任何内容告诉摘要生成器哪些字符串是承载关键信息的。

这里实际上有两种契约在起作用,而且它们通常是未说明的:

  • 语义契约 (Semantic contract)。“我需要知道用户想要什么。”由规划器(planner)、路由逻辑、语气匹配以及任何消耗意图的组件持有。对转述具有鲁棒性。对摘要具有鲁棒性。
  • 词法契约 (Lexical contract)。“我需要用户提供的精确字节。”由每一个数据库查询、每一个具有固定 schema 的 API 调用、每一个缓存键、每一个指纹、每一个审计标识符持有。对转述非常脆弱。会被摘要摧毁。

灾难在于,词法契约在设计阶段是不可见的。绘制智能体架构图的架构师看到标有“摘要生成器”和“工具执行器”的方框,并假设摘要对两者来说都是足够好的输入。他们在后者上错了,而且只有当用户追问“你真的查看了发票 INV-2025-08-44719 吗?”时,他们才会发现问题——而由于发票编号仍不在上下文窗口中,智能体现在也无法回答这个问题。

为什么 Claude Code 和 Codex 在这里分道扬镳

这并不是一个假设性的区别。两个部署最广泛的编程智能体以截然相反的方式处理它,这种分歧很有启发性。Codex 在压缩过程中逐字保留了每一条用户消息。它会删除助手回复和工具消息,并用摘要替换它们,但原始的人类对话轮次被物理地保留在提示词(prompt)中。Claude Code 的 /compact 指令以及更广泛的 Anthropic 压缩 Beta 版默认会摘要化所有内容,包括用户轮次,并要求开发者传递明确的 instructions(指令)来保护特定类型的内容——如代码片段、文件路径、标识符。

Codex 的设计隐式地承认了词法契约:它假设用户输入的任何内容都可能对未来的工具调用具有承载作用,因此从不转述它。代价是 Token 效率。与爱聊天的用户进行的长时间对话会无限期地为每条原始消息付费。Anthropic 的设计则朝另一个方向优化:它假设开发者知道哪些字符串是神圣不可侵犯的,并会告知系统。这在表达能力上更强,但给可能尚未意识到这一负担的团队增加了配置负担。

两者都是合理的工程选择。但对于一个不是你自己构建的智能体来说,哪一个作为默认设置都不是完全正确的。如果你正在使用托管的压缩 API,并且拥有任何针对用户提供的值进行字面查询的工具,你需要假设摘要不会保留这些值,并且你需要设计一个单独的机制来处理。

会员专享

余下内容仅对会员开放。

会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。

  • 完整文章,包含未公开存档的部分
  • 可落地的工作框架,附带权衡与决策依据
  • 新文章抢先看,先于公开发布

随时取消 · 一次订阅,畅读全部

参考资料

保持联系,关注我获取更多内容

阅读需 9 分钟

长期运行 AI 智能体中的上下文毒化

长期运行的 AI 智能体中积累的上下文是如何默默地破坏推理能力的,导致该问题的四种故障模式,以及防止级联故障的检查点、剪裁和不变性检查模式。

insider
agents
阅读需 10 分钟

当用户取消对话后,下游 API 却仍在继续写入

点击停止按钮可以干净地关闭 LLM 流。但这并不会停止工具已经向第三方开启的 HTTP 请求,而第三方并不知道对话已经结束。本文将解释为什么 AbortSignal 止步于套接字,以及你应该在提交边界构建什么来替代它。

insider
agents
阅读需 10 分钟

配额窗口机制重写后,这批夜间脚本是如何拖垮你的交互流量的

一个夜间 LLM 批处理任务稳定运行了 10 个月,直到供应商重写了每日窗口的计算方式——将 00:05 UTC 的 Cron 任务变成了交互式流量的自杀式 429 异常。本文探讨为什么负载隔离、抖动和桶语义契约测试才是结构化的修复方案。

insider
rate-limits
阅读需 10 分钟

一路重试穿过你限流器的 agent

你的 token bucket 衡量的是用户点击;账单衡量的是模型调用。当一次点击扇出成三十次调用,HTTP 边界上的限流器就变成了一把纸糊的伞。

insider
agents
阅读需 9 分钟

供应商 SLA 差距:为什么你的 LLM 提供商的运行时间忽略了导致产品崩溃的故障模式

你的 LLM 供应商 99.95% 的运行时间指标并不能覆盖拒绝率飙升、静默模型更新或配额驱动的降级。以下是能够涵盖这些情况的功能可用性检测方法。

insider
llm-ops