我和我的 AI Agent(3)记忆模块设计上花了不少心思,看看记忆细胞和记忆片段是如何设计以及实现的

github项目

在 Agent 框架设计中,记忆模块扮演着至关重要的角色,使得 Agent 不再是无状态的独立个体,而是能够记住过去的交互、经验和知识,从而做出更智能、更连贯的决策和行为。

记忆可能看作 Agent 背后一系列状态组成,对于 Agent 过往记录,不过应该如何组织记忆。

更多视频在 B 站 zidea2015 获取 B站 zidea2015

记忆单元(cell)

记忆细胞是记忆最小的单位,每一个记忆细胞会持有一个 message,并且将其其持有 message 理解和消化,得到该 message 的概要,这个概要用于随后信息之间检索。是否需要对于 message 进行概要,取决两个方面,第一个方面是 message 类型,还有就是 message 的体积,也就是只是针对 user 和 AI 类型并且超过一定大小的 message 才会进行概要(summarize)

你提出的策略,即对用户和 AI 类型且超过一定大小的消息进行概要,是一个在对话记忆系统中实现高效信息检索的有效方法。通过将记忆组织成携带消息的记忆细胞,并对特定类型的长消息进行概要,可以显著提高系统的性能和可扩展性。在实际应用中,需要仔细考虑消息类型的定义、体积阈值的设定以及选择合适的概要方法。

信息损失 概要本质上是一种信息压缩,可能会丢失一些细节或细微差别。需要设计有效的概要方法以最大程度地保留关键信息。 概要质量 概要的质量直接影响后续检索的准确性。需要使用合适的自然语言处理技术来生成高质量的概要。 计算成本 因为现在生成概要是基于大语言模型,所以需要考虑成本。生成概要本身也需要计算资源。需要在概要的收益和成本之间进行权衡。可以通过其他方法来解决概要,例如提取关键词来作为信息匹配。

  • 词向量平均 (Word Embedding Averaging)
  • 句子/段落嵌入 (Sentence/Paragraph Embeddings)
  • 词语移动距离 (Word Mover's Distance, WMD)
  • 上下文嵌入相似度 (Contextual Embedding Similarity)
  • 生成式评估 (Generative Evaluation - 需要更复杂的设置)
  • 基于任务的评估 (Task-based Evaluation)
python 复制代码
class MemoryCell(BaseModel):
    message: BaseMessage
    token_size: int
    summary: Optional[str]
    model_name: Optional[str] = Field(default="deepseek-chat")
    memory_id: Optional[str] = Field(default="")
    timestamp: float
    metadata :Dict[str,Any]
  • 这里时间戳(timestamp)是用于计算记忆衰减
  • 高效存储和检索,记忆模块需要能够高效地存储大量的记忆数据,并且能够根据需要快速地检索相关信息可以考虑存储该数据类型的数据媒体,然后可以提供 metadata
  • 多媒体数据支持是体现在 BaseMessage
  • 记忆单元持有一个 BaseMessage 这是一个必填字段,其他字段都是可选字段
  • 其他字段初始后自动自动通过计算进行赋值

记忆片段(block)

那么应该如何实现在初始化 MemoryCell(AIMessage(content="写一个函数")),对于其字段进行自动赋值 还有就是如何为 MemoryCell 设置类上属性,也就是所有实例都会共享的属性

python 复制代码
from typing import Union,List
from pydantic import BaseModel,Field
from .memory_cell import MemoryCell

class MemoryCategory(BaseModel):
    name:str = Field(title="记忆类别的名称",examples=['情景记忆'])
    title:str
    description:str = Field(title="记忆类别的描述")
    examples:List[str]



class MemoryBlock(BaseModel):
    memory_block_id:str
    memory_cells:List[MemoryCell]
    memory_entities:List[str]
    memory_category:MemoryCategory

生成 message ,以 SystemMessage 触发,然后就是 AIMessage HumanMessage 交互,中间可能穿插 CodeMessage 等其他 message,如何判断截取记忆块

python 复制代码
def should_extract_memory_block(messages: List[BaseMessage], category_fn: Callable[...,str]) -> bool:
    """
    判断是否应该从消息历史中截取记忆块。

    Args:
        messages: 完整的消息历史列表。
       

    Returns:
        True 如果应该截取记忆块,False 否则。
    """
    if not messages:
        return False

    # 检查是否存在以 SystemMessage 开头,并且后续有交互
    if not isinstance(messages[0], SystemMessage):
        return False

    # 遍历消息历史,查找是否包含属于目标 MemoryCategory 的信息
    for message in messages:
        # 触发条件 
        result = trigger_category_fn(message)
        if result:
            return True
    
    return False

触发条件: 首先我们来判断消息记录不为空。然后消息历史以 SystemMessage 开头(表示 Agent 的初始化状态)。在后续的消息中,至少存在一条消息的 additional_kwargs 中包含一个 memory_category 字段,并且该字段是一个 MemoryCategory 实例,其 name 属性与 trigger_category_name 相匹配。 这个函数用于判断是否满足截取记忆块的基本条件。你可以根据更复杂的业务逻辑调整判断标准。

python 复制代码
def extract_memory_block(messages: List[BaseMessage], category: MemoryCategory) -> Union[MemoryBlock, None]:
    pass

对于 extract_memory_block(messages, category) 函数:

目标类别 : 接收完整的消息历史和一个目标 MemoryCategory 实例。 遍历消息: 遍历消息历史中的每一条消息。

相关推荐
www_pp_26 分钟前
# 使用 Dlib 和 OpenCV 实现基于深度学习的人脸检测
人工智能·深度学习·opencv
Jackilina_Stone26 分钟前
【模型量化】GPTQ 与 AutoGPTQ
人工智能·python·gptq
skywalk816327 分钟前
Cline – OpenRouter 排名第一的CLI 和 编辑器 的 AI 助手
人工智能·编辑器·cline
橙色小博1 小时前
PyTorch中的各种损失函数的详细解析与通俗理解!
人工智能·pytorch·python·深度学习·神经网络·机器学习
小森77672 小时前
(三)机器学习---线性回归及其Python实现
人工智能·python·算法·机器学习·回归·线性回归
-XWB-2 小时前
【LLM】使用MySQL MCP Server让大模型轻松操作本地数据库
人工智能·python·自然语言处理
PacosonSWJTU3 小时前
python基础-13-处理excel电子表格
开发语言·python·excel
訾博ZiBo4 小时前
AI日报 - 2025年4月8日
人工智能
James. 常德 student4 小时前
深度学习之微调
人工智能·深度学习
小军要奋进4 小时前
httpx模块的使用
笔记·爬虫·python·学习·httpx