Agent一大痛点:上下文空间不够了怎么办?

当你在跟Agent不停地探讨开发你的项目时,刚开始可能觉得它真是太懂我了,你说出一个需求,它三两下就完美地帮你做出来。但是当对话持续地进行下去后,可能到50轮对话后,你让它修一个bug,结果它不停地改不停地错,甚至做出一些莫名其妙的行为,这时候你就要知道------它的上下文空间不够了!LLM在得知上下文空间不足时,会感到非常焦虑,这时它会一直想赶紧仓促对任务进行结尾,这会导致它的误判行为。那么你又觉得,这个Agent怎么这么蠢,我要你何用!

为了延长这次对话寿命,那就绕不开Agent的一大核心:Context Engineering------上下文工程。本文我们就来聊聊上下文工程的实现。

一、先避开两个坑

做 Agent 遇到效果不好,很多人的第一反应是这两条路:

  1. "Agent 不够聪明,我训一个自己的模型" ------ 走 Fine-tuning 或 post-training
  2. "等产品稳定了,我用 RL 优化 Agent 的行为"

这两个坑的共同点是:都在试图改模型。但绝大多数场景下,你该改的是上下文。

二、上下文工程的五个维度

Context Engineering 的手段可以归成五类,每一类对应一个不同的问题:

  1. Offload(卸载) ------ 上下文太挤 → 把信息搬到上下文之外(文件、数据库)
  2. Reduce(压缩) ------ 上下文太长 → 压缩成更短的形式(摘要、向量化)
  3. Retrieve(检索) ------ 需要的信息不在上下文里 → 从外部源检索(RAG、文件读取)
  4. Isolate(隔离) ------ 一个上下文装不下所有的事 → 拆成多个独立上下文(Multi-Agent)
  5. Cache(缓存) ------ 重复计算 → 复用已有的计算结果(KV Cache、Prompt Cache)

遇到问题先判断属于哪一类,再挑手段,比一上来就调 prompt 有效得多。

遇到多个问题同时存在时,它们之间还有优先级:

Offload > Cache > Reduce(先紧凑化,实在不行再摘要化)> Isolate > Retrieve

下面按「先卸载、再瘦身、最后按需取回」的思路逐个说。

三、Offload:上下文窗口是昂贵的

卸载的核心思路一句话:

上下文窗口是昂贵的,但是文件系统是廉价的。

能搬到文件里、数据库里的,就别堆在上下文里。这引出了两种截然不同的加载策略:

  • 全量预填充:不管三七二十一,把 Agent 循环过程中拿到的所有信息全塞进上下文
  • JIT(Just-In-Time)按需加载:不提前塞,等 Agent 真正需要某段信息时再填充

JIT 有三种落地方式:RAG、Agentic Search(运行时用工具探索)、Context Offloading(主动卸载 + 按需恢复)。

举个例子:让你排查"登录后每次都跳首页"这个 bug。

一上来就把整个项目读一遍,是最贵的做法。更聪明的做法是按成本递增排序工具调用------先用最便宜的工具,再用稍贵的,最后用最贵的拿细节:

  1. Glob:按文件名模式搜索,只返回路径,不读内容
  2. Grep:按内容模式搜索,返回命中的行
  3. Read:读最终定位到的那几个文件

先用便宜的工具把范围缩小,再用贵的工具拿细节。这就是 Agentic Search(运行时工具探索)------"按需加载"在实践中的样子。

记忆系统本质上也是一种卸载------把跨会话的信息搬到文件或数据库里,用的时候再捞回来。这也是为什么 Agent 需要记忆:上下文窗口就像网吧的电脑,你一下机,系统就重置了,第二天再打开,什么都没了。

四、Reduce:三层压缩,先轻后重

不管你的 prompt 管理做得多好,Agent 跑完 50 轮,prompt 长度大概率会爆。

Claude Code 的思路是:先试轻手段,不行再试重手段

  1. Microcompact(紧凑化) :不删消息、不破坏对话结构,只是把老旧的工具结果缩小。第 3 轮读了个文件拿到 3000 token,到第 30 轮模型早就不需要它了,就替换成一句 [Old tool result content cleared]
  2. Snip(裁切):直接砍掉老消息,从历史记录头部开始删,被删的就永久丢失
  3. Auto-compact(摘要化):用 LLM 生成摘要。信息缺失最多,但 token 回收也最多

触发阈值是 effectiveContextWindow - 13k

Auto-compact 的摘要不是随便写的,它是一套严格的 9 段结构:用户意图、技术概念、文件改动、错误修复、问题解决、用户消息、待办任务、当前工作、下一步。

压缩完还有关键一步:把最近读过的 5 个文件内容附回去。否则模型知道"要去改 auth.ts",却不知道 auth.ts 长什么样。

五、Cache:三个层次,一条分界线

缓存分三层,可控程度不同:

  1. KV Cache:模型推理层,不受我们管控
  2. Prompt Cache :API 层,开发者可控。在 system prompt 上打个缓存断点,几千 token 的规则就不用每轮重算
  3. Context Collapse(上下文折叠):与其把老消息删掉,不如折叠起来------老消息存进外部存储,上下文里只留一个折叠标记

Prompt Cache 有个很实用的设计推论:system prompt 在静态和动态之间有一条分界线。

js 复制代码
const systemPrompt = [
  // ---- 静态部分:全局可缓存,所有用户共享 ----
  identitySection(),        // "你是 XX,负责 YY"
  systemRulesSection(),     // 环境约束
  taskGuidelines(),         // 做事方式
  riskGuidelines(),         // 行动准则
  toolUsageGuide(tools),    // 工具指南
  outputStyle(),            // 输出风格

  // ======== 分界线 ========

  // ---- 动态部分:每会话不同 ----
  envInfo(cwd, gitStatus),  // 工作目录、Git 状态
  userConfig(claudeMd),     // 用户自定义规则
  memoryContext(memories),  // Memory 内容
]

分界线以上的内容所有用户共享,能命中全局缓存;以下每会话都变。把 prompt 按这条线切开、拆成独立模块,缓存友好度和可维护性都会好很多------改输出风格时,不会碰到身份和规则。

还有个细节:高频变化的信息别写进 system prompt,注入到对话消息里。比如当前打开的文件、今天的日期,这些每轮都变,写进 system prompt 就等于每轮都把缓存打穿。

六、Isolate:多 Agent 的两种隔离

一个上下文装不下所有事的时候,就拆成多个。

  1. By communication(消息传递):主 Agent 给子 Agent 发消息,子 Agent 处理完返回结果。对主 Agent 来说,上下文里只多了「发出去的消息 + 收回来的结果」,它不需要知道子 Agent 的内部状态和处理细节
  2. By sharing context(上下文共享) :子 Agent 直接复制主 Agent 当前的上下文,在此基础上继续处理。对主 Agent 来说只多了一个结果,但子 Agent 的 token 消耗会大得多,因为它要复制一份完整的上下文

七、Retrieve:RAG 的上限在数据,不在模型

最后说检索。RAG 的管线是六步:

文档加载 → 数据分块 → Embedding → 向量储存 → 检索 → 注入上下文

流程不复杂,但每一步都会翻车:

  • 文档加载 :Markdown 最友好;PDF 最头疼,纯文本提取会丢掉表格和标题;代码不能按字符硬切------把一个函数从中间切开,两个 chunk 都会变得没意义
  • 数据分块:固定大小硬切最糙;递归分块(先段落、再句子、最后 token)准确率最高
  • 检索语义相似不等于任务相关。所以要用混合检索(向量 + 关键词)兜底

还有个常见现象:搜出来 6 条,5 条都在说同一件事。这时候要上 MMR 去重。

记住这句话:

开卷考试,翻书也可能找不到答案。数据质量决定了 RAG 的效果,而不是模型聪不聪明。

八、总结

用一条线串起来:

  1. 别急着训模型 → 效果不好先看看是不是上下文没喂对
  2. 五个维度 → 卸载、压缩、检索、隔离、缓存,对应五类问题
  3. 优先级 → Offload > Cache > Reduce > Isolate > Retrieve
  4. 加载策略 → 全量预填充 vs JIT 按需加载,按成本递增调工具
  5. 压缩 → Microcompact → Snip → Auto-compact,先轻后重
  6. 缓存 → 把 prompt 按静态/动态切开,让静态部分稳定命中缓存

Agent Loop 是心跳,Tool System 是手脚,而 Context Engineering 是它的记忆和注意力------决定了它能跑多远,也决定了它跑到最后还记不记得自己要去哪

相关推荐
weixin_435208162 小时前
pi agent 扩展与 hook 机制浅析
人工智能·agent
是Guava不是瓜娃3 小时前
开源 AI Agent 中台 AgentOne(灵一)---私有部署、数据不出域的企业级 AI 助手
ai·agent·ai agent·skill·agentscope·agent 中台
Flynt4 小时前
Astra 自主跑了 35 小时烧掉 40 亿 token,产出为零:我给 Agent 加了三道闸
python·aigc·agent
山间小僧9 小时前
「AI学习笔记」Agent Memory(二)跨会话记忆:从聊天记录到可演化的长期记忆
aigc·agent·vibecoding
dong_junshuai16 小时前
每天一个开源项目#99 OpenResearch:2.2K星的本地研究Agent工作台
开源·github·agent
花椒技术16 小时前
把 AI 视频接进直播:提前生成、按次生成、持续生成怎么选?
agent·音视频开发
用户80825986668716 小时前
用 LangGraph 重写自己手写的 Agent:框架替你解决了什么,什么它不管
agent
能不能静下心来看16 小时前
从 RAG 到 Agent:跑通两个 Demo 后,我终于分清了这两个词
agent
ZGi.ai16 小时前
知识库权限变了,怎样避免答错?
agent·权限管理·知识库·工作流·zgi·客服运营