5.1 短期记忆:上下文窗口管理与压缩


5.1 短期记忆:上下文窗口管理与压缩

短期记忆就是 LLM 的上下文窗口——它既是 Agent 「当下能看见什么」的全部,也是最容易爆掉的那个容器。ReAct 轨迹越积越长、用户对话越来越久、工具返回越来越大,全都压在这个有限的窗口里。怎么管好它,是 Agent 工程最日常也最关键的活。

5.1.1 短期记忆的本质:一次性的工作台

短期记忆的本质,是一次 LLM 调用所能「看见」的全部文本。它有以下特征:

特征 含义
有限 受 Token 上限约束(几 K 到几百 K)
易失 调用结束即消失,下次重新拼装
显式 所有内容必须显式拼进 Prompt
昂贵 Token 数与成本、延迟成正比

把短期记忆比作「工作台」最贴切:上面能摆的东西有限,摆太多会乱、会找不到重点,每干完一次活儿(一次调用)就要清空重摆。

💡 短期记忆不是免费的:每多放一个 Token,每次调用都要多付一次钱、多花一次推理时间。「拼 Prompt」是 Agent 最容易烧钱的地方——一个不优化的 Agent,可能把 80% 的 Token 预算花在重复搬运历史上。

5.1.2 短期记忆的预算约束

LLM 的上下文窗口有硬上限。常见模型窗口:

模型类型 典型窗口
早期 LLM 4K-8K
主流 LLM(2024) 32K-128K
长上下文 LLM 200K-1M+

窗口虽大,但**「能装」不等于「该装」**。原因有三:

不该装满的理由 后果
成本 Token 多 = 钱多
延迟 长 Prompt 推理慢
注意力稀释 上下文越长,LLM 越抓不住重点
<svg viewBox="0 0 720 320" xmlns="http://www.w3.org/2000/svg"> <line x1="60" y1="280" x2="680" y2="280" stroke="#475569" stroke-width="2"/> <line x1="60" y1="40" x2="60" y2="280" stroke="#475569" stroke-width="2"/> <text x="680" y="300" font-size="12" fill="#475569" text-anchor="end">上下文长度 →</text> <!-- 成本(线性上升) --> <line x1="80" y1="260" x2="640" y2="80" stroke="#db2777" stroke-width="2"/> <text x="650" y="80" font-size="11" fill="#db2777">成本(线性)</text> <!-- 延迟(线性上升) --> <line x1="80" y1="270" x2="640" y2="120" stroke="#ca8a04" stroke-width="2"/> <text x="650" y="120" font-size="11" fill="#ca8a04">延迟(线性)</text> <!-- 注意力质量(倒 U) --> <path d="M 80 220 Q 200 80 360 80 T 640 240" stroke="#2563eb" stroke-width="2" fill="none"/> <text x="650" y="240" font-size="11" fill="#2563eb">注意力质量(倒 U)</text> <text x="360" y="30" font-size="13" fill="#475569" text-anchor="middle" font-weight="bold">上下文长度的三重代价</text> </svg>

注意力质量是倒 U 形——太短信息不足,太长注意力被稀释。最优长度不是「装满」,而是「刚好够」

5.1.3 压缩策略一:滑动窗口

最简单的压缩——只保留最近 N 步,丢弃更早的

全轨迹: [S1, S2, S3, S4, S5, S6, S7, S8, S9] 窗口=5: 实际送进 Prompt = [S5, S6, S7, S8, S9]

简单滑动窗口的问题

当前 Prompt: [System: 你是财务助手] ← Profile [User: 帮我分析 AAPL] ← 原始任务 (在 S1, 被丢了!) [Step 5-9 的轨迹] ← 最近 5 步 → Agent 忘了在分析 AAPL!

问题:简单滑动窗口会丢失任务目标——而目标通常在最早的第一步。

改进:保头保尾

保留 = [Goal(开头)] + [最近 N 步(结尾)] 丢弃 = 中间的旧步骤 实际送进 Prompt: [System: 你是财务助手] [Goal: 帮我分析 AAPL] ← 保头 [Step 7, 8, 9] ← 保尾
变体 做法
简单窗口 最近 N 步
保头保尾 Goal + 最近 N 步
加权窗口 最近步全保,旧步摘要保

⚠️ 滑动窗口的最大风险是丢目标。生产实践几乎都用「保头保尾」或更复杂的加权方案,绝不用简单窗口——简单窗口迟早让 Agent 忘了自己在干什么。

5.1.4 压缩策略二:摘要压缩

定期让 LLM 把旧轨迹压缩成一段摘要,替换原始轨迹。

摘要的三种粒度

粒度 做法 信息损失
完整摘要 把每步 Thought/Action/Observation 都概括
结论摘要 只保留每步的结论(数字、事实)
任务级摘要 整段轨迹压成「已完成了什么」

一个例子

[原始轨迹 Step 1-5] Thought 1: 查苹果营收 Action 1: search("Apple revenue 2024") Observation 1: $391B Thought 2: 查 2023 对比 Action 2: search("Apple revenue 2023") Observation 2: $383B Thought 3: 计算增长率 Action 3: calculate("...") Observation 3: 2.0% [摘要] "已查询: 苹果 2024 营收 $391B、2023 营收 $383B; 增长率 2.0%。"

原始约 200 Token,摘要约 30 Token,压缩比约 7:1。

💡 摘要的代价:摘要本身要花一次 LLM 调用。触发时机很关键——太频繁(每步摘要)成本高,太稀疏(最后才摘)窗口已爆。生产实践通常「每 K 步触发一次」(K 通常 3-5)。

摘要的失败模式

失败 表现 对策
漏关键信息 摘要丢了关键数字 关键事实外存
摘要错误 LLM 摘错了 摘要后做校验
递归失真 摘要的摘要越来越偏 保留原始 Goal 不参与摘要

5.1.5 压缩策略三:硬压缩(Token 级)

摘要压缩是「语义级」压缩——靠 LLM 理解后重写。还有一类「Token 级」硬压缩——不改变语义,直接压缩 Token

代表工作是 LLMLingua:用小模型评估每个 Token 的「重要性」,删除低重要性的 Token。

原始: "我想要查询苹果公司在 2024 年的财务年度的总营收数据" 压缩: "查询苹果 2024 财年总营收"
压缩方式 压缩比 语义损失 适用
语义压缩(摘要) 5-10:1 中(需 LLM) 长历史
Token 级压缩(LLMLingua) 2-5:1 紧 Prompt
组合 10-20:1 大型 Agent

⚠️ 硬压缩的局限:Token 级压缩对短而精的 Prompt 效果有限(本来就没多少冗余);对长而冗余的 Prompt(如重复历史、啰嗦描述)效果显著。生产中常与摘要组合使用。

5.1.6 压缩策略四:结构化存档

把轨迹里的关键事实抽出来单独存(如存到 Memory 的「事实区」),轨迹本身只留指针。

[事实区] - 苹果 2024 营收: $391B (来自 Step 2) - 苹果 2023 营收: $383B (来自 Step 4) - 增长率: 2.0% (来自 Step 6) [轨迹区 - 精简] - Step 1-2: 查 2024 营收 (见事实区) - Step 3-4: 查 2023 营收 (见事实区) - Step 5-6: 计算增长率 (见事实区)
  • 优点:关键信息长期保留、可检索、不污染轨迹。
  • 缺点:需要设计抽取规则(什么算「关键事实」)。

抽取规则的常见做法

做法 内容
数值 所有数字、日期、金额
命名实体 人名、公司名、地名
决策 「选了 A 而非 B」
错误 失败的尝试与原因

5.1.7 四种压缩策略的组合

生产实践通常组合多种策略

作用
Goal 抽出 保证不丢目标
关键事实外存 保证关键数据可查
旧轨迹摘要 压缩历史
滑动窗口 保留近期细节

这四层组合,能在绝大多数场景下平衡「保留关键信息」与「控制窗口长度」。

5.1.8 上下文管理的反模式

反模式 表现 后果 正确做法
全量历史 每轮拼全部轨迹 窗口爆炸+贵 分层压缩
简单窗口 只留最近 N 步 丢目标 保头保尾
每步摘要 摘太频繁 摘要本身烧钱 每 K 步触发
Goal 也摘要 Goal 被压缩失真 Agent 失方向 Goal 不参与摘要
不抽事实 关键数字随轨迹丢 重新查一遍 关键事实外存
过长 System Prompt Profile 写太长 每次都付长 Prompt 钱 Profile 精简 + 分层

💡 上下文管理是 Agent 工程的「隐性成本中心」。它不显眼,却决定了 Agent 的运行成本上限。一个不优化的 Agent,可能比优化过的贵 5-10 倍——多出来的钱几乎都花在重复搬运历史上。生产 Agent 上线前,必须做一次上下文预算审计:每轮平均多少 Token、瓶颈在哪、能压多少。

本节小结

  • 短期记忆 = LLM 上下文窗口,本质是「一次性工作台」。它有限、易失、显式、昂贵——「能装」不等于「该装」,注意力质量随长度呈倒 U 形。
  • 四种压缩策略:滑动窗口(保头保尾,绝不用简单窗口)、摘要压缩(每 K 步触发,分三种粒度)、硬压缩(Token 级,如 LLMLingua)、结构化存档(关键事实外存)。
  • 生产主流是四层组合:Goal 抽出 + 关键事实外存 + 旧轨迹摘要 + 滑动窗口。这能平衡「保留关键信息」与「控制窗口长度」。
  • 上下文管理是 Agent 的隐性成本中心,决定运行成本上限。生产 Agent 上线前必须做上下文预算审计

下一节《5.2 长期记忆与向量数据库》将讨论跨会话的持久化记忆——Embedding、向量库选型、写入策略。


作者与出处
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 会发光的石头的小龙虾 转发
评论区 (0)
U