第 1 课:上下文窗口就是 Agent 的全部记忆
学习目标:
- 解释"Agent 记得住之前的对话"这句话为什么是一种幻觉
- 说出一次请求的上下文窗口里,哪些内容算数、哪些不算数
- 解释「上下文腐化」是什么现象,为什么窗口更大不等于更好用
- 判断一次 API 调用是不是无状态的,以及这对记忆意味着什么
前置要求:读过前 4 门课,理解工具调用的往返协议 | 下一课 第 2 课 >>
一个看起来"记得住"的对话
你在跟一个客服 Agent 聊天:
第二轮里 Agent 显然"记得"你叫王芳、记得你问的是 ORD-2026-8842。这看起来就像它把这些信息存进了某个地方,下次见面还能想起来。
真相要朴素得多:每一次请求,你的代码都会把从对话开始到现在的全部消息重新打包,原样发给模型1。模型看到的不是"我记得你叫王芳",而是每次都重新读到一遍"用户说过:我叫王芳"。上一轮的每一句话、每一次工具调用,都得靠你的代码亲手塞进这一轮的请求里——模型自己什么都不存。
API 调用是无状态的
这句话说得再直白一点:模型这一次调用和下一次调用之间,没有任何东西被服务器悄悄留下来。这一次请求处理完,那些 token 就从模型"眼前"消失了。下一次请求如果什么都不带,模型看到的就是一张白纸,连你叫什么都不知道。
之所以感觉"记得住",是因为宿主应用替你做了这件苦力活:把完整的历史消息数组重新发一遍。这不是模型的能力,是你代码里那个数组在增长。这个特性有个名字,叫无状态——官方文档的原话是:Messages API 是无状态的,这意味着你每次都要把完整的对话历史发给 API1。服务器不为你的会话保留任何跨请求的私有状态,一切"记忆"都得由客户端自己携带、自己重发。
上下文窗口里,到底装了什么
模型能看到的东西,全部装在一个叫上下文窗口的容器里。官方文档说得很明确:一次请求里的所有东西都算数——系统提示词、messages 数组里的每一条消息(包括工具结果、图片、文档)、你传进去的工具定义,连模型这一轮自己生成的输出(包括扩展思考)也算在内。2
这份请求里,system、tools、messages 数组里的三条消息,全部计入上下文窗口。模型的回答生成出来之后,那部分输出 token 同样要算进当前这一轮的窗口用量。响应里会带一个 usage 字段,告诉你这一轮实际消耗了多少输入和输出 token。2
没被塞进这份请求的东西——比如数据库里那笔还没被工具查询过的订单记录——不属于上下文窗口的一部分。模型看不到它,也没法凭空知道它存在。这就是为什么"记忆"必须靠某种机制主动搬进这份请求,而不是自动可及的。
窗口会腐化,不是越大越好
窗口能装多少东西是有上限的——不同模型的容量不同,官方文档给出的口径是最大可以到 100 万 token。2 但这不意味着往里面塞得越满越好。文档里点名了一个现象,叫上下文腐化:随着 token 数越堆越多,准确率和召回率会下降。2 也就是说,窗口里装的内容越多、越杂,模型从中提取出正确答案的能力反而会打折扣——这让"往上下文里放什么"本身,变得和"窗口还剩多少空间"一样重要。2
这一点对"记忆"的设计影响很直接:把整段历史无脑塞进上下文,既不是免费的(会占满窗口容量),也不是没有代价的(会让模型在一堆陈旧信息里更难找到当前真正相关的那句话)。第 2 课会讲具体怎么应对这种累积——历史该怎么截断、怎么摘要,而不是放任它无限增长。
"记忆"这个词,其实是个比喻
回到开头那个客服对话。当我们说"Agent 记得你叫王芳"时,准确的说法应该是:你的代码把包含"我叫王芳"这句话的完整历史,又一次原样发给了模型,模型在这次请求里重新读到了它。没有存储,没有回忆,只有重发。
这不是在抠字眼。理解"记忆是重发出来的幻觉",直接决定了你接下来怎么设计一个真正"记得住"的 Agent:
- 如果历史消息数组会无限增长,窗口迟早会被填满,还会撞上上下文腐化——这是第 2 课要解决的问题。
- 如果有些信息需要在多个会话之间留存(不只是这一次对话内),就不能指望塞进 messages 数组里,得写到外部才行——这是第 3 课要讲的外部记忆。
- 如果 Agent 需要在任务中途知道"自己做到哪一步了",这份进度同样得是上下文窗口里能看到的结构化状态,而不是模型凭直觉猜——这是第 4 课的内容。
这三条线索,其实都是同一个事实的不同推论:窗口里有什么,模型才知道什么;窗口里没有的,对模型来说就是不存在的。
小结
- "Agent 记得住之前的对话"是一种幻觉:真相是宿主应用每次把完整历史重新塞进请求,模型自己不存储任何东西1
- API 调用是无状态的,服务器不为会话保留跨请求的私有状态,一切"记忆"都得由客户端主动携带1
- 上下文窗口装的是这次请求实际携带的一切:系统提示词、messages 里的每条消息(含工具结果、图片、文档)、工具定义,以及模型本轮的输出2
- 窗口大小是有上限的,而且更大不等于更好用——上下文腐化会让 token 越堆越多、准确率和召回率越下降2
- 理解"窗口里有什么模型才知道什么",直接引出后面三课要解决的问题:历史怎么管理、记忆怎么外部化、状态怎么结构化
>> 第 2 课:对话历史管理:追加、截断、摘要