Skip to content
Gains Summary
Main Navigation 首页 / Home
C++ 编程 / C++ Programming
系统与高性能 / Systems & Performance
Web 开发 / Web Development
人工智能 / Artificial Intelligence
工业软件 / Industrial Software
其他内容 / Other Topics
C++ 编程 / C++系统与性能 / SystemsWeb 开发 / Web人工智能 / AI工业软件 / Industrial

外观

Sidebar Navigation

← 人工智能 / Artificial Intelligence

智能体工程 / Agent Engineering

1. Agent 工程体系全景 / Agent Engineering System Overview

2. Function Calling - 让 LLM 具备行动能力 / Function Calling for Giving LLMs the Ability to Act

3. Agent 框架演进 - 从裸 SDK 到 LangGraph / The Evolution of Agent Frameworks from Raw SDKs to LangGraph

4. RAG 基础 - 让 Agent 拥有"知识" / Retrieval-Augmented Generation Fundamentals for Agent Knowledge

5. 记忆管理 - Agent 的大脑 / Memory Management as the Brain of an Agent

6. Agent 工作流 - 从单步到复杂的执行编排 / Agent Workflows from Single Steps to Complex Orchestration

7. 多 Agent 系统 - 多个 Agent 协作 / Multi-Agent Systems and Agent Collaboration

8. RAG 进阶 - 企业级知识库实战 / Advanced RAG for Enterprise Knowledge Bases

9. 真实 Agent 应用场景 / Real-World AI Agent Applications

10. Structured Output - 让 LLM 输出可控的结构化数据 / Structured Output for Controllable, Machine-Readable LLM Responses

11. Tools Design Best Practices - AI Agent 工具设计最佳实践 / Tools Design Best Practices for AI Agents

12. Agent 架构模式 - 从单 Agent 到多 Agent 的工程范式 / Agent Architecture Patterns

13. Agent Modes — 编程 Agent 的交互模式设计 / Designing Interaction Modes for Coding Agents

14. Agent Workflow 编排:从循环到持久化执行的演进

15. Context Engineering - 从 Prompt 设计到上下文编排 / Context Engineering: From Prompt Design to Context Orchestration

16. Agent 缓存工程:从 KV Cache、Prompt Cache 到语义缓存 / Agent Caching Engineering

17. Harness Engineering, Skills, and Loop Engineering — 从信任模型到验证系统 / From Trusting Models to Verifying Systems

18. MCP 协议 - AI 工具的"USB 接口" / Model Context Protocol for AI Tool Integration

19. Agent 评估与测试 — 如何衡量一个"不可预测"的系统 / Agent Evaluation and Testing — How to Measure an "Unpredictable" System

20. 安全沙箱 - Agent 的安全边界 / Secure Sandboxes as Agent Safety Boundaries

21. 权限与门卫 - Agent 的安全控制中枢 / Permissions and Policy Gates for Agent Control

22. API Key 管理与安全 - Agent 的密钥生命周期的管理 / API Key Lifecycle Management and Security for Agents

23. 提示词注入防护 - Agent 的防御前沿 / Prompt Injection Defense for AI Agents

24. 可观测性与调试 - Agent 运行的透明度保障 / Observability and Debugging for Transparent Agent Operations

25. 模型路由 - 让正确的模型做正确的事 / Model Routing for Matching Models to Tasks

26. OpenClaw 设计深度分析 - 为什么它让人觉得"活"了 / OpenClaw Design Analysis and the Illusion of Liveliness

27. Claude Code 泄露源码深度分析 - 512,000 行代码揭示的生产级 Agent 架构 / Claude Code Source Analysis and Production Agent Architecture

28. LobeChat 设计深度分析 - 全栈 Agent Chat 应用工程实践 / LobeChat Design Analysis and Full-Stack Agent Chat Engineering

29. 编程 Agent 全面对比:从 Claude Code 到 Pi 的设计哲学 / Coding Agents Comparison: Design Philosophies from Claude Code to Pi

30. 领域 Agent 的确定性工具编译与延迟执行——从自然语言规格到单次 CAE 提交

31. Agent 工程学习指南 / An AI Agent Engineering Learning Guide

本页目录

记忆管理 - Agent 的大脑 / Memory Management as the Brain of an Agent ​

📅 创建时间:2026-05-08 🏷️ 标签:#Memory #ContextWindow #会话管理 #记忆类型 📚 前置知识:[[03-rag-basics]]


📋 本章目标 ​

  • 理解为什么 Agent 需要记忆
  • 掌握短时记忆与长时记忆的区别
  • 了解三种记忆类型:语义、情景、程序
  • 掌握上下文窗口的管理策略
  • 能够实现基础的记忆管理方案
  • 理解记忆压缩与摘要技术

第0部分:"记忆"到底存在哪里? ​

Function Calling 那篇已经讲了:LLM 每次 API 调用是无状态的——你把 messages 数组 POST 过去,它返回结果,然后就"忘了"。那"记忆"是什么?就是你的程序在 LLM 之外维护的数据,在每次 API 调用前拼进 messages 里。

0.1 短时记忆——就是 messages 数组本身 ​

每次 API 调用时,你的 messages 大概长这样:

python
messages = [
    {"role": "system", "content": "你是助手..."},
    {"role": "user", "content": "我叫张三"},
    {"role": "assistant", "content": "你好张三!"},
    {"role": "user", "content": "帮我查下北京天气"},
    {"role": "assistant", "content": None, "tool_calls": [...]},
    {"role": "tool", "content": '{"temp": 25}'},
    {"role": "assistant", "content": "北京今天25°C"},
    {"role": "user", "content": "我刚才说我叫什么?"},   ← 新问题
]
1
2
3
4
5
6
7
8
9
10

LLM 能看到整个数组,所以它"记得"你叫张三——因为 messages 的前几行里就有。所谓"短时记忆",就是你的程序把对话历史维护在一个数组里,每次 API 调用时原样发回去。 LLM 自己没存任何东西。

这个数组存在哪?存在你的程序内存里——就是一个 Python list 或 JS array。服务重启就没了,除非你把它持久化到数据库。

0.2 长时记忆——存在外部数据库,用时检索 ​

短时记忆的问题是:messages 数组会越来越长,最终超出模型的 context window 限制(比如 GPT-4o 的 128K tokens,Claude 的 200K tokens)。而且把所有历史对话都塞进每次请求,token 费用也会爆炸。

长时记忆的思路是:把历史信息存到外部数据库,每次请求时只检索相关的部分拼进 prompt。

┌─────────────────────────────────────────────────────────────┐
│                  短时记忆 vs 长时记忆的数据流                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  短时记忆(Session Memory):                                 │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 你的程序维护一个 messages 数组                       │   │
│  │                                                     │   │
│  │ POST /v1/chat/completions                          │   │
│  │ {messages: [所有历史对话 + 新问题]}                  │   │
│  │                                                     │   │
│  │ 存储位置:程序内存(Python list / Redis / session DB)│   │
│  │ 生命周期:当前对话期间                                │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  长时记忆(Long-term Memory):                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 存储:向量数据库 / PostgreSQL / Redis                │   │
│  │                                                     │   │
│  │ 每次请求前:                                         │   │
│  │ 1. 用户问题 → Embedding API → 查询向量              │   │
│  │ 2. 向量数据库.search(查询向量) → 找到相关记忆        │   │
│  │ 3. messages = [system_prompt, 相关记忆, 最近对话, 新问题]│   │
│  │ 4. POST /v1/chat/completions                        │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

关键认知:长时记忆和 RAG 本质上是同一套技术——把信息存到外部数据库,用 Embedding 做语义检索,在需要时注入 prompt。区别只在于存的内容不同:RAG 存的是外部文档,长时记忆存的是 Agent 自己和用户的互动历史。

0.3 一句话总结 ​

记忆类型存在哪里怎么用
短时记忆程序的 messages 数组(内存/Redis)每次 API 调用原样发回去
长时记忆向量数据库/普通数据库每次请求前检索相关内容,拼进 prompt

带着这个数据流模型,下面的细节就好理解了。


第1部分:为什么 Agent 需要记忆? ​

1.1 LLM 的"失忆症" ​

┌─────────────────────────────────────────────────────────────┐
│                    LLM 的记忆特性                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  每次 API 调用是独立的                                       │
│                                                             │
│  请求1:                                                    │
│  messages = [{"role": "user", "content": "我叫张三"}]       │
│  → LLM 回复:"你好张三!"                                    │
│                                                             │
│  请求2(完全独立,无记忆):                                 │
│  messages = [{"role": "user", "content": "你叫什么?"}]     │
│  → LLM 回复:"我没有名字,我是 AI 助手"(忘了张三)          │
│                                                             │
│  结论:LLM 本身没有持久记忆                                  │
│        记忆需要我们手动管理                                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

1.2 Agent 记忆的重要性 ​

┌─────────────────────────────────────────────────────────────┐
│                    Agent 记忆的价值                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  没有记忆的 Agent:                                          │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 用户:帮我订下周一去上海的机票                          │   │
│  │ Agent:好的,请提供您的航班偏好...                      │   │
│  │ 用户:我之前说过要坐国航的...                            │   │
│  │ Agent:抱歉,我没有之前的对话记录                        │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  有记忆的 Agent:                                           │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 用户:帮我订下周一去上海的机票                          │   │
│  │ Agent(查记忆):查到你之前偏好国航+靠窗座位            │   │
│  │ Agent:好的,为你搜索下周一国航上海航班,需要靠窗吗?    │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

1.3 记忆的两个层级 ​

┌─────────────────────────────────────────────────────────────┐
│                    记忆的两个层级                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  短时记忆(Short-term Memory)                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ • 当前会话的上下文                                     │   │
│  │ • 消息历史                                            │   │
│  │ • 生命周期:当前会话                                  │   │
│  │ • 容量限制:上下文窗口(Context Window)               │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  长时记忆(Long-term Memory)                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ • 跨会话的持久化信息                                   │   │
│  │ • 用户偏好、历史交互、积累知识                          │   │
│  │ • 生命周期:永久(或很长时间)                          │   │
│  │ • 容量:理论上无限                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

第2部分:短时记忆 — 上下文管理 ​

2.1 上下文窗口的限制 ​

┌─────────────────────────────────────────────────────────────┐
│                    主流模型的上下文窗口                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  │ 模型          │ 上下文窗口      │ 大约能放多少文字?     │
│  ├───────────────┼────────────────┼────────────────────────┤
│  │ GPT-3.5-turbo│ 16,385 tokens  │ 约 8000 字(4页)     │
│  │ GPT-4o       │ 128,000 tokens │ 约 6.4 万字(32页)   │
│  │ Claude 3.5   │ 200,000 tokens │ 约 10 万字(50页)    │
│  │ Gemini 1.5   │ 100万 tokens   │ 约 50 万字(250页)   │
│                                                             │
│  超出上下文窗口 = 被截断 / 报错                              │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14

2.2 上下文窗口的权衡 ​

┌─────────────────────────────────────────────────────────────┐
│                    上下文窗口权衡                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  塞太少 ← 缺少关键信息 ← Agent 表现差                       │
│                                                             │
│  塞太多 ← Token 成本高 ← 响应慢 ← 模型效果下降(丢失重点)  │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 最佳策略:只塞"最相关"的信息                          │   │
│  │                                                        │   │
│  │ 用户:"帮我写一封感谢邮件给李经理"                     │   │
│  │                                                        │   │
│  │ ❌ 塞整个对话历史(100 条消息)                        │   │
│  │ ✅ 只塞:用户偏好(正式邮件)+ 李经理的联系方式        │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

2.3 上下文管理策略 ​

策略1:滑动窗口(Sliding Window)

python
class SlidingWindowMemory:
    """只保留最近 N 条消息"""
    def __init__(self, max_messages=10):
        self.max_messages = max_messages
        self.messages = []

    def add(self, role, content):
        self.messages.append({"role": role, "content": content})
        # 超过限制时,丢弃最老的
        if len(self.messages) > self.max_messages:
            self.messages.pop(0)

    def get_context(self):
        return self.messages.copy()
1
2
3
4
5
6
7
8
9
10
11
12
13
14

策略2:摘要策略(Summarization)

python
class SummarizedMemory:
    """定期摘要旧消息,保留关键信息"""
    def __init__(self, llm, max_messages=20, summary_threshold=15):
        self.llm = llm
        self.max_messages = max_messages
        self.summary_threshold = summary_threshold
        self.messages = []
        self.summary = ""  # 历史摘要

    def add(self, role, content):
        self.messages.append({"role": role, "content": content})

        # 当消息太多时,摘要早期内容
        if len(self.messages) > self.summary_threshold:
            # 摘要最近 10 条之前的所有内容
            old_messages = self.messages[:-10]
            new_summary = self._summarize(old_messages)
            self.summary = f"{self.summary}\n{new_summary}".strip()
            self.messages = self.messages[-10:]

    def _summarize(self, messages):
        prompt = f"请摘要以下对话的关键信息(保留重要事实和偏好):\n{messages}"
        return self.llm.invoke(prompt).content
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

策略3:选择性记忆(Selective Memory)

python
class SelectiveMemory:
    """只保留与当前任务相关的信息"""
    def __init__(self, llm):
        self.llm = llm
        self.all_messages = []  # 全部历史
        self.important_facts = []  # 重要事实

    def add(self, role, content):
        self.all_messages.append({"role": role, "content": content})

        # 自动提取重要事实
        if "喜欢" in content or "偏好" in content or "我叫" in content:
            self.important_facts.append(content)

    def get_relevant_context(self, query, max_tokens=4000):
        """只返回与查询相关的信息"""
        # 简单策略:包含关键词的历史消息
        keywords = self._extract_keywords(query)

        relevant = []
        for msg in self.all_messages[-20:]:  # 只看最近 20 条
            if any(kw in msg["content"] for kw in keywords):
                relevant.append(msg)

        # 加上重要事实
        return self.important_facts + relevant
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

第3部分:长时记忆 — 持久化存储 ​

3.1 长时记忆的用途 ​

┌─────────────────────────────────────────────────────────────┐
│                    长时记忆的用途                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 用户偏好记忆                                            │
│     • "用户喜欢正式语气"                                     │
│     • "用户总是要靠窗座位"                                   │
│     • "用户不喜欢浪费时间寒暄"                               │
│                                                             │
│  2. 历史交互摘要                                            │
│     • "用户之前问过 Python 问题"                            │
│     • "用户曾在 3 月份问过税务问题"                           │
│                                                             │
│  3. 知识积累                                                │
│     • "这是用户第三次问这个问题了"                           │
│     • "用户的工作是律师"                                     │
│                                                             │
│  4. 跨会话连贯性                                            │
│     • "用户上周让我帮他设置的自动化还在跑吗?"                │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

3.2 长时记忆的存储方案 ​

方案1:向量数据库存储

python
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma

class VectorMemory:
    """用向量数据库存储记忆"""
    def __init__(self, collection_name="user_memory"):
        self.embeddings = OpenAIEmbeddings()
        self.vectorstore = Chroma(
            collection_name=collection_name,
            embedding_function=self.embeddings,
            persist_directory="./memory_db"
        )

    def add(self, content, metadata=None):
        """添加记忆"""
        self.vectorstore.add_texts(
            texts=[content],
            metadatas=[metadata or {}]
        )

    def recall(self, query, top_k=5):
        """根据查询找回相关记忆"""
        results = self.vectorstore.similarity_search(query, k=top_k)
        return [doc.page_content for doc in results]

    def delete(self, memory_id):
        """删除记忆"""
        self.vectorstore.delete(ids=[memory_id])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

方案2:键值对存储(适合结构化偏好)

python
import json
from pathlib import Path

class KVUserMemory:
    """键值对存储用户偏好"""
    def __init__(self, user_id):
        self.user_id = user_id
        self.file_path = Path(f"./user_memory/{user_id}.json")
        self.memory = self._load()

    def _load(self):
        if self.file_path.exists():
            return json.loads(self.file_path.read_text())
        return {}

    def set(self, key, value):
        self.memory[key] = value
        self.file_path.parent.mkdir(parents=True, exist_ok=True)
        self.file_path.write_text(json.dumps(self.memory, ensure_ascii=False))

    def get(self, key, default=None):
        return self.memory.get(key, default)

    def get_all(self):
        return self.memory.copy()

# 使用示例
memory = KVUserMemory("zhang_san")
memory.set("communication_style", "简洁专业")
memory.set("default_language", "中文")
memory.set("job_title", "律师")

preferences = memory.get_all()
# {"communication_style": "简洁专业", "default_language": "中文", "job_title": "律师"}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

3.3 组合方案 ​

python
class HybridMemory:
    """组合短时 + 长时记忆"""
    def __init__(self, user_id, llm):
        self.short_term = SlidingWindowMemory(max_messages=20)
        self.long_term_vector = VectorMemory(collection_name=f"user_{user_id}")
        self.long_term_kv = KVUserMemory(user_id)
        self.llm = llm

    def add(self, role, content):
        self.short_term.add(role, content)

        # 自动提取重要信息到长时记忆
        if self._is_important(content):
            self.long_term_vector.add(content, {"role": role})
            # 提取键值信息
            self._extract_kv(content)

    def get_context(self, query=None):
        """获取完整上下文"""
        # 1. 短时记忆(最近对话)
        short = self.short_term.get_context()

        # 2. 相关长时记忆(向量检索)
        if query:
            relevant_long = self.long_term_vector.recall(query)
        else:
            relevant_long = []

        # 3. 用户偏好
        preferences = self.long_term_kv.get_all()

        return {
            "recent_messages": short,
            "relevant_memories": relevant_long,
            "user_preferences": preferences
        }

    def _is_important(self, content):
        """判断内容是否重要到需要存入长时记忆"""
        important_keywords = ["喜欢", "不喜欢", "我叫", "我是", "以后", "总是", "从不"]
        return any(kw in content for kw in important_keywords)

    def _extract_kv(self, content):
        """从文本中提取键值对"""
        # 简单实现,实际可以用 LLM 提取
        pass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

第4部分:三种记忆类型 ​

4.1 概念解释 ​

┌─────────────────────────────────────────────────────────────┐
│                    三种记忆类型                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  语义记忆(Semantic Memory)                                 │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 事实和概念性的知识                                     │   │
│  │ "我叫张三"、"我喜欢喝美式咖啡"                         │   │
│  │ → 通常存储为键值对或向量                               │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  情景记忆(Episodic Memory)                                 │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 过去发生的事件序列                                     │   │
│  │ "用户上周五问过我关于年假的问题"                       │   │
│  │ → 通常存储为带时间戳的日志或摘要                       │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  程序记忆(Procedural Memory)                               │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ Agent 自己学到的行为模式                               │   │
│  │ "用户每次问代码问题,我应该先问用什么语言"              │   │
│  │ → 通常存储为 Agent 的 System Prompt 或规则              │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

4.2 在 Agent 中的应用 ​

python
# 在构建 Agent 时整合三种记忆
class IntelligentAgent:
    def __init__(self, user_id, llm):
        self.memory = HybridMemory(user_id, llm)

    def chat(self, user_input):
        # 获取完整上下文
        context = self.memory.get_context(user_input)

        # 构建 System Prompt(程序记忆)
        preferences = context["user_preferences"]
        system_prompt = f"""你是一个助手。
用户偏好:{preferences}
沟通风格:{preferences.get('communication_style', '普通')}
语言:{preferences.get('default_language', '中文')}
"""

        # 构建消息
        messages = [{"role": "system", "content": system_prompt}]

        # 添加相关记忆(语义记忆)
        for mem in context["relevant_memories"][:3]:
            messages.append({"role": "user", "content": f"【记忆】{mem}"})

        # 添加最近对话(情景记忆)
        for msg in context["recent_messages"][-10:]:
            messages.append(msg)

        messages.append({"role": "user", "content": user_input})

        # 调用 LLM
        response = self.llm.invoke(messages)

        # 保存对话到记忆
        self.memory.add("user", user_input)
        self.memory.add("assistant", response.content)

        return response.content
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

第5部分:实战技巧 ​

5.1 记忆何时写入 ​

┌─────────────────────────────────────────────────────────────┐
│                    记忆写入时机                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ✅ 应该写入:                                              │
│  • 用户明确表达偏好:"我想要..." / "我喜欢..."               │
│  • 关键事实:"我叫..." / "我是..." / "我在...工作"          │
│  • 任务关键信息:"要发给王总的邮件"                          │
│  • Agent 发现反复出现同一问题                                │
│                                                             │
│  ❌ 不需要写入:                                            │
│  • 闲聊:"今天天气不错"                                     │
│  • 一次性问题:"今天星期几"                                  │
│  • 用户明确说过"不用记住"的信息                              │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

5.2 记忆何时读取 ​

┌─────────────────────────────────────────────────────────────┐
│                    记忆读取策略                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  方式1:每次都读取(保守)                                   │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 每次查询时,把所有相关记忆都塞进 context                │   │
│  │ 优点:不遗漏                                          │   │
│  │ 缺点:Token 消耗大,可能稀释关键信息                   │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  方式2:按需读取(推荐)                                     │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 用户输入 → 提取关键词 → 只检索相关记忆                 │   │
│  │ 优点:精准、Token 高效                                 │   │
│  │ 缺点:可能遗漏间接相关的信息                           │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  方式3:定期预取(主动)                                     │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 根据对话主题,主动预取相关记忆                         │   │
│  │ 例如:检测到"代码"主题 → 预取用户的编程偏好            │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

5.3 记忆的遗忘机制 ​

python
class MemoryWithForget:
    """带遗忘机制的记忆"""

    def __init__(self, max_memories=1000, decay_days=30):
        self.max_memories = max_memories
        self.decay_days = decay_days
        self.memories = []  # (content, timestamp, importance)

    def add(self, content, importance=1.0):
        import time
        self.memories.append((content, time.time(), importance))
        self._prune()

    def _prune(self):
        """删除低重要度或过旧的记忆"""
        import time
        now = time.time()

        # 删除策略:保留 top N
        if len(self.memories) > self.max_memories:
            # 按重要度排序,保留最高的
            self.memories.sort(key=lambda x: x[2], reverse=True)
            self.memories = self.memories[:self.max_memories]

        # 也可按时间衰减删除
        self.memories = [
            (c, t, i) for c, t, i in self.memories
            if (now - t) < self.decay_days * 86400 or i > 0.8
        ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

核心总结 ​

总结1:记忆的两个层级 ​

短时记忆(上下文窗口内)
• 当前会话的消息历史
• 需要管理容量,避免超限

长时记忆(持久化)
• 跨会话的用户偏好、积累知识
• 用向量数据库或键值存储
1
2
3
4
5
6
7

总结2:三种记忆类型 ​

类型内容存储方式
语义记忆事实、偏好键值对、向量
情景记忆历史事件、对话带时间戳的日志/摘要
程序记忆行为模式System Prompt、规则

总结3:上下文管理策略 ​

策略适用场景
滑动窗口对话模式简单,不需要长期上下文
摘要对话很长,需要保留关键信息
选择性记忆对话复杂,需要精准检索

章节测试 ​

测试1:短时 vs 长时记忆 ​

短时记忆和长时记忆的主要区别是什么?各自的容量限制是什么?

测试2:记忆类型 ​

三种记忆类型(语义、情景、程序)分别存储什么内容?

测试3:上下文窗口 ​

当上下文窗口快满时,有哪三种主要处理策略?

测试4:长时记忆存储 ​

向量数据库和键值对存储分别适合存储什么类型的长时记忆?

测试5:记忆读写 ​

什么信息应该被写入长时记忆?什么信息不需要?


参考答案 ​

测试1答案 ​

答案:

  • 短时记忆:当前会话的上下文,容量受限于模型的上下文窗口(如 GPT-4o 是 128K tokens)
  • 长时记忆:跨会话的持久化信息,容量理论上无限,受限于存储成本

测试2答案 ​

答案:

  • 语义记忆:事实和概念性知识(如用户偏好"喜欢美式咖啡")
  • 情景记忆:过去发生的事件序列(如"用户上周问过年假问题")
  • 程序记忆:Agent 自己学到的行为模式(如"用户问代码问题时应先问语言")

测试3答案 ​

答案:

  1. 滑动窗口:丢弃最老的消息,只保留最近 N 条
  2. 摘要:将旧消息压缩成摘要,保留关键信息
  3. 选择性记忆:只保留与当前任务相关的信息

测试4答案 ​

答案:

  • 向量数据库:适合存储非结构化的、语义相关的内容(如对话摘要、提取的事实)
  • 键值对存储:适合存储结构化的用户偏好(如"communication_style": "简洁")

测试5答案 ​

答案:

  • 应该写入:用户明确表达的偏好("我喜欢...")、关键事实(姓名、职业)、任务关键信息
  • 不需要写入:闲聊内容、一次性问题("今天星期几")、用户明确说不用记住的信息

相关笔记 ​

  • [[03-rag-basics]] - RAG 也是一种"外部记忆"的使用方式
  • [[05-agent-workflow]] - 记忆在工作流中的具体应用
  • [[06-multi-agent]] - 多 Agent 系统中每个 Agent 的记忆管理

下一步学习 ​

  • [ ] 阅读 05 - Agent 工作流

学习状态:🟡 开始学习

最后更新于:

Pager
上一篇4. RAG 基础 - 让 Agent 拥有"知识" / Retrieval-Augmented Generation Fundamentals for Agent Knowledge
下一篇6. Agent 工作流 - 从单步到复杂的执行编排 / Agent Workflows from Single Steps to Complex Orchestration

持续记录,持续成长

Copyright © Tidenflow