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:记忆压缩算法
SummarizeStrategy 是 MemoryOptimizationStrategy 的具体实现,将多条记忆合并为单一综合摘要:
# 伪代码:压缩流程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_futuremodel_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 是抽象基类,支持扩展。
替代方案:同时支持多种策略(如时间窗口截断、主题聚类),根据场景自动选择。这需要用户在配置中指定策略类型。