← 🤖 检索与 Agent

FDE Agent 的上下文窗口管理

管理上下文窗口,就是决定 Agent 在每一步能看到什么——这直接关系到客户私有数据的处理和他们的 token 账单。前沿部署工程师把窗口当作一笔需要分配的预算,用四种手段来管理:写入、选择、压缩和隔离,因为忽视这一点的部署,要么运行成本高得离谱,要么不可靠到无法信任。

访谈实录

在实验室里,你调好一次提示词就可以继续下一步。但在客户现场,同一个 Agent 每个任务要循环几十轮,每次工具调用都会追加输出,每一轮都会追加历史记录。这些 token 最终都会出现在采购部门有人盯着的那张账单上。放任不管的话,上下文只会不断膨胀。

假设有一个 Agent:3,000 token 的系统提示词、2,500 token 的工具目录,每轮新增约 450 token 的对话内容,外加 2,000 token 的工具结果。第一轮时窗口里有 7,950 个 token。第五轮,17,750。第十轮,30,000。第二十轮,54,500。而这二十轮总共计费 624,500 个 token,因为每一轮都要重新读取之前的所有内容。

现在做两处改动:把每次工具结果裁剪到下一步实际用到的 300 个 token,并把五轮之前的历史总结成一份 800 token 的摘要。第二十轮现在只需运行 10,050 个 token,最近五轮仍保持原样。整个运行计费 189,500 个 token,成本约为原来的三分之一。客户会注意到这三分之一的差别。模型也会注意到,它的指令不再被四万个 token 的工具输出淹没。

这两处改动是四种手段的具体实例,每一种都是控制某一步实际进入窗口内容的杠杆:写入、选择、压缩、隔离。

写入是指把上下文持久化到窗口之外,而不是内联携带。一个草稿文件、一个外部记忆存储,或一份结构化的运行日志,保存着 Agent 本来每一轮都要重新粘贴的状态。在客户现场,这份日志还能兼作事后利益相关者可以查阅的审计记录,所以它一物两用、物有所值。

选择是指只加载当前这一步需要的内容:对客户语料库进行检索、按需拉取工具 schema,以及根据与当前输入的相似度挑选少样本示例。常见的失败做法是为了保险把整个知识库都塞进去。你为成千上万个无关 token 买单,还把真正重要的段落埋没了。

压缩是指缩小你保留的内容。旧轮次不再被使用后就进行总结。把工具的 JSON 响应裁剪到下一步要读取的三个字段。把检索到的 6,000 token 文档压缩成能回答问题的 400 个 token。未压缩的历史记录是长时 Agent 运行变慢并开始漂移的最常见原因。

隔离是指拆分工作以避免上下文相互污染。使用范围受限的子 Agent,并为每个租户使用独立的会话,可以确保一个客户的数据不会进入另一个客户的提示词;而为嘈杂的工具单独开一个窗口,可以防止话多的 API 挤占指令空间。在多租户部署中,这是一项数据治理要求。你要从第一位客户开始就把它设计进去。

面试官留着的追问是:到第二十轮时,你的 Agent 变慢了,而且是在基于过时的历史记录作答。你会砍掉什么?请用预算来回答。系统提示词 2,000 tokens,工具 1,500,检索到的上下文 4,000,最近几轮逐字保留 3,000,滚动摘要 1,000,16,000 tokens 的目标中剩余部分留给回复。系统提示词和当前任务永远不裁剪。

有数字的预算才是设计。“我们谨慎管理上下文”只是一种愿望。要写、选、压缩、隔离。完整讲解见 fdeinterviews.com。

TL;DR: 前沿的上下文窗口是一个固定预算,你花的是客户的 token 账单,而不是可以随意填满的免费空间。FDE 的工作就是四个动作:把上下文写入持久存储,只选取当前步骤所需的内容,压缩保留的内容,并把一个租户或工具与另一个隔离开。做错了,Agent 到第二十轮就会变慢、变贵,而且自信地出错。

FDE 视角下的问题

上下文窗口这个概念解释了窗口是什么,以及为什么输入和输出共享它。本概念讲的是在此之上更难的工作:让一个 Agent 每天在客户现场、针对客户数据、记在客户账单上运行数千次。

在实验室里,你调一次提示词就继续往下走。而在客户现场,同一个 Agent 每个任务要循环几十轮,读取一个你无法控制的私有语料库,并且每个 token 都记在一个采购部门有人盯着看的账户上。长时间运行的 Agent 的上下文在每一步都会增长:每次工具调用都会追加输出,每一轮都会追加历史。放任不管,它会攀升到模型注意力开始失效的程度,也会攀升到财务部门开始追问的程度。上下文管理正是让部署既准确又可负担的关键,这也是为什么它在资深和首席级别的面试循环中是作为系统问题出现的,而不是一条提示词技巧。

增长首先是算术,然后才是一种感受。假设一个 Agent 有 3,000 token 的系统提示词和 2,500 token 的工具目录,每轮新增约 450 token 的对话内容和 2,000 token 的工具结果。放任不管的话,上下文窗口在第 1 轮为 7,950 token,第 5 轮为 17,750,第 10 轮为 30,000,第 20 轮为 54,500;这二十轮累计计费 token 达 624,500,因为每一轮都要重新读取之前的所有内容。如果把每个工具结果裁剪到下一步实际用到的 300 token,并把五轮之前的历史摘要成 800 token 的摘要,那么第 20 轮只需 10,050 token,整个运行累计计费 189,500,约为原成本的三分之一,而最近五轮仍保持原样(以上均为计算所得)。客户注意到的是那三分之二的成本节省;模型注意到的是,它需要的指令不再被四万 token 的工具输出所淹没。

四种操作

实用的分类法是:写入、选择、压缩、隔离。每一种都是对某一步骤中真正进入上下文窗口的内容施加的杠杆。

上文的骨架就是这四种操作按单个步骤执行顺序的排列,以及每种操作之所以占有一席之地的理由。

写入是指把上下文持久化到窗口之外,而不是内联携带。一个 scratchpad 文件、外部记忆存储或结构化的运行日志,保存着 Agent 否则每轮都要重新粘贴的状态。在客户现场,它还兼作事后利益相关者可以查阅的审计追踪,因此一物两用、物有所值。

选择是指只加载本步骤所需的内容。也就是对客户语料库做 RAG、按需拉取工具 schema 而不是一次性全部加载,以及根据与当前输入的相似度挑选少样本示例。常见的失败模式是为了保险把整个知识库塞进提示词:你为处理数千个无关 token 付费,还把真正重要的段落埋没了。

压缩是指缩小你确实要保留的内容。当旧轮次不再被活跃使用时将其摘要化,把工具的 JSON 响应裁剪到下一步要读取的三个字段,把检索到的 6,000 token 文档压缩为回答问题所需的 400 token。未压缩的历史是长时 Agent 运行变慢并开始漂移的最常见原因。

隔离是指拆分工作,使上下文互不渗透。作用域受限的子 Agent、按租户划分的会话,以及为嘈杂工具单独设置的窗口,能把一个客户的数据挡在另一个客户的提示词之外,并防止喋喋不休的 API 挤占指令空间。在多租户部署中,隔离是由护栏强制执行的数据治理要求,而不是事后才加的性能优化。

面试官为何追问这一点

这是判断你是否在别人的账单上运行过 AI Agent 的一个快速检验。一个候选人如果直接选用百万 token 的模型就止步于此,说明他只读过规格表,却从未观察过每轮成本曲线。面试官会保留一个追问:“你的 Agent 上下文每一轮都在增长,到第二十轮时它变慢了,而且基于过时的历史回答,你会削减什么,按什么顺序削减?”优秀的回答会给出每步预算:先压缩历史,在语料库上做检索选择而不是全量倾倒,并固定系统提示词和当前任务,使它们永远不会被裁剪。用预算的方式说出来:系统提示词 2,000 token,本步可调用的工具 1,500 token,检索到的上下文 4,000 token,最近几轮逐字保留 3,000 token,滚动摘要 1,000 token,16,000 token 目标中剩余的部分留给回复。每一项都有归属和裁剪规则,而永不裁剪的是第一项和当前任务。有数字的预算是设计;“我们谨慎管理上下文”只是愿望。

常见误解

  • “上下文窗口很大,我就不用再管理上下文了。” 成本和延迟随处理的 token 数量扩展,所以更大的窗口意味着更大的账单,而不是免费通行证。你仍然要选择放什么进去。
  • “选择就是 RAG。” 对文档做检索只是其中一种情况。选择还要决定本步加载哪些工具、哪些记忆、哪些示例,每一项都消耗预算。
  • “隔离是过早优化。” 在多租户客户部署中,把一个租户的数据挡在另一个租户的窗口之外是一条合规红线,不是可以推迟的优化。
  • “压缩会丢失信息,所以要避免。” 保留每一轮原始内容和完整的工具输出,正是让长时运行的 Agent 变慢、失去焦点的根源。要有意识地做摘要,如果需要重读,就把原始内容保存在持久化存储中。

核心要点

  • 把窗口当作你分配的每步预算,对照客户的真实 token 成本来衡量,而不是因为模型允许就把它填满的空间。
  • 把状态写入持久化存储,只选择本步所需的内容,压缩保留的部分,并让租户之间和嘈杂的工具之间相互隔离。
  • 面试官保留的追问是一个上下文已经膨胀的长时运行 Agent;用明确的预算和“先压缩再选择”的顺序来回答。
  • 多租户部署中的隔离是数据治理要求,所以要从第一个客户开始就设计进去,而不是在第二个客户之后。

相关课程

相关概念

通过提问来练习这些内容

LLM 与 GenAI 基础你的提示词加上检索到的文档超出了上下文窗口。你有哪些选择,各自的权衡是什么? →中等 · 登录后免费

LLM 与 GenAI 基础什么是“lost in the middle”(中间丢失)问题?它如何改变你为 RAG 系统组装上下文的方式? →中等 · 登录后免费

RAG 与 Agent 系统设计构建一个 Agent,在 200k token 的上下文内,通过多轮长会话处理一份 500 页的文档。你如何管理记忆? →困难 · 付费

RAG 与 Agent 系统设计客户想要一个覆盖其私有文档和开放网络的深度研究 Agent。请设计它,让利益相关者信任其中的引用。 →专家 · 付费

RAG 与 Agent 系统设计构建一个在枢纽停运时重新规划货运路线的 Agent,并设计评测套件以防止它超支。 →困难 · 付费

RAG 与 Agent 系统设计带我完整走一遍 RAG 流水线,并告诉我它通常在哪里出问题 →简单 · 免费