当前位置: 首页 > 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.jsqmd.com/news/924513/

相关文章:

  • 从‘more than one device‘到‘appActivity‘报错:一次完整的Android自动化测试踩坑实录
  • 基于Arduino Leonardo的街机外设DIY:从HID原理到实战开发
  • while循环结构以及具体用法
  • GPT还是MBR?给SATA/NVMe固态硬盘分区选错,重装系统白忙活
  • 基于Arduino Leonardo的头部控制游戏控制器设计与实现
  • 用Reflex全栈Python框架快速构建AI文生图Web应用
  • 洛雪音乐音源全攻略:从新手到高手的完整配置方案
  • CentOS 7.9物理机IPMI环境搭建保姆级教程(含OpenIPMI和ipmitool安装配置)
  • 操作系统-day05-p是地址变量,p是地址变量,p是地址变量
  • 避坑指南:用Python做DEA效率分析时,为什么你的SBM模型结果总不对?
  • Arduino超声波避障机器人:从传感器原理到电机驱动的完整实践
  • 终极指南:三步掌握X-Spider高效下载推特媒体内容
  • Arduino动态记忆游戏:伺服电机驱动的Simon Says升级版
  • 基于Arduino的智能宠物模拟装置:温度触发与振动反馈的硬件实现
  • 【零基础部署】Docker 部署 CrewAI 多 Agent 编排框架保姆级教程
  • 手把手教你用Python处理Weibo_Datasets:从原始TXT到结构化CSV的完整流程
  • 媒体舆情响应延迟超83分钟?Gemini关系管理紧急升级清单,含3个即刻生效的API级补丁
  • OpCore-Simplify架构设计:从硬件适配自动化到智能配置生成的技术演进
  • 2026年广州旧房翻新深度调研:覆盖8区520户业主回访,8家权威评测 - 优家闲谈
  • 从零搭建Arduino绘图机:机电一体化入门实践
  • 从零构建自平衡机器人:Arduino、MPU6050与PID控制实战
  • 2026年广州二手房装修市场洞察:8强品牌格局与选企策略 - 优家闲谈
  • 从超级碗广告看机器人未来:六大趋势揭示人机共融新范式
  • 技术领导力:从开发者到技术管理者
  • Windows环境下Python多版本管理架构解析:pyenv-win深度指南
  • Navicat重置工具:Mac版无限试用期重置的终极指南
  • 微信聊天记录终极保存方案:三步永久备份你的数字记忆
  • 2026破圈!5款AI论文网站实测,告别拖延症,初稿3天搞定!
  • 通过WriteProcessMemory技术实现游戏帧率限制解除的技术方案
  • 2026Excel转PDF免费教程:3种方法一看就会,微信小程序最快3秒完成