一、问题的起点
理解大语言模型(LLM)的”记忆”机制,最常见的误区是将 context 类比为”对话历史”。事实上 context 远比对话历史复杂——它包含 system prompt、工具定义、MCP 注册、tool result、thinking 块等大量用户不可见的内容,对话历史仅是其中一小部分。更进一步的误区是把 context 混同于模型的”知识”——事实上模型的知识固化在训练好的权重中,与 context 完全独立。
Context 的精确定义来自 Anthropic 官方文档:Context 是 LLM 在生成响应时能够引用的全部 token 序列,包括即将输出的响应本身。它是模型的”工作记忆”,每次 API 调用现场构造,调用结束即清空。理解这一点是后续所有 Agent 工程问题(记忆、压缩、检索、Agent 编排)的起点。
要理解 context 为什么是 Agent 工程的核心问题、为什么”context 越大越好”是错觉、为什么 RAG / Compaction / Subagent 等技术都为它而生,前提是搞清楚:context 在工程上由什么构成、它如何累积、它的边界在哪里、为何会”腐烂” (Context rot)。
二、Context 的内部构成
Context 在工程上是一个结构化的 messages 数组,由四种 role 与多种 content block 组成。四种 role 分别承担不同职责:system 定义全局规则、人设、输出约束,user 是人类输入,assistant 是模型回复,tool 是工具调用的执行结果。API 强制约束第一条 message 必须是 user,user 与 assistant 必须严格交替,tool 消息必须紧跟一个发起调用的 assistant。Anthropic 官方明确说明 system 在训练时被赋予更高优先级——即使用户在对话中说”忽略前面的指令”,system 中写的约束通常依然被遵守,这是 system 这个 role 存在的根本意义。
一条 message 内部还可继续拆分为多种 content block:普通 text 块、image 块(仅 user 可用)、tool_use 块(assistant 决定调用工具)、tool_result 块(工具返回值)、thinking 块(reasoning 模型的内部推理)、document 块(PDF 等结构化文档)。一个反直觉的细节是:tool_result 的 role 是 user 而非 tool,因为 Anthropic 的设计逻辑是工具执行器站在用户侧,把执行结果”递给”模型,所以包装成 user 消息注入。
各部分的 token 占比直接决定 Agent 的成本结构与可用容量。下表列出实战中典型的 token 占用情况:
| 组成部分 | 典型占用 | 备注 |
|---|---|---|
| System prompt | 200–3000 tokens | 复杂 Agent 可上万 |
| 工具定义(每个) | 200–800 tokens | 接入 10 个工具就是几千 |
| MCP 自动注册(每个 server) | 数千 tokens | 多 server 场景轻松上万 |
| 历史 user 消息 | 小 | 单条几十到几百 |
| 历史 assistant 输出 | 中 | 单条几百到几千 |
| tool_result | 每次几百到几万 | Agent context 最大消耗 |
| Thinking 块 | 几百到几千 | reasoning 模型显著占用 |
Agent 系统中,tool_result 才是 context 真正的消耗大头。一次代码库搜索可能返回 10KB 文本,一次数据库查询可能返回 50KB JSON,这些数据原样塞回 context,几轮工具调用下来 context 就满了。所有 context 压缩策略,第一刀都砍向 tool_result。
三、API 的无状态性
Anthropic 官方文档原文:“The Messages API is stateless, which means that you always send the full conversational history to the API.”
无状态是计算机科学的术语,意思是服务端不保存任何会话信息,每次请求必须自带所有需要的内容。这对 Agent 工程产生了根本性影响:模型本身从不记忆任何东西,所谓的”会话连续性”完全是应用层把历史回传给 API 的工程结果。
多轮对话的实际机制是这样的:第一轮用户说”我叫 Michael”,应用发给 API;第二轮用户问”我叫什么名字”,应用必须把第一轮的内容一起回传,模型才能”记得”。若应用只发当前问题不回传历史,模型会真实地回答”我不知道”——它从未”记住”过任何东西。这一机制带来的工程后果是:所有看起来像”记忆”的能力(ChatGPT memory、Claude Projects、Copilot personalization)本质上都是应用层在每次请求时把相关信息拼接到 context 里。
四、Context 的累积机制
由于 API 无状态,多轮对话的 context 必然单调递增。Anthropic 官方文档将此过程总结为三条规律:progressive token accumulation(渐进累积)——每轮的 user 与 assistant 消息被永久保留;linear growth pattern(线性增长)——context 占用随轮次线性上涨;capacity ceiling(容量天花板)——所有累积内容加上即将输出的内容,总和不得超过模型最大 context。
在 Agent 场景下,问题更严峻。普通 chatbot 每轮可能增加 1–2K tokens,Agent 每轮可能伴随多次工具调用——一次搜索返回 5KB JSON,一次文件读取返回 12KB 文本,一次 API 查询返回 8KB 数据——单轮 context 增量可达 20K 以上。Claude Code 官方文档明确指出:在用户输入第一条消息之前,context 中已被系统提示、CLAUDE.md、所有 MCP 工具定义、Skill 描述、路径作用域规则等内容占满,一个复杂任务可能开局就消耗几万 token。这是 Agent 比 chatbot 烧 context 烧得快得多的根本原因,也是 context 工程在 Agent 系统中被推到第一优先级的原因。
五、Context 是输入与输出共享的同一池子
一个被大量误解的工程事实:context window 是输入与输出共享的同一额度,不是只算输入。若模型 context 上限为 200K,输入塞入 199K,留给输出的仅剩 1K。许多 API 调用中模型回答突然戛然而止、max_tokens 设大也写不完的根源就在这里。
主流模型当前的 context 容量参考:GPT-5.4 在 API 中标称 1.05M tokens(max output 128K),Claude Sonnet 4.6 支持原生 1M tokens,Gemini 2.5 Pro 同样支持 1M tokens 量级。需要注意 max output 通常远小于 context 上限——模型可以”看到”百万 token,但一次性”输出”不超过十几万 token。这是工程决策中容易踩坑的细节。
六、Context Rot:长上下文性能退化
业内一度认为 context window 越大越好,但 2025 年 7 月 Chroma 团队发布的《Context Rot》技术报告系统性推翻了这一假设。该研究测试了 GPT-4.1、Claude 4、Gemini 2.5、Qwen3 等 18 个前沿模型,结论极为明确:模型并不会均匀地使用 context;随着输入长度增加,模型表现愈发不可靠。Anthropic 官方文档已正式采用 context rot 这一术语,并在 context windows 页面警告:“随着 token 数量增加,准确率与召回率会衰减——所以精心策划放什么进 context,和能放多少一样重要。”
Context rot 必须与 context 溢出严格区分。溢出是二元失败——超过 token 上限时请求被截断或拒绝,会报错;context rot 是连续退化——在远未达到上限时输出质量已经悄悄下降,不报错也不提示。一个 200K context 的模型,可能在 50K tokens 时就已出现明显性能下降。Chroma 研究的核心贡献是揭示:衡量上下文质量的正确指标不是容量,而是信噪比(signal-to-noise ratio)。
Context rot 的成因可从三个层面理解。架构层面:Transformer 的 self-attention 要求每个 token 与所有其他 token 建立 n² 关系,序列越长注意力越被稀释。训练分布层面:训练语料绝大多数是中短文本,长距离依赖在训练分布中被低估,模型对长上下文的推理能力本身就训练不足。应用层面:Agent 在搜索、探索、回溯过程中持续累积噪声 token,这些噪声直接降低后续每一步的输出质量。
七、大窗口模型是否一定更好
由 context rot 引出的精确判断:窗口大小决定”能不能做”,模型代际决定”做得好不好”。
在两者都能装得下的区间(例如同为 50K 输入的小数据量场景),大窗口模型并不天然更好——其表现主要由模型本身的能力决定,不由窗口上限决定。许多场景下感受到的”大窗口模型表现更好”,真正起作用的是”大窗口模型通常是更新一代、训练更充分”,而非”窗口大”这个属性本身。但一旦数据量逼近或超过小窗口上限,大窗口模型就拥有绝对优势——因为小窗口模型已经直接出局。
此外,大窗口模型在工程上还有两个隐性价值。第一是 buffer 余量:Agent 的 context 用量不可预测,大窗口允许 compaction 触发更晚,对应更少的额外 LLM 调用与更少的信息损失。第二是新一代模型的 long-context 训练本身更充分:Gemini 2.5、Claude Sonnet 4.6 在 1M context 上的表现已显著优于上一代模型在 200K 上的表现,context rot 在变弱,只是变弱的速度跟不上容量增长的速度。
八、Context Engineering:新一代工程范式
Anthropic 在 2025 年 9 月 29 日发布博文 Effective Context Engineering for AI Agents,正式将 context engineering 定义为 prompt engineering 的自然演进。两者的本质差异在于关注对象与时间维度:Prompt engineering 关注 system prompt 的写法——一次性的、离散的、静态的写作任务;Context engineering 关注每次推理时往 context 里放什么——持续的、动态的、跨轮次的策划过程。在多轮 Agent 场景中,每一个 inference loop 都会产生新数据,这些数据是否应进入下一轮 context、以何种形式压缩、何时丢弃,构成了 context engineering 的核心工程问题。
Anthropic 给出的核心原则可归纳为五条:第一,将 context 视作稀缺资源进行预算管理——由于 context rot 的存在,无脑塞入更多内容只会降低质量,每个进入 context 的 token 都应有明确价值;第二,system prompt 应在”明确”与”灵活”之间取得平衡——过度工程化的硬规则脆弱易碎,过于模糊的指导无法引导行为;第三,工具定义是 Agent 与环境的契约——工具集应小而精,每个工具的输入输出、副作用、错误模式应清晰可预测;第四,长会话必须有压缩机制;第五,subagent 模式隔离上下文污染。
九、Context 管理的六类工程手段
实践中存在六类主流的 context 管理手段,分别对应不同层次的工程问题。各方案的信息损失、实现复杂度、适用场景差异显著:
| 方案 | 信息损失 | 复杂度 | 主要适用场景 |
|---|---|---|---|
| 截断(滑动窗口) | 高 | 极低 | 简单 chatbot |
| 摘要(Compaction) | 中 | 中 | 长会话 Agent |
| Tool Result Clearing | 低 | 中 | 工具调用密集场景 |
| Subagent 隔离 | 极低 | 高 | 复杂任务分解 |
| RAG(检索式补充) | 取决于检索质量 | 高 | 跨会话长期记忆 |
| Code Execution with MCP | 极低 | 极高 | 大量 MCP 工具场景 |
截断是最朴素的方案,超过阈值丢掉最早几轮对话,实现成本零但早期重要信息直接丢失。摘要(Compaction) 是 Claude Code 的 /compact 命令的核心机制——让另一个 LLM 调用把早期对话总结成结构化摘要,保留任务目标、关键决策、文件状态,丢弃探索过程、被否决的方案、详细 tool_result。摘要由 LLM 生成本身消耗 tokens,且不可逆——一旦压缩被丢的细节就回不来了,但这是当前长会话 Agent 的主流方案。Tool Result Clearing 是专门针对 tool_result 吞噬者的优化——清除中间探路失败的 tool_result 内容但保留对应的 tool_use 调用记录(否则 API 会因不匹配而报错)。Subagent 隔离 是结构性方案:把大量文件读取、搜索操作放入独立 subagent 的 context 中执行,主对话只接收 subagent 返回的摘要,主 context 始终保持干净。RAG 处理跨会话长期记忆,将历史会话/文档存在向量库中,每次请求时只检索与当前问题相关的几段注入 context。
Code Execution with MCP 是 Anthropic 2025-11 提出的最新方案,应对”工具爆炸”问题——当 Agent 接入大量 MCP 工具时,工具定义本身就能塞满 context,解决方案是让 Agent 生成代码调用工具而非直接调用,代码在沙箱执行,仅最终结果回 context。
成熟的 Agent 系统通常组合使用多种方案。Claude Code 同时用了 system prompt 优化、subagent、tool result clearing、/compact 摘要四种机制。
十、Prompt Caching:成本优化的关键机制
Anthropic 的 prompt caching 是 context 工程中无法跳过的成本优化手段。其机制是将稳定的前缀(system prompt、工具定义、长背景资料)缓存在服务端,5 分钟内的后续请求只为变化部分付费。命中缓存的 token 价格降至正常输入的 10%,首次写入价格为 125%。对于多轮会话或固定模板场景,节省比例可达 80–92%。
缓存遵循严格的前缀层级:tools → system → messages,任一层级变更会使该层及之后的所有缓存失效。具体规则:修改工具定义会使整张缓存失效;修改 system 会使 system + messages 缓存失效;修改 tool_choice 仅使 messages 缓存失效。模型对缓存有最小 token 门槛——Claude Sonnet/Haiku 系列要求 ≥1024 tokens,Opus 系列要求 ≥4096 tokens,低于门槛的内容不被缓存。这一机制在工程上的直接影响是:工具集应结构稳定、版本受控,频繁修改工具定义会导致 caching 优化完全失效。
十一、Context 与 Memory 的关系
容易混淆的一对概念是 context 与 memory。Context 指单次推理请求中模型实际看到的全部 token 序列,是模型的工作记忆,调用结束随请求消失。Memory 指跨会话保留的信息,由应用层实现,通常落地在数据库、向量库、知识图谱中。模型本身没有 memory,所谓”模型记得用户偏好”本质上是应用层在每次请求时将相关 memory 提取并注入到 context 中。
二者的关系可类比为:Memory 是磁盘,Context 是 RAM。每次请求时,应用层从 memory 中取出与当前任务相关的片段,连同 system prompt、对话历史、工具定义一起组装成 context 交给模型;模型完成推理后,应用层决定是否将本轮的新信息回写到 memory。
十二、由该机制衍生的常见现象
理解 context 是模型的”工作记忆”、API 无状态、context window 输入输出共享、context rot 存在等核心事实后,许多平时让人困惑的现象可获得统一解释。
| 现象 | 原因 |
|---|---|
| 同一个 Claude 网页对话聊得太久会前后矛盾 | 早期对话被 compaction 摘要时丢失了关键细节 |
| API 调用第二轮完全失忆 | API 无状态,应用未回传第一轮的 messages |
| ChatGPT 偶尔”忘了”之前提过的事 | 该信息未进入当前会话的 context(memory 未匹配或已超容量) |
| 同样 prompt 在 GPT-4 与 GPT-5 输出截然不同 | 模型代际差异,与 context 无关 |
| 1M context 模型在 50K 输入上感觉”更聪明” | 主要是模型代际差异,窗口大小本身贡献小 |
| 长对话末尾模型答非所问 | context rot——长 context 上准确率下降 |
| Agent 跑几轮后突然变慢 | tool_result 累积导致 context 接近上限,处理变慢 |
| 修改工具定义后 prompt caching 失效 | 工具定义在 tools 层级,变更使整张缓存失效 |
| 同样问题某次答对某次答错 | 不同会话 context 内容不同,导致行为差异 |