中文译本。原文见同目录 README.md
第 5 课:记忆与上下文(Memory and Context)——智能体如何记住
你将学到什么
- 上下文窗口(context window)如何工作,以及为何重要
- 上下文工程(context engineering)如何从提示词工程(prompt engineering)演进而来
- 智能体记忆类型:短期(short-term)、长期(long-term)、程序性(procedural)与陈述性(declarative)
- Session(会话)如何为智能体提供对话连续性
- Memory(记忆)与 RAG 的区别
- 什么是上下文腐烂(context rot),以及如何应对
- 管理上下文的实用策略
- 记忆存储选项:向量数据库、知识图谱与混合方案
前置条件
ELI5:把上下文想成一张桌子
想象你在一张桌子上工作。这张桌子就是智能体的上下文窗口——你把正在用的东西都放在这里。
桌子空间有限。你可以摊开笔记、参考书、笔记本电脑和一杯咖啡。但如果不断往上堆,桌子终会乱到找不到东西。重要的笔记被不太相关的纸张埋住,你开始忘了自己在做什么。
AI 智能体的上下文也是如此。上下文窗口是智能体的工作台面。智能体需要思考的一切——用户问题、对话历史、工具结果、指令——都必须装进这张桌子。桌子满了,智能体就要决定留下什么、拿走什么。
良好的记忆管理就像把桌子整理好:把重要的东西保持可见、可取用,把次要信息存到之后还能找到的地方。
上下文窗口详解
什么是上下文窗口?
上下文窗口是 LLM 在单次请求中能处理的文本总量(以 token 计量)。可以把它看成模型的工作记忆——它一次能「看见」的全部内容。
+------------------------------------------------------------------+
| CONTEXT WINDOW |
| |
| [System instructions] |
| [Tool definitions] |
| [Conversation history - user and agent messages] |
| [Retrieved documents / RAG results] |
| [Current user message] |
| [Agent's working thoughts] |
| |
| ... all must fit here ... |
+------------------------------------------------------------------+
上下文窗口大小
上下文窗口已经大幅增长:
| 模型 | 上下文窗口 |
|---|---|
| GPT-3 (2020) | 2K tokens |
| GPT-4 Turbo (2023) | 128K tokens |
| Gemini 1.5 Pro (2024) | 1M tokens |
| Gemini 3.1 Pro (2026) | 1M tokens |
一个 token 大约相当于英文 3/4 个单词。因此 100 万 tokens 大约是 75 万词——约等于 10 本小说的篇幅。
更大并不总是更好
你可能觉得更大的上下文窗口能解决所有问题。它有帮助,但也有权衡:
| 因素 | 小上下文 | 大上下文 |
|---|---|---|
| 成本(Cost) | 每次请求更便宜 | 每次请求更贵 |
| 延迟(Latency) | 响应更快 | 响应更慢 |
| 准确度(Accuracy) | 更聚焦、噪声更少 | 可能在海量文本中难以找到相关信息 |
| 简洁性(Simplicity) | 迫使你做筛选 | 容易忍不住把一切都塞进去 |
研究表明,LLM 对放在很长上下文中间的信息可能处理不好——有时称为「lost in the middle」(中间迷失)效应。你能塞进 100 万 tokens,并不意味着你应该这么做。
从提示词工程到上下文工程
提示词工程:起点
提示词工程关注如何写出合适的输入文本,让 LLM 给出好输出。你写一个相对静态的提示(或许带几个示例),然后发出去。
这对简单任务很有效,但对智能体就不够了。为什么?因为智能体要面对动态、变化的信息:
- 对话历史随每一轮增长
- 工具结果在运行时返回
- 检索到的文档随查询变化
- 用户需求在会话中途演变
上下文工程:下一步
上下文工程是在正确的时间,把正确的信息动态组装进上下文窗口的实践。不再是静态提示,而是构建一个会做决策的系统:
- 放什么进去: 此刻哪些信息相关?
- 什么留在外面: 哪些可以摘要、外置存储或丢弃?
- 以什么顺序: 信息如何排列,模型才能处理得最好?
- 何时刷新: 旧上下文何时需要更新或替换?
可以把提示词工程想成写一封好邮件;上下文工程则是建造邮件系统。
为什么上下文工程对智能体很重要
Prompt Engineering: Context Engineering:
+------------------+ +---------------------------+
| Static prompt | | System instructions |
| + user question | | + Relevant memory |
| | | + Session history (pruned) |
| | | + Tool schemas (selected) |
| | | + Retrieved context |
| | | + Current task state |
| | | |
| "Answer this" | | All dynamically assembled |
+------------------+ +---------------------------+
订酒店的智能体与写代码的智能体需要不同的上下文。即便是同一个智能体,在任务不同阶段也需要不同上下文。上下文工程让这种动态组装成为可能。
记忆类型
智能体出于不同目的需要不同类型的记忆。这与人类记忆的运作方式类似。
短期记忆(会话/对话)
是什么: 用户与智能体之间的当前对话。它直接驻留在上下文窗口中。
人类类比: 你的工作记忆——此刻正在主动思考的内容。
特征:
- 存在于一次会话期间
- 随每次交互增长
- 受上下文窗口大小限制
- 会话结束即丢失(除非做了持久化)
示例:
User: "My name is Alex and I prefer dark mode."
Agent: "Got it, Alex. I will use dark mode settings."
[50 messages later]
User: "What theme am I using?"
Agent: "You are using dark mode, Alex." <-- Only works if the earlier
message is still in context
长期记忆(跨会话持久化)
是什么: 存储在上下文窗口之外、跨会话仍然存在的信息。相关时智能体会检索并加载。
人类类比: 你的长期记忆——学过的事实与经历,即便此刻没有在想它们。
特征:
- 跨会话存活
- 外置存储(数据库、文件系统、向量库)
- 必须显式检索并载入上下文
- 可以无限增长
示例用途:
- 用户偏好(「Alex 喜欢暗色模式,使用 TypeScript」)
- 过往交互(「上周 Alex 问过如何部署到 Cloud Run」)
- 学到的事实(「生产数据库在 us-central1」)
程序性记忆(如何做事)
是什么: 关于如何执行任务的知识——工作流、标准操作流程与逐步过程。
人类类比: 知道如何骑自行车或打字。你不会逐步想每一步——你就是会。
特征:
- 常编码在系统指令或工具定义中
- 相对稳定——不常变化
- 包含模式、模板与标准流程
示例:
Procedural memory: "When a user reports a bug:
1. Ask for reproduction steps
2. Check the error logs
3. Search for similar issues
4. Propose a fix or workaround"
陈述性记忆(事实与知识)
是什么: 智能体知道或可访问的事实信息——数据、文档、规格与参考材料。
人类类比: 知道巴黎是法国首都。这是你能陈述的事实,不是你执行的技能。
特征:
- 可通过 RAG 动态检索
- 包括文档、数据库与知识库
- 可能过时,需要更新
记忆类型小结
| 记忆类型 | 持续时间 | 位置 | 如何更新 | 示例 |
|---|---|---|---|---|
| 短期(Short-term) | 一次会话 | 上下文窗口 | 自动(对话增长) | 当前聊天消息 |
| 长期(Long-term) | 跨会话 | 外部存储 | 由智能体或系统显式更新 | 用户偏好 |
| 程序性(Procedural) | 永久 | 系统提示 / 配置 | 由开发者更新 | 工作流指令 |
| 陈述性(Declarative) | 视情况 | 知识库 / RAG | 由数据流水线更新 | 产品文档 |
Memory Architecture Explorer
Click each memory layer to explore what it stores, how it works, and see example data.
Session:对话的容器
Session(会话)是容纳用户与智能体之间一次对话的容器。Session 给智能体连续性——记住本次交互到目前为止发生了什么。
Session 里有什么?
Session
+-----------------------------------------------+
| Session ID: abc-123 |
| User ID: user-456 |
| Created: 2025-01-15T10:30:00Z |
| |
| Events: |
| [User message: "Help me plan a trip"] |
| [Agent message: "Where would you like..."] |
| [User message: "Tokyo, 5 days"] |
| [Tool call: flight_search(dest="Tokyo")] |
| [Tool result: {flights: [...]}] |
| [Agent message: "I found several..."] |
| |
| State: |
| destination: "Tokyo" |
| duration: "5 days" |
| budget: null |
+-----------------------------------------------+
Session 与 State
- Session: 一次对话中事件(消息、工具调用、结果)的完整历史。
- State(状态): 从 session 中提取出的关键信息的结构化摘要。可以把它想成智能体的记事本。
State 很有用,因为它让智能体快速拿到重要事实,而不必重读整段对话历史。
Google Cloud 中的 Session 管理
Google Cloud 通过 Agent Development Kit(ADK)与 Vertex AI 提供 session 管理:
- ADK Sessions: ADK session 系统 提供内置的 session 管理,含事件追踪与 state。
- Vertex AI Sessions: Vertex AI Agent Engine sessions 提供托管的 session 存储与自动扩缩。
它们处理存储与检索 session 的基础设施,你可以把精力放在智能体逻辑上。
Memory vs. RAG
Memory(记忆)与 Retrieval-Augmented Generation(RAG,检索增强生成)相关,但用途不同。工程师常把二者混淆。
私人助理 vs. 图书馆
Memory 像有一个私人助理,记得你的偏好、日程与过往对话。他们了解你。
RAG 像能使用一座图书馆。需要事实时就去查。图书馆并不认识你个人——只是有大量可用信息。
并排对比
| 方面 | Memory | RAG |
|---|---|---|
| 存储什么 | 用户特定、交互特定的数据 | 通用知识、文档、数据 |
| 关于谁 | 这个用户、这个智能体、这个上下文 | 任何人——共享知识 |
| 何时写入 | 智能体交互过程中 | 数据摄入时(通常离线) |
| 何时读取 | 会话开始或进行中 | 智能体需要特定信息时 |
| 个性化 | 高——对用户唯一 | 低——对所有人相同 |
| 示例 | 「该用户偏好简洁回答」 | 「API 速率限制为 100 请求/分钟」 |
二者如何协同
实践中智能体会两者并用:
User: "Remind me, what was that deployment issue we had last month?"
Agent:
1. Check MEMORY: "This user works on the payments team and
had a Cloud Run deployment failure on Jan 3."
2. Use RAG: Search incident reports for "Cloud Run deployment
failure January" to get specific details.
3. Combine: "Last month you had a Cloud Run deployment failure
related to a misconfigured service account. Here are the
details from the incident report..."
Memory 告诉智能体该找什么。RAG 提供详细信息。
我们将在 第 8 课:Agentic RAG 深入讲解 RAG。
上下文腐烂(Context rot)
什么是上下文腐烂?
当上下文窗口被填满时,关键信息会丢失、稀释或被埋没,这就是上下文腐烂。智能体「忘记」重要内容——不是因为信息被删除了,而是因为它不再处于模型注意力所在的那段上下文中。
杂乱桌子类比
还记得桌子的类比吗?上下文腐烂就是:桌子乱到写着数据库密码的关键便利贴被会议纪要埋住了。纸条技术上仍在桌上,但你需要时找不到。
上下文腐烂如何发生
长对话。 每一轮都向上下文追加消息。50+ 轮之后,早期消息远离模型聚焦的位置。
冗长的工具结果。 工具返回巨大的 JSON。大部分无关,却占用宝贵上下文空间。
累积的指令。 系统指令、few-shot 示例与护栏占用本可用于用户相关信息的空间。
重复内容。 相似消息或结果堆叠,却未做合并。
上下文腐烂的迹象
- 智能体「忘记」用户在对话更早时候告诉它的事
- 智能体与更早的陈述或决定自相矛盾
- 会话早期的工具结果被忽略
- 智能体索要用户已经提供过的信息
管理上下文的策略
1. 滑动窗口(Sliding window)
如何工作: 上下文中只保留最近 N 条消息。更早的消息被丢弃。
Window size: 10 messages
Messages 1-5: [dropped]
Messages 6-15: [in context]
Message 16: [new message arrives, message 6 gets dropped]
优点: 实现简单,内存占用可预期。
缺点: 丢失重要的早期上下文。用户可能引用第 2 条消息中的内容,而它已不在窗口中。
最适合: 近期上下文最重要的闲聊型对话智能体。
2. 摘要(Summarization)
如何工作: 定期把较旧的对话轮次摘要化,并用摘要替换原文。摘要比原始消息占用少得多的空间。
Before summarization:
[20 detailed messages about trip planning] -> 4,000 tokens
After summarization:
[Summary: "User is planning a 5-day trip to Tokyo with a budget
of $3,000. They prefer boutique hotels and want to visit temples
and try local food. Flights are booked for March 15-20."] -> 200 tokens
优点: 在节省空间的同时保留关键信息。
缺点: 摘要可能丢失细微差别。做摘要的智能体可能漏掉重要内容。
最适合: 历史上下文仍然重要的长会话。
3. 基于 Token 的截断(Token-based truncation)
如何工作: 为上下文各部分(系统指令、对话历史、工具结果)设定 token 预算,任一分区超预算则截断。
Total budget: 32,000 tokens
System instructions: 4,000 tokens (fixed)
Tool definitions: 2,000 tokens (fixed)
Conversation history: 20,000 tokens (sliding)
Current turn: 6,000 tokens (reserved)
优点: 对上下文分配有细粒度控制。确保当前任务始终有可用空间。
缺点: 需要仔细调参。硬边界可能在消息中途截断。
最适合: 需要可预期成本与延迟的生产智能体。
4. 基于重要性的选择(Importance-based selection)
如何工作: 按与当前任务的相关性给每段上下文打分,只保留最相关项。
Current task: "Book a hotel in Tokyo"
High relevance (keep):
- User's destination: Tokyo
- User's dates: March 15-20
- User's budget: $3,000
- User's hotel preferences: boutique
Low relevance (drop):
- Discussion about restaurant recommendations
- Earlier conversation about flight options (already booked)
优点: 最大化上下文中的信噪比。
缺点: 相关性打分并不完美。智能体可能丢掉后来才发现重要的内容。
最适合: 多种上下文争抢空间的复杂智能体。
5. 外置并检索(Externalize and retrieve)
如何工作: 把信息存到外部记忆(数据库、向量库或知识图谱),只在需要时检索。
Instead of keeping everything in context:
User preferences -> stored in user profile database
Past conversations -> stored in conversation archive
Reference docs -> stored in vector database
When needed:
Agent queries the relevant store and loads just the
pieces it needs into the current context.
优点: 存储几乎无限。只有相关信息进入上下文。
缺点: 检索增加延迟。检索质量取决于搜索系统。
最适合: 需要访问大量信息、但任意时刻只用其中一小部分的智能体。
策略对比
| 策略 | 上下文节省 | 信息丢失风险 | 复杂度 | 延迟影响 |
|---|---|---|---|---|
| 滑动窗口 | 高 | 高 | 低 | 无 |
| 摘要 | 高 | 中 | 中 | 有一些(摘要步骤) |
| Token 截断 | 中 | 中 | 中 | 无 |
| 重要性选择 | 高 | 中 | 高 | 有一些(打分步骤) |
| 外置 + 检索 | 非常高 | 低 | 高 | 更高(检索步骤) |
记忆存储选项
外置记忆时,需要有地方存放。以下是主要选项。
向量数据库(Vector databases)
做什么: 把信息存成数学向量(embeddings),按相似度检索。
如何工作:
- 用嵌入模型把文本转成向量
- 把向量与原文一起存储
- 搜索时把查询转成向量
- 找到与查询向量最相似的已存向量
适合: 找语义相似内容。「我们讨论过部署什么?」即便措辞不同,也能匹配过去关于部署的对话。
示例: Vertex AI Vector Search、Pinecone、Weaviate、ChromaDB
权衡:
- 语义相似度搜索很强
- 精确匹配或结构化查询较弱
- 嵌入质量影响检索质量
知识图谱(Knowledge graphs)
做什么: 以图结构把信息存成实体与关系。
如何工作:
[User: Alex] --works_on--> [Project: Payments API]
[Project: Payments API] --deployed_on--> [Platform: Cloud Run]
[User: Alex] --prefers--> [Theme: Dark Mode]
适合: 表示实体间的结构化关系。「谁在做 Payments API?」或「Payments API 部署在哪个平台?」
示例: Neo4j、Amazon Neptune、Google Cloud 的 Knowledge Graph
权衡:
- 关系查询优秀
- 需要 schema 设计与维护
- 对非结构化文本不那么自然
混合方案(Hybrid approaches)
实践中许多系统二者结合:
- 向量数据库 用于非结构化记忆(对话、文档、笔记)
- 知识图谱 用于结构化记忆(关系、事实、偏好)
- 键值存储(Key-value store) 用于 session state 与快速查找
"What does Alex prefer?"
-> Key-value store: {theme: "dark", language: "TypeScript"}
"What did Alex and I discuss about deployments?"
-> Vector search: [similar past conversations about deployments]
"What services does Alex's team own?"
-> Knowledge graph: Alex -> team -> services -> dependencies
选择存储方式
| 需求 | 最佳方案 |
|---|---|
| 对话上的语义搜索 | 向量数据库 |
| 用户偏好与设置 | 键值存储 |
| 实体关系 | 知识图谱 |
| 近期会话历史 | 内存 / session 存储 |
| 文档检索 | 向量数据库 + 元数据过滤 |
| 复杂多跳查询 | 知识图谱 |
把它们放在一起
记忆与上下文如何融入智能体架构:
+-------------------+
| User Message |
+--------+----------+
|
v
+-------------+-------------+
| Context Engineering |
| Layer |
| |
| 1. Load system prompt |
| 2. Retrieve relevant |
| memory |
| 3. Load session history |
| (pruned/summarized) |
| 4. Add tool definitions |
| 5. Include current |
| message |
+-------------+-------------+
|
Assembled context
|
v
+--------+----------+
| LLM |
+--------+----------+
|
Agent response
|
v
+-------------+-------------+
| Memory Update Layer |
| |
| 1. Save to session |
| 2. Extract key facts |
| for long-term memory |
| 3. Update user profile |
+---------------------------+
上下文工程层在 LLM 看到 内容之前组装正确上下文。记忆更新层在 LLM 响应之后提取重要信息。二者一起让智能体能记住并保持聚焦。
关键要点
上下文窗口是智能体的工作记忆。 智能体考虑的一切都必须装进这块空间。管好它至关重要。
上下文工程超越提示词工程。 智能体需要动态组装上下文,而不只是静态提示。进入上下文窗口的内容应随情境变化。
智能体需要多种记忆。 短期用于当前对话,长期用于跨会话持久化,程序性用于知道如何做事,陈述性用于事实。
Session 提供对话连续性。 它们追踪一次交互的历史与状态,让智能体能维持连贯对话。
Memory 与 RAG 用途不同。 Memory 是个人的、交互特定的。RAG 关乎访问通用知识。多数智能体两者都需要。
上下文腐烂是真实问题。 上下文增长时,重要信息会被埋没。通过摘要、裁剪与外置存储主动管理,才能保持智能体有效。
按访问模式选择存储。 语义搜索用向量库,关系用知识图谱,快速查找用键值存储。混合方案往往最好。
延伸阅读
- ADK Sessions documentation
- Vertex AI Agent Engine - Manage Sessions
- Vertex AI Vector Search
- Google Cloud AI codelabs
下一课: 规划与推理——智能体如何应对复杂任务
评论