跳转到内容

Agno 记忆管理与压缩策略

Agno 记忆管理与压缩策略

学习目标

本章将分析 Agno 的记忆系统架构:

  • MemoryManager 如何使用独立模型管理记忆 CRUD
  • SummarizeStrategy 的记忆压缩算法
  • 后台线程记忆创建与主管线的协同
  • 记忆工具的设计(add/update/delete/clear)

前置知识

建议先阅读:

下文假设你已理解上述概念,直接聚焦 Agno 的具体实现。


项目实践

MemoryManager:独立模型的记忆管理器

MemoryManager 是一个独立于 Agent 的组件,有自己的模型和系统提示:

# 伪代码:MemoryManager 配置
manager = MemoryManager(
model=OpenAIResponses(id="gpt-4o-mini"), # 独立模型,可用更便宜的模型
system_message="你是一个记忆管理助手...",
memory_capture_instructions="提取关于用户的重要信息...",
additional_instructions="特别关注用户的偏好和习惯。",
db=PostgresDb(db_url="..."),
# 工具开关
add_memories=True,
update_memories=True,
delete_memories=True,
clear_memories=True,
)

关键设计:MemoryManager 可以配置与主 Agent 不同的模型。记忆提取通常不需要最强的模型,使用更便宜的模型可以降低成本。

SummarizeStrategy:记忆压缩算法

SummarizeStrategyMemoryOptimizationStrategy 的具体实现,将多条记忆合并为单一综合摘要:

# 伪代码:压缩流程
class SummarizeStrategy(MemoryOptimizationStrategy):
def optimize(self, memories: List[UserMemory], model: Model) -> List[UserMemory]:
# 1. 收集所有记忆内容
memory_contents = [mem.memory for mem in memories if mem.memory]
# 2. 合并 topic(去重)
all_topics = []
for mem in memories:
if mem.topics:
all_topics.extend(mem.topics)
summarized_topics = list(set(all_topics)) if all_topics else None
# 3. 调用 LLM 压缩
system_prompt = "你是一个记忆压缩助手..."
response = model.chat([
Message(role="system", content=system_prompt),
Message(role="user", content="\n".join(memory_contents)),
])
# 4. 返回单一压缩后的记忆
return [UserMemory(
memory=response.text,
topics=summarized_topics,
user_id=memories[0].user_id,
)]

压缩保证

  • 所有事实信息不丢失(由 LLM 摘要保留)
  • Topic 分类去重合并(set(all_topics)
  • 检查 user_id 一致性,防止跨用户记忆泄漏
  • 检查 agent_id / team_id 一致性(记录日志)

后台线程记忆创建

记忆创建作为后台线程启动(管线步骤 7),与主执行管线并行:

# 伪代码:后台记忆创建
memory_future = _managers.start_memory_future(
agent,
run_messages=run_messages, # 需要完整的消息上下文
user_id=user_id,
existing_future=None, # 可传入已有的 future 复用
)
# 主管线继续执行模型调用,不等 memory_future
model_response = call_model_with_fallback(...)
# 管线末尾等待后台完成
wait_for_open_threads(memory_future, cultural_future, learning_future)

为什么用后台线程? 记忆提取需要完整的 run_messages(包含用户输入),但不需要模型响应。在等待模型调用的同时并行执行记忆提取,不增加用户感知延迟。

记忆 CRUD 工具

MemoryManager 向 Agent 暴露 4 个记忆操作工具:

工具功能默认启用
add_memories添加新记忆到数据库
update_memories更新已有记忆
delete_memories删除指定记忆(按 ID)
clear_memories清空用户的所有记忆

Agent 在对话中可以自主调用这些工具来管理记忆。

问题与规避

1. 跨用户记忆泄漏

如果 MemoryManager 的 user_id 处理不正确,可能导致 A 用户的记忆被写入 B 用户的命名空间。

规避:SummarizeStrategy 在 optimize 中检查所有记忆的 user_id 一致性,不一致时抛出 ValueError。MemoryManager 的 CRUD 工具始终传入当前 run 的 user_id

2. 记忆压缩的延迟

SummarizeStrategy 需要调用 LLM 进行压缩,在记忆数量多时可能耗时数秒。

规避:后台线程模式天然解决了这个问题——压缩在后台运行,不影响主响应。如果压缩未完成,主管线在步骤 12 等待,但此时用户已经收到了响应。

3. 记忆爆炸(记忆过多)

如果不进行压缩或淘汰,记忆数量会随交互线性增长,导致:

  • 数据库存储成本增加
  • 检索时返回过多候选记忆
  • 注入上下文时占用过多 token

规避

  • SummarizeStrategy 压缩多条记忆为一条
  • Curator(在 LearningMachine 中)负责后台淘汰
  • 可自定义 MemoryOptimizationStrategy 实现更激进的压缩

设计取舍

为什么 MemoryManager 使用独立模型?

Agno 的选择是将记忆管理与主 Agent 解耦:

  • 优势:记忆管理可以用更便宜的模型(如 gpt-4o-mini),降低成本
  • 代价:两个模型可能有不一致的记忆理解
  • 替代方案:共享主 Agent 模型——一致性更好,但成本更高

为什么 SummarizeStrategy 是单策略而非多策略?

目前只有 SummarizeStrategy 一个实现。MemoryOptimizationStrategy 是抽象基类,支持扩展。

替代方案:同时支持多种策略(如时间窗口截断、主题聚类),根据场景自动选择。这需要用户在配置中指定策略类型。

参考来源