拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Agno × SurrealDB 记忆管理实战:从零实现 Agent 持久化记忆的完整指南

Agno × SurrealDB 记忆管理实战从零实现 Agent 持久化记忆的完整指南【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agnoAgno原 Phidata将 SurrealDB 作为 Agent 记忆Memory的持久化后端为记忆管理提供高可用、可查询的存储底座。本指南以cookbook/integrations/surrealdb/目录下的 5 个示例脚本为主线从连接配置、CRUD 操作、批量记忆创建、自定义提取指令、多检索方式到 Agent 内嵌记忆工具控制逐步演示如何用 Agno 的SurrealDb与MemoryManager搭建一套完整的 Agent 记忆体系。读完本文你将掌握 SurrealDB 记忆后端的全部核心用法并能直接运行仓库中的示例代码验证效果。一、SurrealDB 记忆集成概览在 Agno 中SurrealDB 被定位为Agent 记忆管理memory management的后端存储。相关示例位于仓库的 cookbook/integrations/surrealdb/ 目录共包含 5 个示例脚本覆盖记忆管理的不同层面示例文件核心主题关键 APIstandalone_memory_surreal.py手动增 / 查 / 删 / 改记忆add_user_memory、get_user_memories、delete_user_memory、replace_user_memorymemory_creation.py从文本与消息历史创建记忆create_user_memories、add_user_memorycustom_memory_instructions.py自定义记忆提取指令MemoryManager(memory_capture_instructions...)memory_search_surreal.py多种记忆检索方式search_user_memories(retrieval_method...)db_tools_control.py控制 Agent 记忆工具的增 / 改 / 删 / 清MemoryManager(add_memoriesTrue, update_memoriesTrue)、enable_agentic_memory运行环境为仓库自带的 demo 虚拟环境所有示例统一通过以下方式执行.venvs/demo/bin/python cookbook/integrations/surrealdb/file.py例如运行第一个记忆操作示例.venvs/demo/bin/python cookbook/integrations/surrealdb/standalone_memory_surreal.py关于运行前提示例通过 WebSocket 连接本机 SurrealDBws://localhost:8000因此需要先启动 SurrealDB 服务端并创建好命名空间namespace与数据库database。仓库也提供了便捷的启动脚本 scripts/run_surrealdb.shWindows 对应 scripts/run_surrealdb.bat。二、连接配置SurrealDb 数据库封装所有示例的第一步都是构造一个SurrealDb数据库实例连接参数高度统一from agno.db.surrealdb import SurrealDb SURREALDB_URL ws://localhost:8000 SURREALDB_USER root SURREALDB_PASSWORD root SURREALDB_NAMESPACE agno SURREALDB_DATABASE memories creds {username: SURREALDB_USER, password: SURREALDB_PASSWORD} db SurrealDb(None, SURREALDB_URL, creds, SURREALDB_NAMESPACE, SURREALDB_DATABASE)SurrealDb的构造函数签名见 libs/agno/agno/db/surrealdb/surrealdb.py为SurrealDb( client, # 阻塞式连接对象可为 BlockingWsSurrealConnectionWebSocket或 BlockingHttpSurrealConnectionHTTP传 None 时按 URL 自动构建 db_url, # 数据库地址示例中为 ws://localhost:8000 db_creds, # 凭据字典示例中为 {username: root, password: root} db_ns, # SurrealDB 命名空间namespace示例为 agno db_db, # SurrealDB 数据库名database示例为 memories # 以下均为可选参数 # session_table / runs_table / memory_table / metrics_table / eval_table # knowledge_table / traces_table / spans_table / id )从源码看SurrealDb还默认维护了多张表除agno_users、agno_agents、agno_teams、agno_workflows等表名外记忆数据存放于memory_table默认记忆表。client传None时会在首次访问client属性时通过build_client(db_url, db_creds, db_ns, db_db)惰性构建连接见 surrealdb.py。这意味着你可以先声明配置、延迟到实际使用时再建立真实连接。SurrealDb继承自BaseDb与 Agno 的会话存储、运行记录、知识库、观测追踪等能力共用一套数据库抽象因此它不只是记忆后端——同一套实例还可用于session_table、traces_table等本文聚焦记忆场景。三、手动记忆操作增、查、删、改standalone_memory_surreal.py 演示了最底层的记忆 CRUD 操作全程不需要 LLM 参与是理解记忆数据模型的最佳入口。它引入了两个核心类型from agno.memory import MemoryManager, UserMemoryUserMemory是记忆的最小单元包含memory记忆文本内容与topics记忆主题标签字段。3.1 添加记忆Add为默认用户不指定user_id时添加记忆memory MemoryManager(dbdb) memory.add_user_memory( memoryUserMemory(memoryThe users name is John Doe, topics[name]), ) print(Memories:) pprint(memory.get_user_memories())为指定用户jane_doeexample.com添加多条记忆并捕获返回的memory_id供后续删除 / 替换使用jane_doe_id jane_doeexample.com memory_id_1 memory.add_user_memory( memoryUserMemory(memoryThe users name is Jane Doe, topics[name]), user_idjane_doe_id, ) memory_id_2 memory.add_user_memory( memoryUserMemory(memoryShe likes to play tennis, topics[hobbies]), user_idjane_doe_id, )示例中的输出统一使用rich.pretty.pprint美化打印便于阅读结构化记忆数据。3.2 查询记忆Getmemories memory.get_user_memories(user_idjane_doe_id) pprint(memories)从源码看get_user_memories在 libs/agno/agno/memory/manager.py 中定义同样遵循user_id缺省时使用default用户的约定返回Optional[List[UserMemory]]。3.3 删除记忆Delete按user_id memory_id精确定位删除assert memory_id_2 is not None memory.delete_user_memory(user_idjane_doe_id, memory_idmemory_id_2) memories memory.get_user_memories(user_idjane_doe_id) pprint(memories) # 此时 hobbies 记忆已不存在3.4 替换记忆Replace以新的UserMemory覆盖指定memory_id的旧记忆assert memory_id_1 is not None memory.replace_user_memory( memory_idmemory_id_1, memoryUserMemory(memoryThe users name is Jane Mary Doe, topics[name]), user_idjane_doe_id, ) memories memory.get_user_memories(user_idjane_doe_id) pprint(memories) # 姓名已更新为 Jane Mary Doereplace_user_memory、delete_user_memory的定义分别位于 manager.py 与 manager.py。这套查 ID → 删 / 改的流程是构建记忆管理工具的基础模式。四、自动记忆创建从文本与消息历史提取记忆memory_creation.py 展示了两种记忆来源一段自然语言文本以及一段多轮对话的消息历史。此时MemoryManager需要绑定一个 LLM 模型示例使用OpenAIChat(idgpt-5.6-luna)由模型负责从原始内容中提炼记忆from agno.models.openai import OpenAIChat memory MemoryManager(modelOpenAIChat(idgpt-5.6-luna), dbmemory_db)4.1 从文本创建记忆add_user_memory传入不带topics的UserMemory时由模型自动提炼主题john_doe_id john_doeexample.com memory.add_user_memory( memoryUserMemory( memory I enjoy hiking in the mountains on weekends, reading science fiction novels before bed, cooking new recipes from different cultures, playing chess with friends, and attending live music concerts whenever possible. Photography has become a recent passion of mine, especially capturing landscapes and street scenes. I also like to meditate in the mornings and practice yoga to stay centered. ), user_idjohn_doe_id, ) memories memory.get_user_memories(user_idjohn_doe_id) print(John Does memories:) pprint(memories)4.2 从消息历史创建记忆create_user_memories接受一组Message对象从多轮对话中抽取用户画像信息from agno.models.message import Message jane_doe_id jane_doeexample.com memory.create_user_memories( messages[ Message(roleuser, contentMy name is Jane Doe), Message(roleassistant, contentThat is great!), Message(roleuser, contentI like to play chess), Message(roleassistant, contentThat is great!), ], user_idjane_doe_id, ) memories memory.get_user_memories(user_idjane_doe_id) print(Jane Does memories:) pprint(memories)create_user_memories在源码中的定义位于 manager.py它内部同样会调用模型完成记忆抽取与写入。其进阶用法见下一节的自定义指令示例传入更长的、含纠错与更新语义的消息历史模型会结合上下文生成、修正记忆例如忘记我下棋我更喜欢桌游这类陈述。五、自定义记忆提取指令控制记住什么、忽略什么custom_memory_instructions.py 的核心价值在于通过memory_capture_instructions参数约束 LLM 的记忆提取范围实现按需记忆。示例同时创建了两个MemoryManager分别用于对比from agno.memory import MemoryManager from agno.models.openai import OpenAIChat from agno.models.anthropic.claude import Claude # 自定义提取指令只记录学术兴趣 custom_memory_manager MemoryManager( modelOpenAIChat(idgpt-5.6-luna), memory_capture_instructions\ Memories should only include details about the users academic interests. Only include which subjects they are interested in. Ignore names, hobbies, and personal interests. , dbmemory_db, ) # 默认提取行为对照 jane_memory_manager MemoryManager( modelClaude(idclaude-3-5-sonnet-latest), dbmemory_db, )5.1 受指令约束的记忆创建给 John Doe 输入一段包含姓名、爱好远足、科幻小说、烹饪、象棋与学术兴趣宇宙历史、天文话题的自我介绍由于指令明确要求只记录学术兴趣、忽略姓名 / 爱好 / 个人兴趣最终生成的记忆应仅包含天文与宇宙相关条目custom_memory_manager.create_user_memories( message\ My name is John Doe. I enjoy hiking in the mountains on weekends, reading science fiction novels before bed, cooking new recipes from different cultures, playing chess with friends. I am interested to learn about the history of the universe and other astronomical topics. , user_idjohn_doe_id, ) memories custom_memory_manager.get_user_memories(user_idjohn_doe_id) print(John Does memories:) pprint(memories)5.2 结合消息历史与纠错语义对 Jane Doe 则传入一长串消息历史其中包含信息更迭我更喜欢玩桌游如龙与地下城覆盖了我喜欢下棋、新信息我对宇宙历史与天文话题感兴趣、我对物理感兴趣给我讲讲量子力学等复杂语义由默认指令的MemoryManager自主提炼jane_memory_manager.create_user_memories( messages[ Message(roleuser, contentHi, how are you?), Message(roleassistant, contentIm good, thank you!), Message(roleuser, contentWhat are you capable of?), Message( roleassistant, contentI can help you with your homework and answer questions about the universe., ), Message(roleuser, contentMy name is Jane Doe), Message(roleuser, contentI like to play chess), Message( roleuser, contentActually, forget that I like to play chess. I more enjoy playing table top games like dungeons and dragons, ), Message( roleuser, contentIm also interested in learning about the history of the universe and other astronomical topics., ), Message(roleassistant, contentThat is great!), Message( roleuser, contentI am really interested in physics. Tell me about quantum mechanics?, ), ], user_idjane_doe_id, ) memories jane_memory_manager.get_user_memories(user_idjane_doe_id) print(Jane Does memories:) pprint(memories)这一示例说明同一套 SurrealDB 后端可以同时承载精准约束型与通用型两类记忆策略方便按业务场景如教育类应用只记学术画像定制记忆粒度。六、记忆检索last_n、first_n 与 agentic 三种方式memory_search_surreal.py 演示如何从 SurrealDB 中按需检索记忆。先为 John Doe 写入两条记忆作为检索样本memory.add_user_memory( memoryUserMemory(memoryThe user enjoys hiking in the mountains on weekends), user_idjohn_doe_id, ) memory.add_user_memory( memoryUserMemory(memoryThe user enjoys reading science fiction novels before bed), user_idjohn_doe_id, ) print(John Does memories:) pprint(memory.get_user_memories(user_idjohn_doe_id))随后调用search_user_memories对比三种检索方式# 最近 N 条last_n默认方式 memories memory.search_user_memories( user_idjohn_doe_id, limit1, retrieval_methodlast_n ) print(\nJohn Does last_n memories:) pprint(memories) # 最早 N 条first_n memories memory.search_user_memories( user_idjohn_doe_id, limit1, retrieval_methodfirst_n ) print(\nJohn Does first_n memories:) pprint(memories) # 与查询语义最相关的记忆agentic需提供 query memories memory.search_user_memories( user_idjohn_doe_id, queryWhat does the user like to do on weekends?, retrieval_methodagentic, ) print(\nJohn Does memories similar to the query (agentic):) pprint(memories)search_user_memories的源码定义在 libs/agno/agno/memory/manager.py其参数语义如下参数取值说明user_id任意字符串缺省为default目标用户limit整数缺省返回全部返回记忆条数上限retrieval_methodlast_n/first_n/agentic检索策略缺省为last_nquery字符串仅agentic方式必填缺省会抛出ValueError(Query is required for agentic search)从源码看三种方式的内部实现路径不同last_n走_get_last_n_memoriesfirst_n走_get_first_n_memoriesagentic则调用_search_user_memories_agentic——后者借助绑定模型示例中为OpenAIChat对记忆做语义级筛选返回与查询最相关的记忆。此外agentic 检索在模型支持时优先使用原生结构化输出MemorySearchResponse否则回退到 JSON Schema 或json_object模式见 manager.py这保证了不同模型能力下的兼容性。七、在 Agent 中启用记忆记忆工具的行为控制db_tools_control.py 把记忆能力接入Agent本体通过add_memories/update_memories开关控制 Agent 记忆工具的行为边界from agno.agent.agent import Agent from agno.memory.manager import MemoryManager from agno.models.openai import OpenAIChat memory_manager_full MemoryManager( modelOpenAIChat(idgpt-5.6-luna), dbmemory_db, add_memoriesTrue, # 允许新增记忆 update_memoriesTrue, # 允许更新既有记忆 ) agent_full Agent( modelOpenAIChat(idgpt-5.6-luna), memory_managermemory_manager_full, enable_agentic_memoryTrue, # 开启 agentic 记忆对话中自主读写记忆 dbmemory_db, )随后在流式对话中验证记忆的写入、召回与更新闭环john_doe_id john_doeexample.com # 1. 首次对话写入初始记忆姓名 爱好 摄影 agent_full.print_response( My name is John Doe and I like to hike in the mountains on weekends. I also enjoy photography., streamTrue, user_idjohn_doe_id, ) # 2. 记忆召回询问自己的爱好 agent_full.print_response(What are my hobbies?, streamTrue, user_idjohn_doe_id) # 3. 记忆更新声明兴趣变更 agent_full.print_response( I no longer enjoy photography. Instead, Ive taken up rock climbing., streamTrue, user_idjohn_doe_id, ) # 4. 检查更新后的记忆内容 print(\nMemories after update:) memories memory_manager_full.get_user_memories(user_idjohn_doe_id) pprint([m.memory for m in memories] if memories else [])整个流程覆盖了记忆的增 → 查 → 改三个阶段Agent 首先将用户自我介绍提炼为记忆存入 SurrealDB随后在回答我的爱好时通过记忆召回保持多轮一致性最后当用户声明不再喜欢摄影时update_memoriesTrue允许 Agent 同步修订既有记忆更新后可通过get_user_memories直接验证。实际使用中可以通过调整add_memories/update_memories的组合来控制 Agent 的记忆写权限例如只读召回、只增不改、或完整读写enable_agentic_memory则决定是否让 Agent 在对话循环中自主调用记忆工具。八、代码质量规范check_cookbook_pattern 校验示例目录同时接受仓库 cookbook 的静态规范校验。TEST_LOG.md记录了校验结果通过check_cookbook_pattern.py对cookbook/integrations/surrealdb目录进行递归校验状态为PASS零违规。校验器位于 cookbook/scripts/check_cookbook_pattern.py采用 AST 静态分析主要检查以下规则模块 docstring每个.py文件顶部必须包含模块文档字符串分节横幅section banners源码需使用# ---或# 风格的分节注释如# Setup、# Create Memory Manager、# Run Example分节顺序包含 Create 的分节必须出现在包含 Run 的分节之前main 门卫非下划线前缀模块必须包含if __name__ __main__:执行门卫禁用 emojiPython 源码中不允许出现 emoji 字符。其 CLI 用法为.venvs/demo/bin/python cookbook/scripts/check_cookbook_pattern.py \ --base-dir cookbook/integrations/surrealdb --recursive支持--output-format json输出结构化违规报告。值得说明的是本次校验仅验证代码结构规范PASS零违规并未在本次执行中实际运行示例脚本——即规范通过与运行时行为是两回事实际功能验证仍需在 SurrealDB 服务可用时运行示例确认。九、扩展从集成示例到完整应用将上述能力组合起来可以快速搭建一个具备持久化记忆的 Agent 应用存储层用SurrealDb统一管理记忆也可复用其session_table、traces_table等能力相关存储示例见 cookbook/06_storage/记忆层按业务选择默认MemoryManager或带memory_capture_instructions的定制实例检索层会话短时用last_n/first_n语义召回用agenticAgent 层通过add_memories、update_memories、enable_agentic_memory精确控制记忆工具的读写边界。配合scripts/run_surrealdb.sh一键启动本地 SurrealDB即可按 cookbook/integrations/README.md 中的方式逐一运行示例脚本从手动 CRUD到Agent 自主记忆完整走通 SurrealDB 记忆链路。十、小结本文围绕 Agno 的 SurrealDB 记忆集成系统梳理了从连接配置、UserMemory数据模型、手动增删改查到 LLM 驱动的记忆创建、自定义提取指令、三种检索方式以及 Agent 内嵌记忆工具控制的全链路用法。核心要点如下SurrealDb是 Agno 统一的数据库封装client传None时惰性构建连接记忆默认落库到记忆表MemoryManager既可手动管理记忆add_user_memory/get_user_memories/delete_user_memory/replace_user_memory也可由模型自动创建记忆create_user_memoriesmemory_capture_instructions可以精确控制记什么、忽略什么适合需要约束记忆粒度的业务场景记忆检索支持last_n、first_n、agentic三种方式其中agentic依赖模型做语义筛选接入 Agent 后通过add_memories/update_memories/enable_agentic_memory控制记忆工具的读写行为实现多轮对话的持久化记忆闭环。示例代码均可在仓库的 cookbook/integrations/surrealdb/ 目录找到配合本地 SurrealDB 即可直接运行验证。【免费下载链接】agnoBuild, run, and manage agent platforms.项目地址: https://gitcode.com/GitHub_Trending/ag/agno创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门