第 8 章:上下文窗口管理——Agent 的“工作台”整理术
上下文窗口是 Agent 的短期记忆。如果不去管理它,Agent 就会变成《福尔摩斯》里的华生——虽然一直在场,但关键时刻总是什么都记不住。
你让 Agent 帮你调试一个生产事故。 对话进行了 50 轮,它终于通过日志定位到是数据库连接池配置不对。 这时你追问了一句:“那你觉得我该怎么改?” 它回答:“抱歉,我不知道你在说什么数据库。”
那一刻,你一定会愣住。 50 轮对话,烧了几万 Token,结果它把最关键的上下文忘了?
这不是 Agent 变笨了,是 上下文管理(Context Management) 没做好。本章我们来聊聊如何解决这个让无数产品经理抓狂的问题。
01. 为什么 Agent 会“失忆”?
LLM(大模型)有一个核心概念叫 上下文窗口(Context Window) 。 你可以把它理解为 Agent 的 工作台。
- 工作台大小是有限的:GPT-4o 约 128k,Claude 3.5 约 200k。
- 每一次对话都要重铺工作台:LLM 是无状态的。你说第 51 句话时,系统必须把前 50 句话全部重新发给它,它才能理解上下文。
这带来了三个致命问题:
- 空间不够(超限) :工作台堆满了,新资料放不上去,请求直接报错。
- 记不住(遗忘) :为了腾空间,系统可能把前面的关键信息(比如数据库密码)给扔了。
- 太贵了(成本) :聊天记录越长,每次请求带的数据越多。就像每次去超市只买一瓶水,却要付整车的运费。
管理的核心目标: 在有限的工作台空间里,尽可能保留最有价值的信息。这本质上是一个 信息熵 的取舍问题。
02. Token:Agent 世界的货币
在讨论管理之前,先得搞懂计量单位:Token。
Token 不是字符,也不是单词,它是 LLM 理解文本的 最小单位。
- 英文:
Apple≈ 1 个 Token - 中文:
苹果≈ 1-2 个 Token - 代码:
function≈ 1 个 Token
为什么不算字符? 因为 LLM 按照语义切分。
工程实践中的估算公式: 为了性能,我们通常不进行精确计算(那样太慢),而是采用 模糊估算:
估算公式: 1 个中文汉字 ≈ 1.5 Token 4 个英文字符 ≈ 1 Token 安全冗余:在此基础上增加 10% 的缓冲空间。
这就像去菜市场买菜,你不需要精确到克,大概掂量一下别超重就行。
03. 三大主流“瘦身”流派
除了基础的暴力截断,目前业界主流的上下文压缩策略主要分为三派。它们不是互斥的,通常会混合使用。
流派一:滑动窗口+摘要(The Summarizer)
核心思想:保留两头,压缩中间。 这是 Shannon 框架的主力策略,适合连续对话场景。
- 头部(Primers) :保留最初的 3-5 轮(初心锚点),防止目标漂移。
- 中部(Summary) :中间漫长的 50 轮试错,调用一个小模型压缩成一段 200 字的摘要。
- 尾部(Recents) :最近的 10 轮完整保留,保证“刚才那个代码”这种指代能被听懂。
比喻:就像人类的记忆,清楚记得刚才发生的事(尾部),模糊记得很久以前的大概(中部摘要),但永远记得自己的人生目标(头部)。
流派二:向量检索(The Librarian)
核心思想:别把书都背在身上,要用的时候去图书馆查。 这是 RAG(检索增强生成) 在记忆管理上的应用。
- 做法:当对话太长时,把旧的对话切片,存入向量数据库(如 Chroma、Milvus)。
- 触发:当用户问“之前报错的日志是什么”时,系统先去数据库里“检索”最相关的几条历史记录,临时插到上下文里。
- 优点:理论上可以拥有无限的记忆,而且不占当前的 Token 预算。
比喻:Agent 随身只带一本笔记本(Context Window),旧资料都扔进档案室(Vector DB)。需要时让管理员送过来。
流派三:实体记忆(The Profiler)
核心思想:只记重点,不记流水账。
- 做法:在对话过程中,实时抽取关键实体(Key-Value)。
- 效果:系统维护着一个 JSON 小本本:
{ "User": "Java工程师", "Database": "MySQL 5.7", "Error": "Connection Timeout" } - 优点:无论对话多长,这个 JSON 只有几百 Token,但包含了最核心的上下文。
比喻:就像医生写病历,不会把你说的每一句废话都记下来,只记“症状、病史、过敏源”。
04. 成本控制:不只是“抠门”
解决了“记不住”的问题,还得解决“太贵”的问题。除了硬性的预算限制,还有更聪明的省钱办法。
策略 A:多级熔断(防止破产)
这是最基础的风控:
- Session 总闸:整个任务限额 10 万 Token。
- Task 分闸:单个搜索步骤限额 5000 Token。
- Agent 单兵限额:防止某个 Agent 死循环。
策略 B:模型路由(Model Routing)
核心思想:杀鸡焉用牛刀。 目前最流行的降本方案,也叫“大小模型混用”。
-
做法:
- 简单的意图识别、总结摘要:路由给 GPT-4o-mini 或 Claude Haiku(极其便宜)。
- 复杂的代码生成、逻辑推理:路由给 GPT-4o 或 Claude 3.5 Sonnet(昂贵但聪明)。
比喻:这就像开公司。你不会雇佣一个年薪百万的教授(大模型)去前台取快递,这种事交给实习生(小模型)做就好。
策略 C:语义缓存(Semantic Cache)
核心思想:不要为同一个问题付两次钱。
- 做法: 如果用户问了“怎么配置 MySQL”,过了一会儿又问了“MySQL 配置方法”。 系统计算语义相似度,发现是同一个问题,直接把上次 AI 生成的答案拿出来,改个称呼发回去。
- 效果:Token 消耗为 0,响应速度极快。
05. 背压机制:优雅的限流
当预算快用完,或者系统负载过高时,直接报错(500 Error)是非常粗暴的。 Shannon 参考了网络工程中的 背压(Backpressure) 机制。简单来说就是:我不直接拒绝你,但我会让你知道我很忙。
常见的背压策略有三种:
策略一:延迟响应(Throttling)
逻辑:让用户感觉到“慢”,从而自觉降低频率。
- 做法:预算使用 80% 时,人为增加 500ms 延迟;95% 时增加 2s 延迟。
- 心理学原理:通过负反馈调节用户行为。
策略二:服务降级(Degradation)
逻辑:忙不过来时,只提供基础服务。
- 做法:当系统检测到高并发或预算紧张时,自动将本来应该由 GPT-4o 处理的非关键请求,降级 路由给 GPT-4o-mini。
- 比喻:这就像米其林餐厅爆满时,不再接受单点大餐,只提供“快速套餐”,虽然体验降级,但至少能让你吃上饭。
策略三:排队缓冲(Buffering)
逻辑:削峰填谷。
- 做法:不立即处理请求,而是放入队列,告诉前端“Agent 正在思考中...”(其实是在排队)。
- 比喻:银行的取号机。窗口虽忙,但你领了号坐在等候区,就不会觉得被直接拒之门外,系统也能按自己的节奏慢慢处理。
06. 最佳实践配置清单
给产品经理的一份“避坑指南”:
| 场景 | 推荐压缩流派 | 推荐成本策略 | 建议 |
|---|---|---|---|
| 代码调试 | 滑动窗口 (细节最重要) | 大模型为主 | 代码细节多,压缩容易丢关键符号,尽量完整保留最近 30 轮。 |
| 闲聊客服 | 向量检索 (知识面广) | 小模型 + 缓存 | 很多问题是重复的(如退款政策),缓存能省大钱。 |
| 长文写作 | 实体记忆 + 摘要 | 混合路由 | 用小模型写大纲,大模型润色段落,实体记忆记住文章设定。 |
总结
上下文窗口管理,本质上是在 有限的算力 和 无限的信息 之间做平衡。
- 三大流派:滑动窗口(保连贯)、向量检索(保广度)、实体记忆(保精度)。
- 省钱三招:预算熔断(保底)、模型路由(分工)、语义缓存(复用)。
做好了这几点,你的 Agent 才能在长跑中保持清醒,既不会把老板聊破产,也不会聊着聊着就忘了自己是谁。
下一章预告
上下文窗口管理解决了 短期记忆 问题——单次对话内的上下文。但 Agent 如何在跨会话、跨任务之间保持 长期记忆?
下一章我们来聊 记忆架构 ——如何通过向量数据库实现语义检索和知识积累。
准备好了?往下走。