当前位置: 首页 > news >正文

长期记忆存储:构建持久的 AI 记忆系统

长期记忆存储:构建持久的 AI 记忆系统

前言

长期记忆是 AI Agent 持续学习的关键。需要设计持久化存储方案,让 Agent 能够保存和恢复记忆。

我在多个项目中实现过长期记忆存储,今天分享一些设计和实现。

存储接口设计

from abc import ABC, abstractmethod from typing import List, Optional, Dict, Any class MemoryStoreBackend(ABC): """记忆存储后端""" @abstractmethod def save(self, memory: MemoryItem): """保存记忆""" pass @abstractmethod def load(self, memory_id: str) -> Optional[MemoryItem]: """加载记忆""" pass @abstractmethod def load_all(self) -> List[MemoryItem]: """加载所有记忆""" pass @abstractmethod def delete(self, memory_id: str): """删除记忆""" pass @abstractmethod def search_similar(self, embedding: List[float], top_k: int = 5) -> List[MemoryItem]: """相似性搜索""" pass

文件存储后端

import os import json from typing import List, Optional, Dict class FileMemoryStore(MemoryStoreBackend): """文件系统存储""" def __init__(self, storage_path: str = "./memory"): self.storage_path = storage_path self.memory_file = os.path.join(storage_path, "memories.json") self.ensure_storage() def ensure_storage(self): """确保存储目录存在""" os.makedirs(self.storage_path, exist_ok=True) def _load_data(self) -> Dict[str, Any]: """从文件加载数据""" if not os.path.exists(self.memory_file): return {} with open(self.memory_file, 'r', encoding='utf-8') as f: return json.load(f) def _save_data(self, data: Dict[str, Any]): """保存数据到文件""" with open(self.memory_file, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) def save(self, memory: MemoryItem): """保存记忆""" data = self._load_data() data[memory.id] = memory.to_dict() self._save_data(data) def load(self, memory_id: str) -> Optional[MemoryItem]: """加载记忆""" data = self._load_data() if memory_id not in data: return None return self._dict_to_memory(data[memory_id]) def load_all(self) -> List[MemoryItem]: """加载所有记忆""" data = self._load_data() return [ self._dict_to_memory(item) for item in data.values() ] def delete(self, memory_id: str): """删除记忆""" data = self._load_data() if memory_id in data: del data[memory_id] self._save_data(data) def _dict_to_memory(self, d: Dict) -> MemoryItem: """字典转记忆项""" return MemoryItem( id=d["id"], type=MemoryType(d["type"]), content=d["content"], metadata=d.get("metadata", {}), embedding=d.get("embedding"), timestamp=d.get("timestamp", 0), importance=d.get("importance", 1.0), tags=d.get("tags", []), access_count=d.get("access_count", 0), last_access=d.get("last_access") ) def search_similar(self, embedding: List[float], top_k: int = 5) -> List[MemoryItem]: """相似搜索(文件版本)""" # 简单实现:加载全部,计算相似度 memories = self.load_all() if not memories: return [] import numpy as np scored = [] for mem in memories: if mem.embedding: # 计算相似度 sim = np.dot(embedding, mem.embedding) / ( np.linalg.norm(embedding) * np.linalg.norm(mem.embedding) ) scored.append((sim, mem)) # 排序 scored.sort(key=lambda x: x[0], reverse=True) return [mem for sim, mem in scored[:top_k]]

数据库存储后端

import sqlite3 from typing import List, Optional class SQLiteMemoryStore(MemoryStoreBackend): """SQLite 存储""" def __init__(self, db_path: str = "./memory/memories.db"): self.db_path = db_path self.ensure_database() def ensure_database(self): """确保数据库存在""" os.makedirs(os.path.dirname(self.db_path), exist_ok=True) conn = sqlite3.connect(self.db_path) cursor = conn.cursor() cursor.execute(""" CREATE TABLE IF NOT EXISTS memories ( id TEXT PRIMARY KEY, type TEXT NOT NULL, content TEXT, metadata TEXT, embedding TEXT, timestamp REAL, importance REAL, tags TEXT, access_count INTEGER, last_access REAL ) """) conn.commit() conn.close() def save(self, memory: MemoryItem): """保存记忆""" import json conn = sqlite3.connect(self.db_path) cursor = conn.cursor() cursor.execute(""" INSERT OR REPLACE INTO memories (id, type, content, metadata, embedding, timestamp, importance, tags, access_count, last_access) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( memory.id, memory.type.value, str(memory.content), json.dumps(memory.metadata), json.dumps(memory.embedding) if memory.embedding else None, memory.timestamp, memory.importance, json.dumps(memory.tags), memory.access_count, memory.last_access )) conn.commit() conn.close() def load(self, memory_id: str) -> Optional[MemoryItem]: """加载记忆""" import json conn = sqlite3.connect(self.db_path) cursor = conn.cursor() cursor.execute("SELECT * FROM memories WHERE id = ?", (memory_id,)) row = cursor.fetchone() conn.close() if not row: return None return MemoryItem( id=row[0], type=MemoryType(row[1]), content=row[2], metadata=json.loads(row[3]) if row[3] else {}, embedding=json.loads(row[4]) if row[4] else None, timestamp=row[5] or 0, importance=row[6] or 1.0, tags=json.loads(row[7]) if row[7] else [], access_count=row[8] or 0, last_access=row[9] ) def load_all(self) -> List[MemoryItem]: """加载所有记忆""" import json conn = sqlite3.connect(self.db_path) cursor = conn.cursor() cursor.execute("SELECT * FROM memories") rows = cursor.fetchall() conn.close() memories = [] for row in rows: memories.append(MemoryItem( id=row[0], type=MemoryType(row[1]), content=row[2], metadata=json.loads(row[3]) if row[3] else {}, embedding=json.loads(row[4]) if row[4] else None, timestamp=row[5] or 0, importance=row[6] or 1.0, tags=json.loads(row[7]) if row[7] else [], access_count=row[8] or 0, last_access=row[9] )) return memories def delete(self, memory_id: str): """删除记忆""" conn = sqlite3.connect(self.db_path) cursor = conn.cursor() cursor.execute("DELETE FROM memories WHERE id = ?", (memory_id,)) conn.commit() conn.close() def search_similar(self, embedding: List[float], top_k: int = 5) -> List[MemoryItem]: """相似搜索""" # 简化版本 memories = self.load_all() import numpy as np scored = [] for mem in memories: if mem.embedding: sim = np.dot(embedding, mem.embedding) / ( np.linalg.norm(embedding) * np.linalg.norm(mem.embedding) ) scored.append((sim, mem)) scored.sort(key=lambda x: x[0], reverse=True) return [mem for sim, mem in scored[:top_k]]

完整的持久化记忆系统

class PersistentMemoryStore(MemoryStore): """持久化记忆存储""" def __init__(self, backend: MemoryStoreBackend, dimension: int = 768): super().__init__(dimension) self.backend = backend self._load_from_backend() def _load_from_backend(self): """从后端加载""" memories = self.backend.load_all() for mem in memories: self.memories[mem.id] = mem self.embeddings.append(mem.embedding) self.id_map.append(mem.id) self._rebuild_index() def add(self, memory: MemoryItem): """添加记忆""" super().add(memory) self.backend.save(memory) def delete(self, memory_id: str): """删除记忆""" if memory_id in self.memories: del self.memories[memory_id] # 重建索引 self.memories = {k: v for k, v in self.memories.items() if k != memory_id} self.embeddings = [self.memories[mid].embedding for mid in self.memories.keys()] self.id_map = list(self.memories.keys()) self._rebuild_index() self.backend.delete(memory_id) def save(self): """保存所有""" for mem in self.memories.values(): self.backend.save(mem)

总结

长期记忆存储要点:

  1. 后端抽象:统一的存储接口
  2. 多后端支持:文件、数据库等
  3. 增量存储:定期保存避免数据丢失
  4. 序列化:对象序列化存储
  5. 恢复机制:启动时自动恢复

实践建议:

  • 从小文件开始
  • 定期备份重要数据
  • 监控存储大小
  • 考虑使用专业的向量数据库
http://www.zskr.cn/news/1435845.html

相关文章:

  • 用Reflex全栈Python框架快速构建AI文生图Web应用
  • 洛雪音乐音源全攻略:从新手到高手的完整配置方案
  • CentOS 7.9物理机IPMI环境搭建保姆级教程(含OpenIPMI和ipmitool安装配置)
  • 操作系统-day05-p是地址变量,p是地址变量,p是地址变量
  • Arduino超声波避障机器人:从传感器原理到电机驱动的完整实践
  • 终极指南:三步掌握X-Spider高效下载推特媒体内容
  • 从超级碗广告看机器人未来:六大趋势揭示人机共融新范式
  • 从零构建自平衡机器人:Arduino、MPU6050与PID控制实战
  • Navicat重置工具:Mac版无限试用期重置的终极指南
  • 2026Excel转PDF免费教程:3种方法一看就会,微信小程序最快3秒完成
  • 通过WriteProcessMemory技术实现游戏帧率限制解除的技术方案
  • FinalBurn Neo终极指南:构建专业级街机游戏模拟器的完整教程
  • 人机协作:AI辅助软件开发
  • 轻松搭建鸟类追踪站!监测附近鸟类访客,还能实时展示
  • 2026年5月评价高的纸箱生产基地有哪些厂家推荐榜,重型包装与定制纸箱厂家选择指南 - 海棠依旧大
  • 为什么你的Gemini退款总在T+5卡住?资深SRE逆向追踪API响应链路与重试阈值设置
  • 基于MH-18M蓝牙音频模块的无线音频系统DIY:从原理到功放实战
  • 有哪些AI写作辅助软件是真的适配学科专业,而不是随意编造?
  • 鸣潮自动化革命:如何用智能工具解放你的游戏时间
  • IDM激活脚本终极指南:深度解析注册表锁定技术实现永久免费下载
  • 莲花控股跨界转型:对标味之素,能否打破跨界魔咒?
  • 高效部署方案:MobileNet-SSD目标检测实战指南
  • 终极指南:MobileNet-SSD目标检测模型部署与实战应用
  • 2026 宁波品牌首饰变现选哪家 不玩套路的回收门店有哪些 - 薛定谔的梨花猫
  • Jetpack Compose TextField长度限制的隐藏问题与健壮解决方案
  • 零代码点亮七段数码管:Arduino硬件驱动与电路原理实践
  • 123云盘免费解锁完整教程:5分钟获取VIP高速下载特权 [特殊字符]
  • 2026年4月优秀的防撞墙模板公司推荐,海岸软体排模具/地基梁模板/风电基础模板/流水槽模具,防撞墙模板生产厂家口碑分析 - 品牌推荐师
  • 推荐一家广州口碑不错的地基纠偏公司 - 品牌推广大师
  • 如何在老旧Mac上免费升级最新macOS系统:5个简单步骤让旧设备焕然一新