Agent 跑着跑着,对话越来越长,token 越来越多,最后撞上模型的上下文窗口限制。怎么办?

算一笔账你就知道问题有多大:

组成部分 大约消耗 tokens
系统提示 ~500
工具定义(假设 10 个工具) ~2000
每轮对话(用户+助手+可能的工具调用) ~500-2000
20 轮对话后的历史 20000+
一次工具返回(比如读一个文件) 3000-5000

20 轮对话就奔着 25000 tokens 去了。如果中间调了几次工具读文件、搜网页,轻松翻倍到 50000+。DeepSeek 的窗口是 128K,Claude 是 200K,听起来很大?Agent 消耗 token 的速度比你想象的快得多——一次代码分析任务调 15 轮工具,上下文就能吃掉一半窗口。

而且别忘了,tool calling 原理篇里讲过:每次 API 请求都要带完整的 tools 数组。10 个工具的定义大约 2000 tokens,这笔钱每一轮都要交——不管你这轮用不用得上那些工具。对话 20 轮,光工具定义就重复发送了 20 次,每次都计入 input tokens 计费。Anthropic 和 OpenAI 都有 Prompt Caching 机制可以降低重复发送的费用,但上下文空间是实打实被占掉了。

窗口是有限的,对话是无限的。 怎么在有限窗口里维持 Agent 的记忆和能力?

这个问题不是鸿蒙 Agent 特有的——Claude Code、Cursor、Windsurf、CrewAI,所有 Agent 都得面对。区别只在于各家的解法不同。

━━━━━━━━━━━━━━━━━━━━

◆ 六种方法,从简单到复杂

━━━━━━━━━━━━━━━━━━━━

方法 1:固定截断——只保留最近 N 条

最简单粗暴:对话历史只保留最近 N 条消息,前面的全扔掉。

// OHClaw 现在就是这么干的const CONTEXT_WINDOW = 50const history = await dbService.getMessages(chatId, CONTEXT_WINDOW)

一行代码搞定。OHClaw(我们在 ReAct 循环篇里做的鸿蒙 Agent)的 CONTEXT_WINDOW = 50,每次调 API 只发最近 50 条消息。

优点:零开销,零复杂度。 缺点:前面聊了什么?忘了。Agent 彻底"失忆"。 适合:简单问答,不需要长记忆的场景。做原型验证阶段够用。

────────────────────

方法 2:滑动窗口——钉住系统提示

固定截断的小改进:系统提示永远保留,剩余空间放最近的消息。

[系统提示 (永远在第一条)] + [最近 N tokens 的对话]

比纯截断好一点——至少 Agent 不会忘了自己是谁、有哪些工具可以用。大多数框架的默认实现就是这个。

OHClaw 其实也做了这个:系统提示每次重新构造,不走历史消息的 CONTEXT_WINDOW 截断。所以严格说我们是方法 2,不是纯方法 1。

💡 你可以把这想象成考试——卷子头上的考试说明(系统提示)一直印在那里,但你能参考的笔记(对话历史)只有最近几页。

────────────────────

方法 3:消息摘要——用 LLM 压缩旧对话

这是"真正的"解决方案的起点。当对话快要超限时,用 LLM 把旧消息总结成一段摘要,替换掉原始的长对话。

之前:[系统提示] + [第1-10轮原始消息] + [第11-15轮原始消息]之后:[系统提示] + [摘要:"前10轮讨论了X功能的实现方案,决定用Y方式,创建了Z文件"] + [第11-15轮原始消息]

OpenClaw 的 /compact 命令就是这个——手动触发,让 LLM 把当前对话压缩一遍。Claude Code 的自动压缩也是这个思路——上下文使用量达到 83.5% 时自动触发。

“用 LLM 压缩"具体怎么做?把需要压缩的旧消息取出来,单独发一个新的 API 请求——旧消息作为内容,加上压缩指令,让模型输出摘要。为什么不在当前对话里直接追加一条"请压缩”?因为上下文已经快满了,再往里塞指令只会更撑;而且模型的输出会混进正常对话,不好拆分。独立请求干净利落——输入是旧消息,输出就是摘要。

以 OpenClaw 为例,它发给 LLM 的压缩指令大致是这样的:

请根据以下对话历史,生成一份简洁、事实性的摘要,包含以下几个部分:## Decisions(已做的决策)## Open TODOs(待办事项)## Constraints/Rules(约束和规则)## Pending user asks(用户未被回应的请求)## Exact identifiers(原样保留的标识符:文件路径、URL、ID、端口号等)不要遗漏用户尚未解决的请求。优先保留最近的上下文,而不是早期的讨论。

拿到摘要后,回到主对话,用摘要替换掉旧消息,窗口一下子就空出来了。如果旧消息太长一个请求都装不下,就先按 token 数切成几块,每块分别摘要,最后再合并。

没有什么黑魔法——压缩的质量完全取决于这个 prompt 写得好不好。你让它"总结一下",它可能只给你三句话;你像上面这样规定好结构(决策、待办、标识符),它就知道什么该保留。

优点:保留了语义信息。前面讨论了什么方案、做了什么决定,摘要里都有。 缺点:/*/有损压缩。细节、代码路径、精确的指令措辞,在摘要中一定会丢失。//*就像把一本书缩写成摘要——大意还在,但你再也找不到第 37 页第三段那句话了。

社区对 Claude Code 自动压缩的吐槽很多:“压缩后变笨了”、“不知道自己在看哪些文件了”、“刚才说的编码规范忘得一干二净”。这不是 bug,这是有损压缩的必然代价。

💡 想想 JPEG 压缩图片——文件变小了,但细节模糊了。消息摘要就是对话的 JPEG 压缩。压缩率越高,丢失越多。

────────────────────

方法 4:混合摘要缓冲——最佳折中

方法 2 + 方法 3 的组合:旧消息摘要,最近消息原样保留,系统提示钉住。

[系统提示 (永远在)] + [旧消息的摘要] + [最近 K 轮的原始消息]

LangChain 的 ConversationSummaryBufferMemory 就是这个实现。它维护一个 token 预算——比如 4000 tokens。最近的消息原样保留,一旦超过预算,就把最老的那批消息摘要掉。

from langchain.memory import ConversationSummaryBufferMemorymemory = ConversationSummaryBufferMemory(    llm=llm,    max_token_limit=4000  # 超过这个就开始摘要旧消息)

目前大多数生产级 Agent 的选择。原因很简单:最近几轮的对话质量对 Agent 表现影响最大(最近在干嘛、用户刚才要什么),而更早的对话知道个大概就行。

为什么说它是"最佳折中"?看一个对比:

方法 近期对话质量 远期记忆 额外 API 开销 实现复杂度
固定截断 极低
消息摘要 中(全部被摘要) 有(摘要) 每次压缩调一次 LLM
混合摘要缓冲 高(最近原样保留) 有(摘要) 每次压缩调一次 LLM

混合方案在每个维度上都没有明显短板。工程上的"最优"很多时候就是"没有致命缺点"。

────────────────────

方法 5:分层记忆——像操作系统管内存

MemGPT(现在叫 Letta)的做法,直接借鉴了操作系统的内存管理模型:

┌─────────────────────────────────────┐│  核心记忆 (上下文窗口) = RAM         │  ← 快,但容量有限│  - 系统提示                          ││  - 关键事实和偏好                    ││  - 最近对话                          │├─────────────────────────────────────┤│  外部存储 (数据库/向量库) = 磁盘      │  ← 慢,但容量无限│  - 完整对话历史                      ││  - 存档的记忆                        ││  - 文件和文档                        │└─────────────────────────────────────┘

关键设计:Agent 自己决定什么放"内存"、什么存"磁盘"。它有专门的工具来管理自己的记忆——core_memory_append(往核心记忆加东西)、archival_memory_insert(存到外部存储)、archival_memory_search(从外部存储检索)。

💡 就像你工作时桌面上放着最重要的文件(核心记忆),其他资料放文件柜(外部存储)。需要的时候去翻文件柜,用完了再放回去。不同的是,这里是 Agent 自己决定什么放桌面、什么放柜子。

优点:理论上可以实现"无限"上下文。 缺点:工程复杂度高。而且——Agent 管理记忆本身也要消耗 token。你让 Agent 花 token 来决定"这条信息该不该记住",这本身就是开销。

────────────────────

方法 6:RAG 检索增强——按需加载

不把所有历史塞进上下文,而是存到向量数据库里,需要的时候按语义检索回来。

MCP/Skill/RAG 篇里做的端侧 RAG 就是这个思路——知识库文档存在向量数据库里,用户问问题时检索相关片段注入上下文。同样的思路也可以用在对话历史管理上:把老对话存向量库,需要时检索回来。

CrewAI 用 ChromaDB 做短期记忆存储,Windsurf 对整个代码库做 RAG 索引。Cursor 的 @ 符号引用也是一种手动 RAG——你手动告诉 Agent “去看这个文件”。

优点:只注入相关内容,省 token。 缺点:检索质量不稳定。“我刚才做了什么"这类时序连续性问题,语义检索不擅长——因为"刚才"不是一个语义概念,是一个时间概念。向量检索擅长的是"跟 X 相关的内容”,不擅长"时间上接近的内容"。

────────────────────

六种方法一张图

简单 ──────────────────────────────────────────── 复杂低成本                                           高成本方法1        方法2        方法3        方法4        方法5        方法6固定截断  →  滑动窗口  →  消息摘要  →  混合缓冲  →  分层记忆  →  RAG检索(丢就完了)   (钉住系统)   (LLM压缩)   (摘要+原文)  (类OS管理)   (按需加载)OHClaw       大多数框架   Claude Code  LangChain   MemGPT/Letta  Cursor                         OpenClaw     生产级Agent               Windsurf

实际使用中,这些方法经常组合。比如 CrewAI 同时用了方法 4 和方法 6——短期记忆用混合缓冲,长期记忆用 RAG 检索。

━━━━━━━━━━━━━━━━━━━━

◆ 各家 Agent 怎么做的

━━━━━━━━━━━━━━━━━━━━

Agent/框架 策略 细节
OHClaw(我们的) 滑动窗口 CONTEXT_WINDOW = 50 ,系统提示钉住
OpenClaw 摘要压缩 /compact 命令 + 自动 prune
Claude Code 自动摘要压缩 上下文达 83.5% 自动触发
LangChain 全家桶 5 种 Memory 类型可选
CrewAI RAG + 四层记忆 短期/长期/实体/上下文四层
MemGPT/Letta 分层记忆 类 OS 内存管理,Agent 自主迁移
Cursor RAG + 手动引用 @ 符号引用 + 向量检索
Windsurf 全库 RAG 预索引整个代码库

没有银弹。简单场景用方法 1-2 就行,复杂 Agent 通常是方法 3-4 打底,方法 5-6 做增强。

有个有意思的趋势:越是面向开发者的 Agent(Claude Code、Cursor、Windsurf),越依赖 RAG。因为代码分析任务天然需要从大量文件中检索相关内容——你不可能把整个代码库塞进上下文。而面向普通用户的对话 Agent,更倾向于用摘要压缩——因为对话历史是线性的,摘要比检索更自然。

━━━━━━━━━━━━━━━━━━━━

◆ 一个反直觉的事实:窗口越大不代表越好

━━━━━━━━━━━━━━━━━━━━

Chroma Research 2025 年做了一个实验,发现一个反直觉的结论:所有模型随着输入长度增加都会性能退化。他们管这个叫 Context Rot(上下文腐烂)。

包括 Gemini 2.5 Pro 的 1M 窗口。

具体表现:

  • 即使模型能完美检索到上下文中的所有证据,任务完成质量仍然随输入长度下降
  • "Lost in the Middle"效应(最早由斯坦福 2023 年的研究发现,Chroma 的报告进一步验证):放在上下文中间位置的信息,回忆准确率明显低于开头和结尾
  • 大窗口减少了"撞壁"的频率(不会因为装不下而报错),但不能消除质量退化

💡 打个比方:一个书架能放 1000 本书不代表你能同时读 1000 本。书架从 100 格扩到 1000 格,你不会因为放不下书而发愁了,但你找某本书的效率反而可能下降——因为要翻的格子太多了。

tool calling 原理篇里说过一句话:“200k 的上下文窗口装得下不代表看得清——注意力分配的质量才是关键。” 现在有实验数据验证了。

结论:真正的解决方案不是无限扩大窗口,而是精准地选择放什么进去。

这也解释了为什么方法 6(RAG)有价值——与其把所有东西塞进一个巨大的上下文让模型自己找,不如只把相关的东西放进去。10K tokens 的精准上下文,可能比 100K tokens 的大杂烩效果更好。

换句话说:上下文管理的核心不是"怎么装更多",而是"怎么选更准"。 方法 1-4 在回答"怎么在有限空间里装东西",方法 5-6 在回答"怎么在需要的时候找到对的东西"。两个方向,两类问题。

━━━━━━━━━━━━━━━━━━━━

◆ Claude Code 的压缩细节

━━━━━━━━━━━━━━━━━━━━

这是大家日常最可能接触到的上下文管理实现,值得单独展开。

触发条件:上下文使用量达到 83.5%(大约 167K/200K tokens)时自动触发 compaction。

做法:Claude 分析当前对话,提取关键信息生成一段结构化摘要,替换掉旧的对话历史。新的对话从这段摘要开始。整个过程对用户透明——你会看到状态栏闪一下"Compacting conversation…",然后继续正常对话。但如果你仔细观察,会发现压缩后 Agent 的"记忆"确实变模糊了。

保留什么

  • 代码修改记录(改了哪些文件、怎么改的)
  • 架构决策(为什么选了方案 A 不选方案 B)
  • 当前任务目标(在做什么、做到哪了)
  • 命名规范和编码偏好

丢失什么

  • 对话开头设定的具体编码规范(如果没写进 CLAUDE.md)
  • 具体的文件路径和代码细节
  • 精确的指令措辞
  • "第三轮对话里你说了什么"这种精确回忆

────────────────────

社区 Workaround

Claude Code 用户摸索出了三个实用技巧来应对压缩丢信息:

1. 把重要规则写进 CLAUDE.md 文件

CLAUDE.md 是 Claude Code 每次启动都会读取的配置文件,不依赖对话历史。编码规范、项目约定、技术栈要求——写在这里就不怕压缩丢掉。

# CLAUDE.md- 使用 TypeScript strict mode- 组件用函数式写法,不用 class- API 错误统一用 Result 类型处理- 测试文件放 __tests__ 目录

2. 在任务断点手动 /compact

别等自动触发。一个大任务做完一个阶段,主动压缩一次。这样你能控制压缩的时机——在你觉得"前面的信息可以摘要了"的时候压缩,而不是在你正需要某个细节的时候被自动压缩掉。

3. "三件套"文件恢复状态

创建 plan.mdcontext.mdtasks.md 三个文件。每个阶段让 Claude 把当前状态写进这三个文件。压缩后 Claude 自动读取这些文件就能恢复工作状态——相当于手动实现了方法 5(分层记忆)的简化版。

plan.md    → 整体方案和架构决策context.md → 当前工作上下文(在看哪些文件、改了什么)tasks.md   → 任务清单和完成状态

💡 说白了,这三个文件就是给 Agent 准备的"交接文档"。压缩 = Agent 换了一个新脑子,交接文档让新脑子能快速进入状态。

这个 Workaround 本质上就是方法 5(分层记忆)的人工版——你手动把关键信息从"易失的上下文"迁移到了"持久的文件系统"。MemGPT 是让 Agent 自动做这件事,Claude Code 的用户是手动做。效果差不多,后者更可控。

────────────────────

一个实用的判断标准

什么时候该关心上下文管理?一个简单的经验法则:

  • 对话在 10 轮以内就结束 → 不用管,方法 1-2 足够
  • 对话经常超过 20 轮,或者有大量工具调用 → 至少上方法 3
  • Agent 需要跨会话记住信息 → 需要方法 5 或 6
  • Agent 需要处理大量文档/代码 → 方法 6 是必需的

OHClaw 目前的使用场景——聊几句天、查个天气、搜个东西——10 轮以内大部分都能搞定。所以 CONTEXT_WINDOW = 50 暂时没翻车。但如果你让它帮你重构一个项目、分析一堆文件,50 条消息很快就不够看了。

━━━━━━━━━━━━━━━━━━━━

◆ 回到 OHClaw:下一步该怎么改

━━━━━━━━━━━━━━━━━━━━

我们的 CONTEXT_WINDOW = 50 是最简单的方法 2(滑动窗口)。对原型验证来说完全够用——50 条消息跑个几轮工具调用绰绰有余。

但如果真要做生产级 Agent,至少得上方法 3(摘要压缩)或方法 4(混合摘要缓冲)。具体改法也不复杂:

  1. 在发 API 请求前估算 token 总量(粗略按 1 中文字 ≈ 1.5 tokens 算就行)
  2. 超过阈值(比如 80% 窗口)时,把旧消息拼成一段文本,调一次 LLM 生成摘要
  3. 用摘要替换旧消息,保留最近 5-10 轮原始消息

代码量大概多个百来行。不难,但确实有效。

伪代码大概是这样:

async function maybeCompact(messages: ApiMessage[], maxTokens: number) {    const estimated = estimateTokens(messages)    if (estimated < maxTokens * 0.8) return messages  // 还没到 80%,不用压缩    // 分成两部分:旧消息要压缩,最近 10 条保留原样    const oldMessages = messages.slice(0, -10)    const recentMessages = messages.slice(-10)    // 调 LLM 生成摘要    const summary = await llm.summarize(oldMessages)    // 系统提示 + 摘要 + 最近消息    return [        messages[0],  // 系统提示永远在        { role: 'system', content: `对话摘要:${summary}` },        ...recentMessages    ]}

不过话说回来——上下文管理只是 Agent 工程化的冰山一角。真正的挑战还在后面:多 Agent 协作时上下文怎么共享?跨会话的长期记忆怎么做?Agent 怎么知道自己"忘了"什么?

这些问题,后面再聊。

━━━━━━━━━━━━━━━━━━━━

◆ 术语速查

━━━━━━━━━━━━━━━━━━━━

术语 解释
Context Window 上下文窗口。模型一次能处理的最大 token 数量,超过就"装不下"了
Token 模型处理文本的最小单位。英文大约 1 词 ≈ 1 token,中文大约 1 字 ≈ 1.5-2 tokens
Context Rot 上下文腐烂。Chroma Research 提出的概念:输入越长,模型性能越差
Compaction 压缩。Claude Code 的术语,指把长对话摘要成短摘要以释放上下文空间
Sliding Window 滑动窗口。保留固定长度的最近消息,超出部分丢弃
MemGPT/Letta 分层记忆框架,借鉴 OS 内存管理,让 Agent 自主管理核心记忆和外部存储
ConversationSummaryBufferMemory LangChain 的混合记忆实现,旧消息摘要+最近消息原样保留
Lost in the Middle 中间丢失效应。放在上下文中间位置的信息比开头结尾更容易被模型"忘记"
RAG Retrieval-Augmented Generation,检索增强生成。从外部知识库按需检索内容注入上下文

────────────────────

AI时代,未来的就业机会在哪里?

答案就藏在大模型的浪潮里。从ChatGPT、DeepSeek等日常工具,到自然语言处理、计算机视觉、多模态等核心领域,技术普惠化、应用垂直化与生态开源化正催生Prompt工程师、自然语言处理、计算机视觉工程师、大模型算法工程师、AI应用产品经理等AI岗位。

在这里插入图片描述

掌握大模型技能,就是把握高薪未来。

那么,普通人如何抓住大模型风口?

AI技术的普及对个人能力提出了新的要求,在AI时代,持续学习和适应新技术变得尤为重要。无论是企业还是个人,都需要不断更新知识体系,提升与AI协作的能力,以适应不断变化的工作环境。

因此,这里给大家整理了一份《2026最新大模型全套学习资源》,包括2026最新大模型学习路线、大模型书籍、视频教程、项目实战、最新行业报告、面试题、AI产品经理入门到精通等,带你从零基础入门到精通,快速掌握大模型技术!

由于篇幅有限,有需要的小伙伴可以扫码获取!
在这里插入图片描述

1. 成长路线图&学习规划

要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。这里,我们为新手和想要进一步提升的专业人士准备了一份详细的学习成长路线图和规划。

在这里插入图片描述

2. 大模型经典PDF书籍

书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础(书籍含电子版PDF)

在这里插入图片描述

3. 大模型视频教程

对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识

在这里插入图片描述

4. 大模型项目实战

学以致用 ,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

在这里插入图片描述

5. 大模型行业报告

行业分析主要包括对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。

在这里插入图片描述

6. 大模型面试题

面试不仅是技术的较量,更需要充分的准备。

在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。

在这里插入图片描述

为什么大家都在学AI大模型?

随着AI技术的发展,企业对人才的需求从“单一技术”转向 “AI+行业”双背景。企业对人才的需求从“单一技术”转向 “AI+行业”双背景。金融+AI、制造+AI、医疗+AI等跨界岗位薪资涨幅达30%-50%。

同时很多人面临优化裁员,近期科技巨头英特尔裁员2万人,传统岗位不断缩减,因此转行AI势在必行!

在这里插入图片描述

这些资料有用吗?

这份资料由我们和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理,现任上海殷泊信息科技CEO,其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证,服务航天科工、国家电网等1000+企业,以第一作者在IEEE Transactions发表论文50+篇,获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。

资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的技术人员,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。

在这里插入图片描述
在这里插入图片描述

大模型全套学习资料已整理打包,有需要的小伙伴可以微信扫描下方CSDN官方认证二维码,免费领取【保证100%免费】

在这里插入图片描述

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐