首页
/ Agno 02_agents 示例详解:用 MemoryManager 与 LearningMachine 为 Agent 构建跨会话持久记忆

Agno 02_agents 示例详解:用 MemoryManager 与 LearningMachine 为 Agent 构建跨会话持久记忆

2026-09-05 16:52:42作者:裘旻烁

本文围绕 Agno 仓库 cookbook/02_agents/06_memory_and_learning 目录中的两个官方示例展开:memory_manager.py 演示如何为 Agent 提供跨会话的持久记忆(MemoryManager),learning_machine.py 演示如何基于 LearningMachine 实现 agentic 模式的用户画像学习。读完本文,你将理解两种记忆机制的适用边界、关键参数(enable_agentic_memoryLearningMode.AGENTIC、记忆数据库注入等)的作用方式,并能按文档给出的环境配置直接复现这两个可运行的完整示例。

一、文档定位与示例文件清单

cookbook/02_agents/06_memory_and_learning 是 Agent 章节(02_agents)下专门演示"持久记忆与学习行为"(persistent memory and learning behavior)的示例目录。目录中的 README.md 列出了两个核心文件:

文件 作用
learning_machine.py 演示基于 LearningMachine 的学习能力(以 agentic 模式维护用户画像)
memory_manager.py 使用 MemoryManager 为 Agent 提供跨会话的持久记忆

两个示例的共同思路是:在两次独立的交互之间,Agent 能把第一次交互中获得的信息(姓名、偏好)沉淀下来,并在第二次交互中被主动调用。区别在于沉淀的载体与机制:MemoryManager 走"记忆捕获 + 记忆检索"路线,LearningMachine 则走"结构化学习类型(用户画像、实体记忆、决策日志等)"路线。

二、前置条件与环境准备

README 给出的运行前置条件(原文完整继承):

  • 使用 direnv allow 加载环境变量(其中必须包含 OPENAI_API_KEY);
  • 通过 ./scripts/demo_setup.sh 创建演示环境(对应仓库根目录的 scripts/demo_setup.sh),随后使用 .venvs/demo/bin/python 运行 cookbook;
  • 部分示例依赖可选的本地服务(例如 pgvector)或特定服务商的 API Key。

运行命令统一为:

.venvs/demo/bin/python cookbook/02_agents/06_memory_and_learning/<file>.py

两个示例都使用 OpenAIResponses 模型,因此 OPENAI_API_KEY 是硬性依赖;而记忆/学习数据的落盘在本示例中使用 SQLite,不需要额外数据库服务。

三、示例一:MemoryManager 跨会话持久记忆

3.1 完整示例代码

cookbook/02_agents/06_memory_and_learning/memory_manager.py 的完整内容如下:

"""
Memory Manager
=============================

Use a MemoryManager to give agents persistent memory across sessions.
"""

from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.memory.manager import MemoryManager
from agno.models.openai import OpenAIResponses

# ---------------------------------------------------------------------------
# Create Agent
# ---------------------------------------------------------------------------
db = SqliteDb(db_file="tmp/memory_demo.db")

agent = Agent(
    model=OpenAIResponses(id="gpt-5.2"),
    db=db,
    # Enable agentic memory so the agent can store and retrieve memories
    enable_agentic_memory=True,
    # Provide a MemoryManager for structured memory operations
    memory_manager=MemoryManager(
        db=db,
        model=OpenAIResponses(id="gpt-5-mini"),
    ),
    markdown=True,
)

# ---------------------------------------------------------------------------
# Run Agent
# ---------------------------------------------------------------------------
if __name__ == "__main__":
    # First interaction: tell the agent something to remember
    agent.print_response(
        "My name is Alice and I prefer Python over JavaScript.",
        stream=True,
    )

    print("\n--- Second interaction ---\n")

    # Second interaction: the agent should recall the preference
    agent.print_response(
        "What programming language do I prefer?",
        stream=True,
    )

示例的验证逻辑非常直接:第一次交互向 Agent 陈述"My name is Alice and I prefer Python over JavaScript.",第二次交互提问"What programming language do I prefer?"。如果 Agent 能回答出 Python,说明记忆已成功持久化并在会话间被召回。

3.2 关键参数解读

  • db = SqliteDb(db_file="tmp/memory_demo.db"):记忆与运行状态的落盘位置。同一个 db 实例同时传给 AgentMemoryManager,保证记忆读取/写入与 Agent 会话数据使用同一个存储后端。SqliteDb 来自 agno.db.sqlite,是本地零依赖的默认选择;生产环境可替换为其他实现(仓库 libs/agno/agno/db 下还有 PostgreSQL、Mongo、Redis 等后端)。
  • enable_agentic_memory=True:开启 agentic memory,使 Agent 自身具备存储与检索记忆的工具能力(源码注释即"Enable agentic memory so the agent can store and retrieve memories")。
  • memory_manager=MemoryManager(db=db, model=OpenAIResponses(id="gpt-5-mini")):提供结构化的记忆管理操作。注意这里使用了一个更小、更廉价的模型(gpt-5-mini)来执行记忆管理,而不是与主 Agent 相同的 gpt-5.2——记忆捕获本质上是辅助任务,用轻量模型控制成本是合理的工程做法。
  • 两次 print_response 调用未显式传 user_id:默认用户下两次交互共享同一记忆命名空间,因此偏好可以跨"会话"召回。

3.3 源码级实现:MemoryManager 到底做了什么

MemoryManager 定义在 libs/agno/agno/memory/manager.py。从源码结构看,它是一个 dataclass,核心字段包括:

  • model:执行记忆管理(记忆捕获、去重、更新)所用的模型。若未提供,get_model() 会回退到 OpenAIChat(id="gpt-4o")(见 manager.py#L112-L123),并在缺少 openai 包时打印明确的安装提示后退出。
  • system_message / memory_capture_instructions / additional_instructions:分别用于覆盖默认的 Manager 系统消息、默认的记忆捕获指令,以及追加附加指令。这三个参数是让记忆行为"可定制"的入口,默认值即可满足示例场景。
  • 四个数据库工具开关delete_memoriesclear_memoriesupdate_memoriesadd_memories,决定 Manager 向 Agent 暴露哪些记忆操作工具。注意 __init__ 签名中的默认值为 delete_memories=Falseclear_memories=Falseupdate_memories=Trueadd_memories=True(见 manager.py#L77-L93),即默认只开放"增、改",不开放"删、清",这与示例中不做删除操作的行为一致。
  • db:类型标注为 Optional[Union[BaseDb, AsyncBaseDb]](见 manager.py#L73),即同步/异步数据库基类均可。示例中读取记忆走 read_from_db():当未指定 user_id 时调用 db.get_user_memories() 读取全部记忆,并按 user_id 分组成字典(见 manager.py#L125-L139)。这解释了为什么示例中同一个 user_id 空间内的两次交互能互相"记住"对方。
  • debug_mode:置为 True 可打开 Manager 内部的调试日志,排查"为什么这条记忆没有被捕获"时很有用。

另外,Manager 内部定义了一个 MemorySearchResponse 模型(字段为 memory_ids),用于按语义相似度返回与查询最匹配的记忆 ID(见 manager.py#L36-L42),说明记忆召回支持基于相似度的检索路径。

四、示例二:LearningMachine 的 Agentic 学习

4.1 完整示例代码

cookbook/02_agents/06_memory_and_learning/learning_machine.py 的完整内容如下:

"""
Learning Machine
=============================

Learning Machine.
"""

from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.learn import LearningMachine, LearningMode, UserProfileConfig
from agno.models.openai import OpenAIResponses

# ---------------------------------------------------------------------------
# Setup
# ---------------------------------------------------------------------------
agent_db = SqliteDb(db_file="tmp/agents.db")

# ---------------------------------------------------------------------------
# Create Agent
# ---------------------------------------------------------------------------
agent = Agent(
    name="Learning Agent",
    model=OpenAIResponses(id="gpt-5.2"),
    db=agent_db,
    learning=LearningMachine(
        user_profile=UserProfileConfig(mode=LearningMode.AGENTIC),
    ),
    markdown=True,
)

# ---------------------------------------------------------------------------
# Run Agent
# ---------------------------------------------------------------------------
if __name__ == "__main__":
    user_id = "learning-demo-user"

    agent.print_response(
        "My name is Alex, and I prefer concise responses.",
        user_id=user_id,
        session_id="learning_session_1",
        stream=True,
    )

    agent.print_response(
        "What do you remember about me?",
        user_id=user_id,
        session_id="learning_session_2",
        stream=True,
    )

与 MemoryManager 示例相比,这个示例刻意强调了跨会话(cross-session):两次 print_response 使用同一个 user_idlearning-demo-user)但不同的 session_idlearning_session_1 / learning_session_2)。第一次会话陈述姓名与偏好("My name is Alex, and I prefer concise responses."),第二次会话直接提问"What do you remember about me?"——如果学习成果按用户(而非会话)维度持久化,第二次会话应当能复述出这两条信息。

4.2 关键参数解读

  • learning=LearningMachine(...)Agent 通过 learning 参数挂载学习系统。LearningMachine 是学习模块的统一入口,模块文档字符串(libs/agno/agno/learn/init.py)将其描述为"Unified learning system",与 Config(学习类型配置)、Schemas(学习类型数据结构)、Stores(存储后端)四大组件共同构成 agno.learn 包。
  • UserProfileConfig(mode=LearningMode.AGENTIC):只启用"用户画像"这一种学习类型,并指定其模式为 AGENTICLearningMode 是定义在 libs/agno/agno/learn/config.py 中的枚举,UserProfileConfigconfig.py#L57。从命名与枚举设计可以推断,AGENTIC 模式意味着由模型自主决定何时提取/更新画像字段,而不是按固定规则硬编码捕获。
  • agent_db = SqliteDb(db_file="tmp/agents.db"):学习数据同样依赖 db 落盘,且文件与 MemoryManager 示例(tmp/memory_demo.db)相互独立,避免两个演示互相污染。

4.3 源码级实现:learn 模块的结构

libs/agno/agno/learn 包的 __init__.py 导出了完整的组件面(见 learn/init.py#L41-L67):

  • 主类LearningMachine(实现位于 learn/machine.py#L82);
  • 六种学习类型的 ConfigUserProfileConfig(用户画像)、UserMemoryConfig(用户记忆)、EntityMemoryConfig(实体记忆)、SessionContextConfig(会话上下文)、LearnedKnowledgeConfig(习得知识)、DecisionLogConfig(决策日志);
  • 对应的 SchemasUserProfileMemoriesEntityMemorySessionContextLearnedKnowledgeDecisionLog
  • 对应的 StoresUserProfileStoreUserMemoryStoreEntityMemoryStoreSessionContextStoreLearnedKnowledgeStoreDecisionLogStore,以及通用基类 LearningStore

也就是说,示例中只开了 UserProfileConfig 一项,但同一套机制还可以按需叠加实体记忆、决策日志等其它学习类型——每种类型都有独立的 Config / Schema / Store 三元组,彼此正交。此外 learn 包还包含 curate.py(学习成果的整理/精炼)与 migrations.py(存储迁移)等支撑模块,说明学习数据在持久化层面有版本演进能力。

五、两种机制的对比与选型

维度 MemoryManager(memory_manager.py) LearningMachine(learning_machine.py)
启用方式 Agent(enable_agentic_memory=True, memory_manager=MemoryManager(...)) Agent(learning=LearningMachine(user_profile=UserProfileConfig(...)))
记忆载体 非结构化记忆条目,存于 db.get_user_memories() 可读取的用户记忆表 结构化学习类型(用户画像等),按类型分 Store
辅助模型 示例中显式指定 gpt-5-mini 降低记忆管理成本 由学习模式(如 AGENTIC)驱动,未单独指定
用户隔离 示例未显式传 user_id,使用默认用户 显式传 user_id 并跨两个 session_id 验证
典型问题 "我偏好什么语言?"(单点事实召回) "你记得我什么?"(画像式复述)

选型建议:如果只需要"记住用户说过的事实并能在后续会话中召回",MemoryManager 方案更直接;如果需要把用户信息沉淀为可管理、可演进的画像/实体/决策日志等结构化资产(配合 libs/agno/agno/learn 中六种学习类型),则应使用 LearningMachine。两者都要求为 Agent 与记忆/学习组件注入同一个 db 实例,这是示例中最容易被忽略的"隐性契约"。

六、测试记录与复现

cookbook/02_agents/06_memory_and_learning/TEST_LOG.md 记录了 2026-02-13 的验证结果:

  • learning_machine.py:PASS,5 秒内完成,"Ran successfully and produced expected output";
  • memory_manager.py:PASS,9 秒内完成,同样成功产出预期输出;
  • 测试环境为 .venvs/demo/bin/python,pgvector 服务处于运行状态。

复现步骤(与 README 一致):

# 1. 允许 direnv 加载 .env(需包含 OPENAI_API_KEY)
direnv allow

# 2. 创建 demo 虚拟环境
./scripts/demo_setup.sh

# 3. 分别运行两个示例
.venvs/demo/bin/python cookbook/02_agents/06_memory_and_learning/memory_manager.py
.venvs/demo/bin/python cookbook/02_agents/06_memory_and_learning/learning_machine.py

运行后可检查 tmp/memory_demo.dbtmp/agents.db 两个 SQLite 文件,确认记忆/学习数据确实被持久化。

七、小结

06_memory_and_learning 目录虽然只有两个示例脚本,但完整覆盖了 Agno Agent 的两条记忆/学习技术路线:

  1. MemoryManager 路线enable_agentic_memory + MemoryManager(db=..., model=...),通过 libs/agno/agno/memory/manager.py 中的可定制系统消息、记忆捕获指令与增/改/删/清四个工具开关,实现跨会话的事实记忆;
  2. LearningMachine 路线learning=LearningMachine(user_profile=UserProfileConfig(mode=LearningMode.AGENTIC)),依托 libs/agno/agno/learn 中"Config—Schema—Store"三件套,把用户画像等学习成果结构化地按用户维度持久化,并用不同 session_id 验证跨会话生效。

两条路线都以显式注入共享 db 为前提,都可用仓库自带的 scripts/demo_setup.sh 环境直接复现,适合作为在生产 Agent 中引入长期记忆前的最小可行验证方案。

登录后查看全文
热门项目推荐
相关项目推荐