2026-05-14 · 架构
32
架构 · 2026-05-14

Arize 怎么解决 Agent 的上下文管理:系统为什么会被 Context 拖垮

这篇文章讲的是一个很容易被低估、但几乎所有 Agent 产品都会撞上的问题:上下文管理。Sally-Ann Delucia 这场分享的价值很直接,她没有泛泛谈“长上下文很重要”,直接把团队在真实产品里踩过的坑讲清楚了,尤其是为什么截断不行、为什么总结也不稳,以及最后为什么留下来的是一套更克制的 context + memory + sub-agent 组合拳。

这场 talk 的标题很直接,How we solved Context Management in Agents。但我看完之后,更强烈的感受是:上下文管理别再被当成模型参数问题,它早就是产品问题、系统问题,也是评估问题。

很多团队做 Agent,前期最容易把注意力放在 prompt 上。system prompt 怎么写,tool description 怎么写,few-shot 怎么摆,语气是不是够稳,约束是不是够严。这些当然有用,但一旦 Agent 真的进入有状态、长对话、多工具、多数据源的环境里,prompt 很快就会从主角退到配角。

真正开始决定产品上限的,是 context。

Sally 这场分享最值钱的地方,是她把 Arize 团队怎么撞墙、怎么修、最后为什么改成现在这套做法,整个过程都讲得很实在。

一、Agent 失败,很多时候是因为它看到的东西已经错了

她上来就把一个判断说透了:现在大家讲 prompt engineering,已经不够了,真正重要的是 context engineering。

这个转变我很认同。

因为很多人对上下文的理解还停在“别超过 token limit”。但 context management 真正难的地方,根本不在于你有没有超限,而在于你到底给模型看了什么,又让它漏掉了什么。

这是两个完全不同的问题。

只要 Agent 开始处理真实工作流,这个问题马上就会变得很尖锐。用户输入会变,系统提示会变,工具调用结果会越来越长,历史对话会越来越厚,外部数据又会一层层叠进来。你表面上看,是“上下文越来越大”;往深一点看,其实是“上下文质量越来越不受控”。

模型不是因为上下文长就必然失败,很多时候它失败,是因为它在关键时刻看到的是错误的切片。重要的被冲掉了,次要的被保留了,真正该记住的状态已经在中间某一轮被挤没了。

也就是说,Agent 崩掉的根源,往往在于它拿到的上下文已经不值得推。

二、Arize 遇到的问题很典型,而且会越来越常见

他们做的 Alyx,本质上是一个帮助 AI 团队构建和分析 AI 应用的 agent harness。问题在于,它自己又运行在大量 trace 数据之上。

这个场景很有代表性,因为它会形成一个很恶心的闭环:

她把这个叫 vicious loop,我觉得非常准确。

这类循环不只会出现在 observability 产品里。凡是 Agent 要处理自己生成的记录、日志、工作轨迹、历史步骤、用户长会话,最后都会慢慢走到这个坑里。

这也是为什么她说,context management 不是纯工程问题,它已经是产品和 UX 问题。

因为用户不关心你内部怎么截断上下文,他只会关心一件事:为什么这个 agent 刚才还懂我,现在突然像失忆了一样?为什么刚才还能跟进,后面一追问就开始胡说?为什么一次复杂任务跑到一半,整套理解崩掉了?

这些体验层面的“怪”,背后大概率都是 context 失控,而不是 prompt 写得不够花。

三、第一种直觉解法,截断,为什么会失败

他们最先想到的方案非常自然:截断。

既然上下文太大,那就直接留前面一部分,比如前 100 个字符,后面的先丢掉。这个想法很像大家做系统时最先会下意识做的事,成本低,逻辑清晰,也容易立刻实现。

而且它一开始确实“看起来能跑”。

但这种方案很快就暴露问题了。对简单场景还凑合,一旦进入多轮交互,Agent 就开始像鱼一样失忆。前面还聊得好好的,用户一追问某个前文提过的东西,它就完全接不上。follow-up 在它那里会像一段全新对话,而不是上一轮的继续。

这个失败其实特别值得记。

因为它说明了一件很重要的事:上下文不是越短越稳,截掉的部分里,往往正藏着推理链需要接住的状态。

很多系统做优化时会默认“反正丢点旧信息问题不大”。但在 Agent 里,旧信息不是背景板,它经常就是当前任务还能不能继续成立的前提。

尤其当任务有连续依赖时,粗暴截断几乎等于主动破坏推理条件。

四、第二种直觉解法,总结,为什么听上去聪明,实际上不稳

截断不行,下一个自然想到的方案就是总结。

既然上下文太长,那能不能让 LLM 先把它压缩成一个更短的 summary,再把 summary 喂回去?

这个思路表面看很优雅。你既保留了“关键信息”,又节省了 token,看起来像是一个聪明人会做的办法。

但 Arize 团队的结论很直接:不稳定。

问题不在总结能不能做,在于一旦你把“什么重要”交给 LLM 自己决定,你就失去控制权了。

LLM 的 summary 当然可能大体靠谱,但它也可能在最要命的时候,保留了看起来像重点、其实对当前任务没用的东西,删掉了接下来真的要用的状态。更麻烦的是,这个错误不是每次都会发生,它是波动的、偶发的、很难稳定复现的。

这类问题在工程上特别烦。

因为“偶尔错”比“稳定错”更难修。稳定错你还能下规则,偶尔错往往意味着你把一个核心选择权交给了一个不受控的过程。

她的原话大意就是,summarization 听上去是 obvious solution,但太 inconsistent。这个判断我觉得很扎实。

很多团队一提 context compression,就自动想到 summarize。但如果你的系统对状态连续性要求高,对细节依赖深,对后续追问很敏感,那 summary 很可能会变成一层你以为在帮忙、其实在偷偷改写上下文语义的薄膜。

五、他们最后跑通的,是一套很朴素但更稳的策略

Arize 最后留下来的方案,其实没有那么花哨。

核心是三件事:

  1. 保留 head
  2. 保留 tail
  3. 中间部分进 memory store,需要时再取

也就是她说的 smart truncation + memory。

这个方案之所以值得抄,不是因为它听起来高级,恰恰相反,是因为它足够朴素,也足够克制。

它没有假装自己知道全部重要信息。它承认一个现实:当前窗口里,最有价值的通常是开头的任务设定和尾部的最新状态;中间那坨最厚的历史,不适合永远硬塞在主上下文里,但也不能真丢掉,所以把它挪进一个可检索 memory store,等 Agent 觉得有必要时再回来拿。

这里最重要的变化,不在“节省 token”,在于Agent 对上下文的取用权被重新设计了。

以前是系统替它决定,“这些你别看了”。
现在变成系统只帮它做结构化裁剪,但仍保留检索通道,让它在需要时自己回补。

这就比 summarize 稳很多,因为 summary 会篡改内容形态,而 memory retrieval 更像是延迟访问,信息本体没有被二次改写。

Sally 提到,这套方案他们用了几个月都没怎么动过,这其实已经说明问题了。真正在产品里站住脚的 context strategy,通常不靠花哨,靠的是可预期。

六、一个特别值得记住的区分:Context 决定模型当前看到什么,Memory 决定什么东西能活下来

她在 talk 里给了一个很好的区分:context aside what the model sees, memory decides what survives。

这句话很重要。

很多团队会把 context 和 memory 混着讲,但这两个东西最好别混。

一旦把这两层分清楚,系统设计就会清爽很多。

你不需要把“长期保留”误当成“永远塞进上下文”。
你也不需要把“当前没看到”误当成“系统已经忘了”。

这是很多 Agent 产品容易绕进去的坑。总觉得只要是重要信息,就应该想办法一直留在 context 里。结果越留越肥,越肥越乱,最后每一轮都在拿高成本、低信噪比的上下文继续推进。

把 context 和 memory 分层之后,问题会变成:
- 当前窗口里,哪些必须实时看见?
- 哪些只需要在特定时刻能被找回?

这才是一个更像产品系统的问法。

七、长对话最麻烦的地方,是 bug 往往晚才出现

她后面讲 long sessions 那段,我觉得特别像真实世界。

很多 Agent 问题,前 5 轮都很好,前 10 轮也没事,甚至前半段看起来已经“成了”。结果越往后跑,系统开始慢慢漏状态、记错信息、追问接不上、工具链路变钝。最烦的是,这些 bug 一开始并不明显,往往是到用户已经用了很久、流程已经很深的时候才暴露。

这就导致一个很现实的问题:你不能靠肉眼碰运气去等 bug 浮现。

Arize 给出的做法很务实,他们做 long session evals。比如加载前 10 turns,测试第 11 turn,专门去看长对话下 context strategy 会不会开始出问题。

这个思路很值钱,因为它把那种“后期才冒头”的问题,硬拉回了可测范围。

很多团队做 Agent eval 还停在单轮问答、多轮简单任务或者固定 benchmark 上,但真正影响产品体验的,常常是这种越来越长、越来越脏、越来越接近真实用户使用轨迹的 session。你不专门测,它就不会主动告诉你哪里坏了。

所以这里最值得记的,不只是“他们做了 eval”。更重要的是:上下文管理必须配长会话 eval,不然你会误以为系统已经稳定。

八、另一个很大的收获:不是所有 context 都该留在同一个 agent 里

这部分我很认同。

他们后来发现,哪怕有了 smart truncation + memory,仍然有一类任务会把单 agent 撑爆。典型例子就是 search task,尤其当 Alyx 要在大量 trace、span 和多步中间推理里来回搜索时,一堆重数据、重 reasoning 全塞在主 agent 里,迟早出问题。

所以他们没有继续硬挤 context,转去做 sub-agents。

这个变化背后的思想非常关键:有些上下文,不该属于主对话。

主对话只保留轻量上下文、用户意图、必要状态。
重数据、重查询、重推理,放到 sub-agent 去处理。
等 sub-agent 跑完,再把结果回传给主 agent。

这一下就把很多上下文压力拆散了。

以前是所有东西共挤一个窗口。
后来变成上下文按任务类型分区存放。

这不只是性能优化,它其实是在重新定义 agent 边界。你不再默认“一个 agent 负责所有事”,会开始承认某些任务天然就该拆出去,天然就该在另一个上下文容器里完成。

这也是现在很多 Multi-Agent 有价值的地方。它不是为了炫“有多个 agent”,目的更实际:把不同密度、不同寿命、不同负载的 context 分开处理。

九、他们还没彻底解决,但已经把正确问题问出来了

我喜欢这场分享的另一个原因,是 Sally 没有装作“我们已经全解决了”。

她明确讲了还没搞定的几件事:

这其实比“我们有一个终极方案”更可信。

因为 context management 本来就不是一道一劳永逸的题。它更像一个持续校准过程:
- 产品在变
- 用户行为在变
- session 变长
- tool 输出变厚
- 模型能力在变
- 你的失效模式也会跟着变

所以靠谱的团队,不会只交付一个策略,他们会不断调整这套策略配套的 memory、eval、sub-agent 分工和 retrieval 路径。

她甚至提到,他们看了 Claude Code 的 source release,本来还期待能偷到一点“秘密”,结果发现对方某些地方也在做类似的 truncation + compression 路线。这反而说明,目前这条路大概真的是现实世界里比较站得住的一条,不只是某个团队的偶然偏好。

十、这场 talk 最该带走的,是一个判断

如果只能带走一句,我会改写成这样:

Agent 失败,很多时候是因为 context 没被当成一等公民来设计。

这句话后面其实带着三层意思:

1)Context engineering 已经是主战场

Prompt 还重要,但它已经不再是主要矛盾。

2)Memory 不是附属功能

没有可回取的 memory,很多长任务本质上跑不稳。

3)Evaluation 必须跟着 context 走

你不测长对话、不测跨轮状态、不测 retrieval 失效点,就很容易高估系统稳定性。

Arize 这场分享没有给一个完美答案,但它把问题结构讲清楚了。对现在做 Agent 的团队来说,这已经很值钱。

因为接下来真正拉开差距的,不会只是“谁先接了更多工具”,而会是“谁更早把 context、memory、sub-agent 和 long-session eval 当成一个完整系统来做”。

附:视频信息

目录 最新
← 左侧翻上一屏 · 右侧翻下一屏 · 中间唤出菜单