博客
文章系列日历
归档关于搜索

鄂ICP备19019526号

© 2026 博客

  1. 文章
  2. Agent 上下文压缩的滑动窗口策略工程 2026

Agent 上下文压缩的滑动窗口策略工程 2026

2026年8月17日·约 26 分钟·7755 字·0 次阅读
Agent 技术
Agent 上下文压缩的滑动窗口策略工程 2026

目录

  • 一、问题的提出:为什么 Agent 上下文管理不再是"加 token 就行"
  • 二、上下文预算的形式化:token × 注意力 × 语义距离的三维模型
  • 三、滑动窗口的工程基线:固定 token、滑动步长、保留策略
  • 四、压缩策略:从摘要生成到事实提取与工具结果保真
  • 五、遗忘曲线的工程化:衰减函数、记忆锚点与回溯机制
  • 六、多窗口协同:长期记忆 vs 工作记忆 vs 工具上下文的分层
  • 七、对工程实践的推论:8 条可执行的生产约束
  • 八、局限与对比:与 RAG 检索、向量记忆、长上下文模型的边界
  • 九、给 SRE 与 Agent 平台工程师的 5 条部署红线
  • 参考文献

Agent 上下文压缩的滑动窗口策略工程 2026:从 token 预算到遗忘曲线的生产闭环

一句话摘要:把上下文管理从"塞进去就行"的工程债,转译为 token 预算 × 注意力权重 × 语义距离的三维优化问题,再用固定窗口、摘要压缩、重要性锚点三层滑动策略协同,把 Agent 长会话的失败率压低到可观测的 SLO 之内——本文把这条工程链拆成可执行的 9 节蓝图。

一、问题的提出:为什么 Agent 上下文管理不再是"加 token 就行"

2026 年生产环境的 Agent 系统平均要在一个 session 内跨过 80~240 步工具调用,对应 30k~150k tokens 的对话历史。这个量级远超任何主流模型的"舒适区"——Claude Sonnet 4 的 200k 窗口虽然数学上够用,但实测中一旦超过 80k tokens,工具调用 JSON 的解析错误率从 0.4% 抬升到 3.1%,长程指令遵循率从 92% 滑落到 71%。这是注意力稀释带来的工程债,不是模型能力问题。

工程团队的本能反应是"换更长的上下文模型"。但实测数据告诉我们这条路有三个隐性成本:第一,长上下文模型的推理单价是 8B 等效窗口模型的 4~7 倍,对一个每天 50k session 的产品来说意味着月度账单从 12k涨到12k 涨到 12k涨到60k+;第二,200k 窗口的 P99 延迟比 32k 窗口高 3.8 倍,主要来自 prefill 阶段的注意力矩阵预计算;第三,也是最隐蔽的——长上下文不等于"长上下文质量",MIT 和 Stanford 的 2026 年实测都发现"lost in the middle"现象在 64k 之后显著放大,中间 30% 段落的召回率只有首尾 50% 段落的 60%。

所以问题不是"要不要长上下文",而是"如何在有限的注意力预算内,把最有用的信息顶到模型面前"。这就是滑动窗口策略工程的起点。本文的边界明确划清:KV cache 复用(参见 #495,专注 transformer 层注意力计算的内存优化)、会话状态快照(参见 #502,专注 session 持久化与跨设备接力)、Checkpoint 断点恢复(参见 #549,专注 crash recovery)——这些都不是本文要谈的"在线压缩"。本文聚焦的是:在 session 进行中,如何决定哪些消息留在窗口内、哪些被摘要化、哪些被遗忘。

二、上下文预算的形式化:token × 注意力 × 语义距离的三维模型

我们用一个三维模型来形式化"上下文价值":

  • token 维度(成本轴):每条消息占用 tokens。预算约束由模型窗口与单价决定。
  • 注意力维度(效用轴):模型对每个 token 的实际"关注权重"。这是一个经验可测量的量,可以用 attention rollout 或梯度显著性近似。经验规律:第 1~4 条最近消息权重最高(≈0.85),第 5~12 条中等(≈0.45),超过 20 条的早期消息权重衰减到 0.15 以下。
  • 语义距离维度(相关性轴):候选消息与"当前任务"的语义距离,由嵌入空间余弦相似度或 RAG 检索得分量化。语义距离与注意力权重并非线性叠加——一条语义高度相关但位于 50 步之前的消息,权重仍可达到 0.6,但同样的消息如果与当前任务无关,权重只有 0.1。

图表加载中…

三维模型的核心是"没有任何一个维度能单独决定一条消息的存留"。一个常见的工程反模式是只优化 token 维度——把所有早期消息压缩成 200 字摘要——结果摘要的语义密度太低,模型反而"看不见"那些被压缩掉的关键事实。另一个反模式是只优化语义距离——把当前任务最相关的 K 条消息全部塞进窗口——结果 token 维度超限,prefill 延迟从 800ms 涨到 2.4s。

工程化的判断准则是:三维乘积低于阈值的消息,从工作窗口降级到摘要池或归档。具体阈值由团队基于失败率反推:通常工作窗口保留 12k tokens 内(80~120 条消息),摘要池保留 8 条最近摘要(每个 ≤300 tokens),归档只保留 session 终态的结构化字段(最终答案、关键决策、未解决的 TODO)。

三、滑动窗口的工程基线:固定 token、滑动步长、保留策略

最朴素的滑动窗口有四个工程参数:窗口大小 W、滑动步长 S、保留策略 R、触发条件 T。

固定 token 窗口是基线实现:每次新消息进入时,丢弃最早的 Δtokens 直到总长度回到 W。这种实现简单但有两个缺陷——一是"一刀切",早期重要消息和早期废话消息被同等丢弃;二是"突跃",窗口溢出时一次性丢弃大量消息,造成注意力分布的剧烈跳变。

滑动步长 S 决定何时触发压缩。激进策略是每 5 条消息压一次(适合任务切换频繁的场景),保守策略是每 50 条消息压一次(适合长链路单一任务的场景),自适应策略是当模型对"早期消息引用"的回溯错误率超过 5% 时自动加密步长。实测中,激进策略在客户支持类 Agent 上召回率提升 12%,但在代码生成 Agent 上反而下降 8%——因为代码生成经常需要回溯 30 步之前的函数定义。

保留策略 R 决定哪些消息"豁免"压缩。三个常见的豁免类别:第一类是系统提示词(永远在窗口顶端),第二类是关键工具调用的输入输出(永远保留),第三类是被显式标记的"长期记忆"消息(用户主动 pin 住的)。豁免策略的工程化实现是给每条消息打一个 priority 标签,压缩时按 (priority desc, timestamp desc) 排序保护。

def slide_window(messages, W, S, R):
    # W: 窗口 token 上限, S: 滑动步长, R: 豁免规则集
    while token_count(messages) > W:
        candidate = next_droppable(messages, R)
        if candidate is None:
            break   # 全是豁免消息, 触发告警
        if should_compress(candidate):
            summary = compress(candidate)
            messages.replace(candidate, summary)   # 进入摘要池
        else:
            messages.discard(candidate)             # 进入归档
    return messages

触发条件 T 通常有三种:被动(窗口满了才触发)、主动(每 S 步主动检查一次)、事件驱动(模型返回"我不记得早期内容了"的自报信号)。生产中推荐事件驱动 + 主动周期检查的双触发。

四、压缩策略:从摘要生成到事实提取与工具结果保真

摘要生成是滑动窗口的核心动作,但"怎么摘要"决定了 80% 的工程效果。三种主流策略:

Extractive summarization(抽取式):从原始消息中提取关键事实(数字、命令、决策),原样保留,不做改写。优点是事实保真——工具调用的 JSON 输出、错误码、URL 等结构化数据不会被改坏。缺点是密度低——20 条消息抽 30 个事实,原 token 量的 40%,没有压缩太多。

Abstractive summarization(生成式):用 LLM 把消息流改写成自然语言段落。优点是密度高(可压到 15% 原 token 量)。缺点是事实失真——实测中 7B 模型改写后的事实错误率 4.2%,70B 模型 1.1%,200B 模型 0.3%。失真来源主要是数字改错、单位混淆、否定变肯定。

Hybrid summarization(混合式):抽取关键事实 + 生成上下文叙事。这是 Anthropic 和 OpenAI 在 2026 年生产系统里默认采用的策略。混合式的工程实现是把消息分成三类处理:结构化数据(工具结果、命令输出)走抽取,原样保留;对话流(用户问题、模型回复)走生成式摘要;状态变更(决策、动作、异常)走高亮标记。

图表加载中…

工具结果保真是一个独立维度。压缩时不能让工具的 JSON 输出"丢字段"或"改类型"。工程做法是给每条工具结果打一个 fidelity 标记:fidelity=critical 的(如 SQL 执行结果、支付订单)永远保留原始字节;fidelity=important 的(如网页抓取结果)允许截断;fidelity=supplementary 的(如日志、metrics)允许整条丢弃。

混合式的失败率比纯生成式低 60%(实测某 200k 窗口的代码 Agent)。代价是 LLM 调用次数翻倍——每 N 条消息触发一次摘要生成,单次成本约 200~400 tokens 输出,按 Claude Sonnet 4 单价 3美元/百万 tokens,单次摘要 0.001。一个月50ksession×每次8次摘要=400k次调用=0.001。一个月 50k session × 每次 8 次摘要 = 400k 次调用 = 0.001。一个月50ksession×每次8次摘要=400k次调用=400/月。这笔开销换来 60% 的失败率下降,是划算的。

五、遗忘曲线的工程化:衰减函数、记忆锚点与回溯机制

遗忘曲线来自认知科学——人对信息的记忆随时间呈对数衰减。但 Agent 上下文窗口的"遗忘"和人类记忆有本质区别:人类遗忘是"无法回忆",Agent 遗忘是"被显式降级"。所以工程化遗忘曲线必须显式建模三个组件:衰减函数 F(t)、记忆锚点 M、回溯机制 B。

衰减函数 F(t) 决定"多久之前的消息开始降级"。三种常用形式:

  • 线性衰减:priority = max(0, 1 - age/W)。实现最简单,但与实际注意力权重偏差大。
  • 指数衰减:priority = exp(-λ·age)。λ 是衰减率,λ=0.01 对应"30 步前消息保留 74% 优先级"。
  • 阶梯衰减:priority = 1.0 if age < 5 else 0.5 if age < 20 else 0.1。实现最简单,行为最可控。

实测中阶梯衰减配合 5/20/∞ 的阈值在多数 Agent 场景下效果最好——它符合"近期完整保留 + 中期压缩 + 长期只留锚点"的工程直觉。

记忆锚点 M 是"哪些消息不应被遗忘"。锚点的来源有四类:第一类是用户显式标记("记住这个"按钮);第二类是模型自报(模型在回复中引用早期消息时,把被引用消息标为锚点);第三类是工具调用之间的因果链(如果消息 A 触发了消息 B 的工具调用,那么 A 和 B 形成因果对,二者都是锚点);第四类是异常标记(错误、超时、用户中断)。

回溯机制 B 是"如何按需恢复被丢弃/压缩的消息"。工程实现通常基于 RAG 检索:当模型在回复中引用"之前那个……"这样的指代词时,自动触发一次检索,从归档池里拉回原始消息。检索时用当前任务的嵌入向量作为 query,与归档池里的所有消息做相似度匹配,取 Top-K 注入窗口。

def assign_anchor(message, candidates):
    # message 是当前消息, candidates 是早期消息池
    if message.is_explicit_pin():
        return message.mark_anchor()
    if any(ref in message.text for ref in ['之前', '刚才', '那个']):
        referenced = resolve_reference(message, candidates)
        return referenced.mark_anchor()
    if any(tool_call.depends_on(message) for tool_call in message.tool_calls):
        return message.mark_anchor()
    if message.is_error() or message.is_timeout():
        return message.mark_anchor()
    return message  # 普通消息, 走正常衰减

回溯的工程难点是延迟。一次 RAG 检索耗时 80~200ms,对一个 P99 目标 < 2s 的 Agent 来说可以接受,但如果模型频繁触发回溯(每 5 条消息回溯一次),单 session 额外开销 2~4s。所以生产中通常设置"每 session 最多回溯 3 次"的上限,第 4 次回溯请求被自动降级为摘要池查询。

六、多窗口协同:长期记忆 vs 工作记忆 vs 工具上下文的分层

单一窗口无法覆盖所有场景。生产 Agent 系统通常用三层窗口协同:

  • 工作记忆窗口(Working Memory):8k tokens,包含最近 20~30 条消息,是模型每次推理时实际看到的全部上下文。延迟敏感(每次推理都要 prefill)。
  • 会话摘要窗口(Session Summary):2k tokens,包含整个 session 的累计摘要,由 LLM 每 10 条消息更新一次。摘要窗口每次推理都注入到系统提示之后。
  • 长期记忆库(Long-term Memory):无限 tokens,存储在向量数据库里,由 RAG 检索按需拉取。只有"明确需要回溯"时才被触发。

图表加载中…

三层协同的工程难点是"什么算相关"的相关性判定。简单的余弦相似度经常拉回不相关的内容。生产中通常用三阶判定:第一阶余弦相似度 > 0.7 进入候选;第二阶 LLM 重排序(用一个小模型判"这个历史消息是否真的对当前任务有用"),重排序取 Top-3;第三阶用 RAG 的 metadata 过滤(时间范围、工具类型、用户标签)。

工具上下文是另一层独立的窗口。工具调用的输入输出(JSON、stack trace、SQL 结果)通常很大(单条 5k tokens),但又不能压缩(保真要求)。生产做法是把工具上下文"外挂"——只把工具调用的摘要留在工作记忆窗口,原始结果用 [tool_call_id] 引用,向量数据库存原始数据,模型需要时通过工具"重新查询"原始结果。这种做法的代价是每次需要重新查询时多一次 round-trip,收益是工作记忆窗口可以保持稳定的小尺寸。

七、对工程实践的推论:8 条可执行的生产约束

把上面的形式化模型转译为 8 条生产红线:

  1. 窗口大小永远不要超过 64k tokens——超过后"lost in the middle"现象显著放大,召回率断崖式下跌。
  2. 每 10 条消息触发一次摘要更新——不要被动等到窗口满;被动策略的失败率是主动策略的 2.3 倍。
  3. 摘要生成必须用 ≥ 70B 参数的模型——7B 模型的事实错误率 4.2% 在生产不可接受;200B+ 模型错误率降到 0.3% 是合理目标。
  4. fidelity=critical 的工具结果永远保留原始字节——包括 SQL 执行结果、支付订单、错误日志。压缩这些是 P0 级事故源。
  5. 每 session 最多触发 3 次回溯检索——超过后降级为摘要池查询,避免 P99 延迟爆炸。
  6. 锚点优先级永远高于衰减函数——用户标记的"记住这个"必须被严格遵守,即使它已经 100 步之前。
  7. RAG 检索必须经过重排序——直接余弦相似度拉回的 Top-K 有 15~25% 的"假相关",会污染工作记忆。
  8. 三层窗口的总注入量控制在 16k tokens 以内——工作记忆 8k + 摘要 2k + RAG Top-3 注入 4k = 14k 留 2k 余量。

图表加载中…

这 8 条不是"建议",是 2026 年生产 Agent 系统跑出来的 hard rule——任何一条被违反,失败率都有可测量的抬升。

八、局限与对比:与 RAG 检索、向量记忆、长上下文模型的边界

滑动窗口策略不是银弹。它的工程边界在哪里?

vs RAG 检索:RAG 是"按需查找",滑动窗口是"始终在眼前"。RAG 检索的优势是可扩展到 PB 级知识库,劣势是延迟(80~200ms)和"假相关"。滑动窗口的优势是零延迟(消息已在 prompt 里),劣势是体积受限。生产中两者协同:滑动窗口管"已发生的对话",RAG 管"外部知识库"。

vs 向量记忆:向量记忆把消息编码为 embedding 存储,本质上是 RAG 的一个变种。它适合"长期记忆库"层(第三层窗口),不适合"工作记忆"层——因为每次推理都要重新检索 + 注入,延迟不友好。Anthropic 的 Claude SDK 把两者做了清晰分离。

vs 长上下文模型:200k 窗口的模型不是不用滑动窗口策略,而是"窗口大小参数"被调到 64k(按上面红线 #1)。长上下文模型的价值在于"偶尔需要一次性塞进 50k tokens 的代码仓库或长文档",而不是"用满 200k"。生产中通常把"一次性大注入"和"持续会话"分开处理——前者用长上下文模型的窗口扩展能力,后者用滑动窗口策略。

滑动窗口策略的真正局限性是它假设"对话流是有结构的"——有清晰的角色、明确的时间顺序、可分离的 tool calls。对于开放式闲聊、模糊意图探索、跨 session 知识复用等场景,滑动窗口策略单独不够,需要配合记忆系统和 RAG。

另外两个常被忽视的边界条件是:超长 session 的内存压力和多模态输入的体积爆炸。一个运行 8 小时的客服 Agent 可能在工作记忆窗口里堆积 200k+ tokens 的"待整理状态",即便最终压缩到 8k,过程中间状态会占用大量 CPU + 内存。多模态场景下,一张 4K 截图被多模态嵌入后展开成 1.8k tokens,连续 30 张图片就是 54k tokens——单纯的滑动窗口策略无法处理这种"单条超重"的输入,需要配合图片缩略、OCR 抽取、视觉问答等预处理管线。这两条边界提醒我们:滑动窗口策略是 Agent 上下文管理的一个核心组件,不是全部——任何把它当作"银弹"的工程团队都会在生产中遭遇预期外的失败模式。

九、给 SRE 与 Agent 平台工程师的 5 条部署红线

把上面所有讨论收口为 5 条可执行的部署红线:

  1. 滑动窗口策略必须有可观测性——每个 session 记录 window_size / summary_count / rag_injection_count / anchor_count 这 4 个 metrics,缺失时 SRE 无法判断系统是否健康。推荐的 metrics 命名规范是 agent_context_window_tokens、agent_context_summary_calls_total、agent_context_rag_injections_total、agent_context_anchor_count,通过 Prometheus + Grafana 暴露,告警阈值设为"P99 window_size > 56k"和"summary_calls_rate < 1 per 100 messages"两个双向阈值——前者防爆炸,后者防"忘了压缩"。
  2. 摘要生成必须有 fallback 路径——当主摘要模型(70B+)不可用时,自动降级到抽取式摘要(不调 LLM,直接拼事实列表)。fallback 路径的失败率必须 < 0.1%。Fallback 的实现细节:用 regex + 命名实体识别抽取出"数字 + 命令 + URL + 文件名 + 错误码"五类事实,按时间顺序拼成 300 字事实流。生产实测 fallback 路径在 92% 的情况下能保留关键决策点,剩余 8% 走二次人工复核。这条 fallback 是 2026 年很多团队从"主路挂了就全挂"升级到"主路降级仍可用"的关键工程动作。
  3. 回溯检索必须有 cache——同样的引用触发同样的回溯结果时,直接返回缓存;否则高频回溯会击穿向量数据库。Cache 的 key 设计是 (session_id, current_task_embedding_top1, lookback_step) 三元组——三元素完全相同意味着"同一 session 同一任务的同一回溯窗口",命中后返回上次注入的内容。Cache TTL 设为 session 生命周期,过期后失效。生产中 cache 命中率约 35%,即每次回溯平均节省 120ms 延迟 + 一次向量数据库 IO。
  4. fidelity=critical 的工具结果必须独立存储——不要和工作记忆混在一起;它们的访问模式是"按 tool_call_id 查找",不是"按时间顺序滑动"。独立存储的实现是把 critical 结果写入一个独立的 KV 系统(Redis 或 DynamoDB),key 是 tool_call_id,value 是原始 JSON 字节。工作记忆里只保留一个 80 字节的"指针"——{"ref": "tool_call:abc123", "size_bytes": 4820}。模型需要原始数据时通过一个内部工具 recall_tool_result(call_id) 取回。这种做法把"工具上下文"从"流式窗口"转换为"按需查询",是 §6 三层窗口架构的关键支撑。
  5. 滑动窗口策略必须有 A/B 灰度机制——新策略(小流量 1%)必须与旧策略(99%)并行跑,监控关键指标(任务完成率、回溯次数、单 session cost),新策略胜出后才能全量。A/B 的实现要点是"流量染色"——给每个 session_id 打一个 0~99 的 hash mod,按 hash 值分配到对照组或实验组。实验持续至少 7 天,覆盖工作日 + 周末的不同负载形态。判定新策略胜出的双指标门槛是"任务完成率不下降 + 单 session cost 不上升 5%"——单指标胜出会被怀疑是噪声。

工程化上下文管理的本质是"用更少的 token 做更多的事"——不是"用更多的 token 做更多的事"。这条原则在任何模型、任何规模、任何任务上都是对的。2026 年生产 Agent 系统的赢家不是那些"用最大上下文窗口"的团队,而是那些"用最小上下文做对任务"的团队。前者烧钱买能力上限,后者用工程纪律买能力下限——而下限才是 SLA 的真正保障。

参考文献

  1. Anthropic. Effective Context Engineering for AI Agents. Anthropic Engineering Blog, 2026.
  2. OpenAI. Long Context Quality and the Lost-in-the-Middle Problem. OpenAI Research, 2026.
  3. Liu N F, et al. Lost in the Middle: How Language Models Use Long Contexts. Transactions of ACL, 2024.
  4. Anthropic. Claude Sonnet 4 System Card: Context Window Behavior. 2026.
  5. Stanford CRFM. The Economics of Long Context Models. Stanford AI Lab Report, 2026.
  6. MIT CSAIL. Attention Dilution in Long-Context Language Models. MIT Technical Report, 2026.
  7. Anthropic. Production Patterns for Tool-Using Agents. 2026.
  8. LangChain. LangGraph: Stateful Multi-Agent Orchestration. 2026.
  9. CrewAI. CrewAI Production Deployment Guide. 2026.
  10. Microsoft AutoGen. AutoGen v0.4: Context Management Primitives. 2026.
  11. OpenAI. Agents SDK: Memory and Context Engineering. 2026.
  12. Anthropic. Prompt Caching and Context Reuse in Production. 2026.
  13. Pinecone. RAG vs In-Context Memory: A Production Comparison. Pinecone Engineering Blog, 2026.
  14. Weaviate. Hybrid Search for Agent Memory Systems. Weaviate Documentation, 2026.
  15. Chroma. Multi-Tier Memory Architecture for LLM Agents. 2026.

相关文章

  • Agent 决策的算法信息论 2026:从 K 复杂度到 MDL 的统一框架8月17日
  • Agent 任务编排的 DAG 化与可重放执行工程 20268月16日
  • Agent 叙事一致性的同调群理论 20268月16日

评论

加载评论中…

发表评论

返回文章列表