【大模型应用开发】记忆
- [1. 记忆功能的重要性](#1. 记忆功能的重要性)
-
- [1.1 人类记忆系统](#1.1 人类记忆系统)
- [1.2 为何智能体需要记忆](#1.2 为何智能体需要记忆)
-
- [1.2.1 无状态导致的对话遗忘](#1.2.1 无状态导致的对话遗忘)
- [1.3 记忆与RAG系统架构设计](#1.3 记忆与RAG系统架构设计)
- [1.4 记忆类型层](#1.4 记忆类型层)
-
- [1.4.1 WorkingMemory 工作记忆(短时记忆 + TTL)](#1.4.1 WorkingMemory 工作记忆(短时记忆 + TTL))
- [1.4.2 EpisodicMemory 情景记忆(经历、故事、对话历史)](#1.4.2 EpisodicMemory 情景记忆(经历、故事、对话历史))
- [1.4.3 SemanticMemory 语义记忆(知识、事实、关系、图谱)](#1.4.3 SemanticMemory 语义记忆(知识、事实、关系、图谱))
- [1.4.4 PerceptualMemory 感知记忆(图片、声音、多模态)](#1.4.4 PerceptualMemory 感知记忆(图片、声音、多模态))
- [2. memory包](#2. memory包)
- [3. Python如何实现多参数构造函数](#3. Python如何实现多参数构造函数)
- [4. package下的`init.py`](#4. package下的
__init__.py) - 附录
1. 记忆功能的重要性
1.1 人类记忆系统
人类记忆是一个多层级的认知系统,它不仅能存储信息,还能根据重要性、时间和上下文对信息进行分类和整理。认知心理学为理解记忆的结构和过程提供了经典的理论框架,如下图所示。

根据认知心理学的研究,人类记忆可以分为以下几个层次:
- 感觉记忆(Sensory Memory):持续时间极短(0.5-3秒),容量巨大,负责暂时保存感官接收到的所有信息
- 工作记忆(Working Memory):持续时间短(15-30秒),容量有限(7±2个项目),负责当前任务的信息处理
- 长期记忆(Long-term Memory):持续时间长(可达终生),容量几乎无限,进一步分为:
- 程序性记忆:技能和习惯(如骑自行车)
- 陈述性记忆:可以用语言表达的知识,又分为:
- 语义记忆:一般知识和概念(如"巴黎是法国首都")
- 情景记忆:个人经历和事件(如"昨天的会议内容")
1.2 为何智能体需要记忆
借鉴人类记忆系统的设计,我们可以理解为什么智能体也需要类似的记忆能力。人类智能的一个重要特征就是能够记住过去的经历,从中学习,并将这些经验应用到新的情况中。同样,一个真正智能的智能体也需要具备记忆能力。对于基于LLM的智能体而言,通常面临局限:对话状态的遗忘。
1.2.1 无状态导致的对话遗忘
当前的大语言模型虽然强大,但设计上是无状态的。这意味着,每一次用户请求(或API调用)都是一次独立的、无关联的计算。模型本身不会自动"记住"上一次对话的内容。这带来了几个问题:
- 上下文丢失:在长对话中,早期的重要信息可能会因为上下文窗口限制而丢失
- 个性化缺失:Agent无法记住用户的偏好、习惯或特定需求
- 学习能力受限:无法从过往的成功或失败经验中学习改进
- 一致性问题:在多轮对话中可能出现前后矛盾的回答
让我们通过一个具体例子来理解这个问题:
python
from hello_agents import SimpleAgent, HelloAgentsLLM
agent = SimpleAgent(name="学习助手", llm=HelloAgentsLLM())
# 第一次对话
response1 = agent.run("我叫张三,正在学习Python,目前掌握了基础语法")
print(response1) # "很好!Python基础语法是编程的重要基础..."
# 第二次对话(新的会话)
response2 = agent.run("你还记得我的学习进度吗?")
print(response2) # "抱歉,我不知道您的学习进度..."
要解决这个问题,我们的框架需要引入记忆系统。
1.3 记忆与RAG系统架构设计
memory_tool负责存储和维护对话过程中的交互信息。
rag_tool则负责从用户提供的知识库中检索相关信息作为上下文,并可将重要的检索结果自动存储到记忆系统中。

记忆系统采用了四层架构设计:
html
HelloAgents记忆系统
├── 基础设施层 (Infrastructure Layer)
│ ├── MemoryManager - 记忆管理器(统一调度和协调)
│ ├── MemoryItem - 记忆数据结构(标准化记忆项)
│ ├── MemoryConfig - 配置管理(系统参数设置)
│ └── BaseMemory - 记忆基类(通用接口定义)
├── 记忆类型层 (Memory Types Layer)
│ ├── WorkingMemory - 工作记忆(临时信息,TTL管理)
│ ├── EpisodicMemory - 情景记忆(具体事件,时间序列)
│ ├── SemanticMemory - 语义记忆(抽象知识,图谱关系)
│ └── PerceptualMemory - 感知记忆(多模态数据)
├── 存储后端层 (Storage Backend Layer)
│ ├── QdrantVectorStore - 向量存储(高性能语义检索)
│ ├── Neo4jGraphStore - 图存储(知识图谱管理)
│ └── SQLiteDocumentStore - 文档存储(结构化持久化)
└── 嵌入服务层 (Embedding Service Layer)
├── DashScopeEmbedding - 通义千问嵌入(云端API)
├── LocalTransformerEmbedding - 本地嵌入(离线部署)
└── TFIDFEmbedding - TFIDF嵌入(轻量级兜底)
RAG系统专注于外部知识的获取和利用:
html
HelloAgents RAG系统
├── 文档处理层 (Document Processing Layer)
│ ├── DocumentProcessor - 文档处理器(多格式解析)
│ ├── Document - 文档对象(元数据管理)
│ └── Pipeline - RAG管道(端到端处理)
├── 嵌入表示层 (Embedding Layer)
│ └── 统一嵌入接口 - 复用记忆系统的嵌入服务
├── 向量存储层 (Vector Storage Layer)
│ └── QdrantVectorStore - 向量数据库(命名空间隔离)
└── 智能问答层 (Intelligent Q&A Layer)
├── 多策略检索 - 向量检索 + MQE + HyDE
├── 上下文构建 - 智能片段合并与截断
└── LLM增强生成 - 基于上下文的准确问答
1.4 记忆类型层
从上图中可以看到记忆类型层分为:WorkingMemory(纯内存+TTL)、EpisodicMemory(事件序列)、SemanticMemory(知识图谱)、PerceptualMemory(多模态)
1.4.1 WorkingMemory 工作记忆(短时记忆 + TTL)
对应人类:当下正在想的事,过会儿就忘
特点:临时、有过期时间、只存在内存里
举例场景

典型用途
- 当前对话上下文
- 临时任务状态
- 多轮对话里的临时信息
- 用完就丢,不存库
1.4.2 EpisodicMemory 情景记忆(经历、故事、对话历史)
对应人类:我记得上次我们聊过什么、发生过什么
特点:按时间线存、长期保存、像日记
举例场景

更多例子
- "你上次说你喜欢吃辣"
- "你上周让我帮你查过北京天气"
- "你昨天让我写一份离职邮件"
凡是 "我记得我们之间发生过什么",都是情景记忆。
1.4.3 SemanticMemory 语义记忆(知识、事实、关系、图谱)
对应人类:常识、知识点、人物关系、结构化信息
特点:不是故事,是 "事实",可推理
举例场景

典型用途
- 用户基本信息
- 领域知识(如 "Transformer 是一种注意力模型")
- 关系推理(A 是 B 的老公 → B 怀孕 → A 要注意育儿)
- 规则、定义、常识
1.4.4 PerceptualMemory 感知记忆(图片、声音、多模态)
对应人类:我记得你长什么样、那首歌的旋律、那张截图内容
特点:非文本、多模态、存向量
举例场景

2. memory包

2.1 base.py
整体代码
python
"""记忆系统基础类和配置
按照第8章架构设计的基础组件:
- MemoryItem: 记忆项数据结构
- MemoryConfig: 记忆系统配置
- BaseMemory: 记忆基类
"""
from abc import ABC, abstractmethod
from typing import List, Dict, Any
from datetime import datetime
from pydantic import BaseModel
class MemoryItem(BaseModel):
"""记忆项数据结构"""
id: str
content: str
memory_type: str
user_id: str
timestamp: datetime
importance: float = 0.5
metadata: Dict[str, Any] = {}
class Config:
arbitrary_types_allowed = True
class MemoryConfig(BaseModel):
"""记忆系统配置"""
# 存储路径
storage_path: str = "./memory_data"
# 统计显示用的基础配置(仅用于展示)
max_capacity: int = 100
importance_threshold: float = 0.1
decay_factor: float = 0.95
# 工作记忆特定配置
working_memory_capacity: int = 10
working_memory_tokens: int = 2000
working_memory_ttl_minutes: int = 120
# 感知记忆特定配置
perceptual_memory_modalities: List[str] = ["text", "image", "audio", "video"]
class BaseMemory(ABC):
"""记忆基类
定义所有记忆类型的通用接口和行为
"""
def __init__(self, config: MemoryConfig, storage_backend=None):
self.config = config
self.storage = storage_backend
self.memory_type = self.__class__.__name__.lower().replace("memory", "")
@abstractmethod
def add(self, memory_item: MemoryItem) -> str:
"""添加记忆项
Args:
memory_item: 记忆项对象
Returns:
记忆ID
"""
pass
@abstractmethod
def retrieve(self, query: str, limit: int = 5, **kwargs) -> List[MemoryItem]:
"""检索相关记忆
Args:
query: 查询内容
limit: 返回数量限制
**kwargs: 其他检索参数
Returns:
相关记忆列表
"""
pass
@abstractmethod
def update(self, memory_id: str, content: str = None,
importance: float = None, metadata: Dict[str, Any] = None) -> bool:
"""更新记忆
Args:
memory_id: 记忆ID
content: 新内容
importance: 新重要性
metadata: 新元数据
Returns:
是否更新成功
"""
pass
@abstractmethod
def remove(self, memory_id: str) -> bool:
"""删除记忆
Args:
memory_id: 记忆ID
Returns:
是否删除成功
"""
pass
@abstractmethod
def has_memory(self, memory_id: str) -> bool:
"""检查记忆是否存在
Args:
memory_id: 记忆ID
Returns:
是否存在
"""
pass
@abstractmethod
def clear(self):
"""清空所有记忆"""
pass
@abstractmethod
def get_stats(self) -> Dict[str, Any]:
"""获取记忆统计信息
Returns:
统计信息字典
"""
pass
def _generate_id(self) -> str:
"""生成记忆ID"""
import uuid
return str(uuid.uuid4())
def _calculate_importance(self, content: str, base_importance: float = 0.5) -> float:
"""计算记忆重要性
Args:
content: 记忆内容
base_importance: 基础重要性
Returns:
计算后的重要性分数
"""
importance = base_importance
# 基于内容长度
if len(content) > 100:
importance += 0.1
# 基于关键词
important_keywords = ["重要", "关键", "必须", "注意", "警告", "错误"]
if any(keyword in content for keyword in important_keywords):
importance += 0.2
return max(0.0, min(1.0, importance))
def __str__(self) -> str:
stats = self.get_stats()
return f"{self.__class__.__name__}(count={stats.get('count', 0)})"
def __repr__(self) -> str:
return self.__str__()
2.1 核心组件
1. MemoryItem 数据结构
python
class MemoryItem(BaseModel):
"""记忆项数据结构"""
id: str
content: str
memory_type: str
user_id: str
timestamp: datetime
importance: float = 0.5
metadata: Dict[str, Any] = {}
class Config:
arbitrary_types_allowed = True
功能 :定义记忆项的标准数据结构,包含以下字段:
- id :记忆唯一标识符
- content :记忆内容
- memory_type :记忆类型(如 working、episodic、semantic 等)
- user_id :用户标识符
- timestamp :创建时间
- importance :重要性分数(0-1),默认 0.5
- metadata :元数据字典,用于存储额外信息
技术点 :
- 继承自 Pydantic 的 BaseModel ,提供数据验证和序列化功能
- 设置 arbitrary_types_allowed = True ,允许存储任意类型的元数据
2. MemoryConfig 配置类
python
class MemoryConfig(BaseModel):
"""记忆系统配置"""
# 存储路径
storage_path: str = "./memory_data"
# 统计显示用的基础配置(仅用于展示)
max_capacity: int = 100
importance_threshold: float = 0.1
decay_factor: float = 0.95
# 工作记忆特定配置
working_memory_capacity: int = 10
working_memory_tokens: int = 2000
working_memory_ttl_minutes: int = 120
# 感知记忆特定配置
perceptual_memory_modalities: List[str] = ["text", "image", "audio", "video"]
功能 :定义记忆系统的配置参数,包含:
- 存储配置:存储路径
- 基础配置:容量限制、重要性阈值、衰减因子
- 工作记忆配置:容量、token 限制、过期时间
- 感知记忆配置:支持的模态类型
技术点 :
- 使用 Pydantic 模型管理配置,提供默认值
- 模块化配置设计,便于不同记忆类型使用不同配置
3. BaseMemory 抽象基类
功能 :定义所有记忆类型的通用接口和行为,是一个抽象基类。
python
class BaseMemory(ABC):
"""记忆基类
定义所有记忆类型的通用接口和行为
"""
def __init__(self, config: MemoryConfig, storage_backend=None):
self.config = config
self.storage = storage_backend
self.memory_type = self.__class__.__name__.lower().replace("memory", "")
@abstractmethod
def add(self, memory_item: MemoryItem) -> str:
"""添加记忆项
Args:
memory_item: 记忆项对象
Returns:
记忆ID
"""
pass
@abstractmethod
def retrieve(self, query: str, limit: int = 5, **kwargs) -> List[MemoryItem]:
"""检索相关记忆
Args:
query: 查询内容
limit: 返回数量限制
**kwargs: 其他检索参数
Returns:
相关记忆列表
"""
pass
@abstractmethod
def update(self, memory_id: str, content: str = None,
importance: float = None, metadata: Dict[str, Any] = None) -> bool:
"""更新记忆
Args:
memory_id: 记忆ID
content: 新内容
importance: 新重要性
metadata: 新元数据
Returns:
是否更新成功
"""
pass
@abstractmethod
def remove(self, memory_id: str) -> bool:
"""删除记忆
Args:
memory_id: 记忆ID
Returns:
是否删除成功
"""
pass
@abstractmethod
def has_memory(self, memory_id: str) -> bool:
"""检查记忆是否存在
Args:
memory_id: 记忆ID
Returns:
是否存在
"""
pass
@abstractmethod
def clear(self):
"""清空所有记忆"""
pass
@abstractmethod
def get_stats(self) -> Dict[str, Any]:
"""获取记忆统计信息
Returns:
统计信息字典
"""
pass
def _generate_id(self) -> str:
"""生成记忆ID"""
import uuid
return str(uuid.uuid4())
def _calculate_importance(self, content: str, base_importance: float = 0.5) -> float:
"""计算记忆重要性
Args:
content: 记忆内容
base_importance: 基础重要性
Returns:
计算后的重要性分数
"""
importance = base_importance
# 基于内容长度
if len(content) > 100:
importance += 0.1
# 基于关键词
important_keywords = ["重要", "关键", "必须", "注意", "警告", "错误"]
if any(keyword in content for keyword in important_keywords):
importance += 0.2
return max(0.0, min(1.0, importance))
def __str__(self) -> str:
stats = self.get_stats()
return f"{self.__class__.__name__}(count={stats.get('count', 0)})"
def __repr__(self) -> str:
return self.__str__()
核心方法 :
-
抽象方法 (子类必须实现):
- add() :添加记忆项
- retrieve() :检索相关记忆
- update() :更新记忆
- remove() :删除记忆
- has_memory() :检查记忆是否存在
- clear() :清空所有记忆
- get_stats() :获取记忆统计信息
-
具体方法 (基类实现):
- _generate_id() :生成唯一记忆ID
- _calculate_importance() :计算记忆重要性
__str__():字符串表示__repr__():官方字符串表示
3. Python如何实现多参数构造函数
- 一个类可以没有
__init__,照样能正常用。
只要你的类 不需要在创建对象时传参数、不需要初始化变量 ,就可以不写。
python
class Tool:
def say_hi(self):
print("你好")
# 照样能创建对象
t = Tool()
t.say_hi()
- 什么时候必须写 init?
在创建对象时,自动做一些初始化工作。
比如:
- 传入参数
- 给对象绑定属性(name、age、model_path 等)
- 初始化配置、session、数据库连接
- 如果你不写
__init__,Python 会自动给你一个默认的空 init,类似这样:
python
def __init__(self):
pass
- 想实现 "不同参数类型的构造" 怎么办?
这叫 多构造器模式。
python
class Person:
def __init__(self, name="", age=0):
self.name = name
self.age = age
# 方式1:从名字创建
@classmethod
def from_name(cls, name):
return cls(name=name)
# 方式2:从身份证信息创建
@classmethod
def from_id(cls, id_card):
name = id_card["name"]
age = id_card["age"]
return cls(name, age)
# 使用
p1 = Person.from_name("张三")
p2 = Person.from_id({"name":"李四","age":30})
4. package下的__init__.py
__init__.py是Python包(package)中一个特殊的文件,它主要有以下作用:
- 标记文件夹为 Python 包
只要目录里有__init__.py
bash
my_package/
__init__.py
a.py
b.py
你就能:
python
import my_package
from my_package import a
- 统一暴露接口(最常用!)
在__init__.py里写:
python
from .a import ClassA
from .b import ClassB
外面就能直接从包导入,不用进子文件
python
from my_package import ClassA, ClassB
否则你必须写:
python
from my_package.a import ClassA
- 工程级写法
python
"""HelloAgents记忆系统模块
按照第8章架构设计的分层记忆系统:
- Memory Core Layer: 记忆核心层
- Memory Types Layer: 记忆类型层
- Storage Layer: 存储层
- Integration Layer: 集成层
"""
# Memory Core Layer (记忆核心层)
from .manager import MemoryManager
# Memory Types Layer (记忆类型层)
from .types.working import WorkingMemory
from .types.episodic import EpisodicMemory
from .types.semantic import SemanticMemory
from .types.perceptual import PerceptualMemory
# Storage Layer (存储层)
from .storage.document_store import DocumentStore, SQLiteDocumentStore
# Base classes and utilities
from .base import MemoryItem, MemoryConfig, BaseMemory
__all__ = [
# Core Layer
"MemoryManager",
# Memory Types
"WorkingMemory",
"EpisodicMemory",
"SemanticMemory",
"PerceptualMemory",
# Storage Layer
"DocumentStore",
"SQLiteDocumentStore",
# Base
"MemoryItem",
"MemoryConfig",
"BaseMemory"
]

附录
1.参考 hello-agents https://hello-agents.datawhale.cc/#/./chapter8/第八章 记忆与检索