如何为你的AI助手打造“长期记忆“系统?小白/程序员必备收藏,从架构到代码实现深度解析
本文深入探讨了为AI Agent构建持久化记忆系统的必要性,分析了LLM上下文窗口有限等局限性。文章详细介绍了分层架构设计,涵盖记忆条目分类、相关性评分算法、存储抽象(支持内存和SQLite)、环形缓冲区实现短期记忆、向量嵌入进行语义搜索以及多因子相关性排序。通过实战示例展示了基本使用方法和自定义配置,最后展望了向量数据库集成、记忆压缩等未来方向,为开发者实现智能AI助手提供了一套完整的参考方案。
为什么 AI Agent 需要记忆系统?
LLM 的局限性
大语言模型虽然强大,但存在一个根本性的限制:上下文窗口有限。即使最新的模型支持百万级 tokens,也无法记住所有历史对话。更重要的是:
- • 成本问题:每次都传递完整历史,API 调用费用会快速累积
- • 注意力稀释:上下文过长会导致模型"注意力分散",回复质量下降
- • 无法持久化:新会话无法访问旧会话的信息
记忆系统的价值
一个设计良好的记忆系统可以:
- • ✅ 跨会话记忆:记住用户的偏好、历史交互
- • ✅ 智能检索:只召回与当前对话相关的内容
- • ✅ 知识沉淀:将交互中提取的知识长期保存
- • ✅ 成本优化:通过检索替代完整上下文传递
系统架构概览
agent-io 的记忆系统采用分层架构设计:

核心模块职责
| 模块 | 职责 | 文件 |
|---|---|---|
MemoryManager |
统一入口,协调各组件 | manager.rs |
MemoryEntry |
记忆条目数据结构 | entry.rs |
MemoryStore |
存储抽象 trait | store.rs |
RingBuffer |
短期记忆的环形缓冲区 | buffer.rs |
EmbeddingProvider |
文本向量化接口 | embeddings.rs |
MemoryRanker |
记忆相关性排序 | ranker.rs |
核心组件详解
记忆条目(MemoryEntry)
每条记忆都是一个结构化的条目:
pub struct MemoryEntry { pub id: String, // 唯一标识 pub content: String, // 记忆内容 pub embedding: Option<Vec<f32>>, // 向量表示(用于相似度搜索) pub memory_type: MemoryType, // 记忆类型 pub metadata: HashMap<String, Value>, // 元数据 pub created_at: DateTime<Utc>, // 创建时间 pub last_accessed: Option<DateTime<Utc>>, // 最后访问时间 pub importance: f32, // 重要性评分 (0.0 - 1.0) pub access_count: u32, // 访问次数}
记忆类型分类
pub enum MemoryType { ShortTerm, // 短期记忆:最近的对话 LongTerm, // 长期记忆:持久化知识 Episodic, // 情景记忆:特定事件/经历 Semantic, // 语义记忆:事实和概念}
这种分类借鉴了认知心理学中的记忆模型:
- • 短期记忆:容量有限,快速存取,类似工作记忆
- • 长期记忆:容量无限,需要检索才能访问
- • 情景记忆:个人经历,如"昨天我去了咖啡店"
- • 语义记忆:通用知识,如"巴黎是法国首都"
相关性评分算法
系统会根据多个因素动态计算记忆的相关性:
pub fn relevance_score(&self) -> f32 { let age_hours = (Utc::now() - self.created_at).num_hours() as f32; let recency_factor = (-age_hours / 24.0 / 7.0).exp(); // 一周内指数衰减 let access_factor = 1.0 + (self.access_count as f32).ln().max(0.0) * 0.1; self.importance * recency_factor * access_factor}
评分公式:score = 重要性 × 时间衰减因子 × 访问频率因子
存储抽象(MemoryStore)
采用 Trait 抽象存储层,支持多种后端实现:
#[async_trait]pub trait MemoryStore: Send + Sync { async fn add(&self, entry: MemoryEntry) -> Result<String>; async fn search(&self, query: &str, limit: usize) -> Result<Vec<MemoryEntry>>; async fn search_by_embedding(&self, embedding: &[f32], limit: usize, threshold: f32) -> Result<Vec<MemoryEntry>>; async fn get(&self, id: &str) -> Result<Option<MemoryEntry>>; async fn update(&self, entry: MemoryEntry) -> Result<()>; async fn delete(&self, id: &str) -> Result<()>; async fn clear(&self) -> Result<()>; async fn count(&self) -> Result<usize>;}
内存存储实现
适合开发测试,所有数据保存在内存中:
pub struct InMemoryStore { memories: RwLock<HashMap<String, MemoryEntry>>,}
支持向量相似度搜索(余弦相似度):
fn cosine_similarity(a: &[f32], b: &[f32]) -> f32 { let dot: f32 = a.iter().zip(b.iter()).map(|(x, y)| x * y).sum(); let norm_a: f32 = a.iter().map(|x| x * x).sum::<f32>().sqrt(); let norm_b: f32 = b.iter().map(|x| x * x).sum::<f32>().sqrt(); dot / (norm_a * norm_b)}
SQLite 存储实现
适合生产环境,支持持久化和全文搜索:
pub struct SqliteStore { conn: Arc<Mutex<Connection>>,}
数据库设计亮点:
-
- FTS5 全文搜索:利用 SQLite 的 FTS5 扩展实现高效文本搜索
-
- 向量存储:将向量序列化为 BLOB 存储
-
- 自动触发器:插入/更新/删除时自动同步 FTS 索引
CREATE VIRTUAL TABLE memories_fts USING fts5( id UNINDEXED, content, content='memories', content_rowid='rowid');-- 自动同步触发器CREATE TRIGGER memories_ai AFTER INSERT ON memories BEGIN INSERT INTO memories_fts(rowid, id, content) VALUES (new.rowid, new.id, new.content);END;
短期记忆缓冲区(RingBuffer)
短期记忆采用环形缓冲区实现,固定容量,自动淘汰最旧的数据:
pub struct RingBuffer<T> { buffer: VecDeque<T>, capacity: usize,}impl<T> RingBuffer<T> { pub fn push(&mut self, item: T) { if self.buffer.len() == self.capacity { self.buffer.pop_front(); // 淘汰最旧的 } self.buffer.push_back(item); }}
设计优势:
- • O(1) 时间复杂度的插入和删除
- • 内存占用可控
- • 保留最近 N 条对话上下文
向量嵌入(Embeddings)
记忆系统依赖向量嵌入实现语义搜索:
#[async_trait]pub trait EmbeddingProvider: Send + Sync { async fn embed(&self, text: &str) -> Result<Vec<f32>>; async fn embed_batch(&self, texts: &[&str]) -> Result<Vec<Vec<f32>>>; fn dimension(&self) -> usize;}
内置实现:
| Provider | 模型 | 维度 |
|---|---|---|
OpenAIEmbedding |
text-embedding-3-small | 1536 |
OpenAIEmbedding |
text-embedding-3-large | 3072 |
MockEmbedding |
测试用 Mock | 可配置 |
记忆排序器(Ranker)
当检索到多条相关记忆时,需要按相关性排序:
pub struct RankingWeights { pub similarity: f32, // 向量相似度权重 (0.4) pub importance: f32, // 重要性权重 (0.25) pub recency: f32, // 时效性权重 (0.2) pub frequency: f32, // 访问频率权重 (0.15)}
综合评分公式:
score = 0.4 × similarity + 0.25 × importance + 0.2 × recency + 0.15 × frequency
时间衰减机制
记忆的重要性会随时间衰减:
pub struct DecayConfig { pub daily_rate: f32, // 每日衰减率 (默认 1%) pub min_threshold: f32, // 最小阈值 (低于此值的记忆可清理) pub grace_period_days: u32, // 宽限期 (新记忆不衰减)}
衰减公式:importance × (1 - daily_rate)^days
核心工作流程
记忆存储流程(Remember)
pub async fn remember(&mut self, content: &str, memory_type: MemoryType) -> Result<String> { // 1. 生成向量嵌入 let embedding = self.embedder.embed(content).await?; // 2. 创建记忆条目 let entry = MemoryEntry::new(content) .with_type(memory_type) .with_embedding(embedding); // 3. 根据类型选择存储位置 match memory_type { MemoryType::ShortTerm => { self.short_term.push(entry.clone()); Ok(entry.id) } _ => { if self.config.enable_long_term { self.store.add(entry).await // 持久化存储 } else { self.short_term.push(entry.clone()); Ok(entry.id) } } }}
流程图:

记忆检索流程(Recall)
pub async fn recall(&self, query: &str) -> Result<Vec<MemoryEntry>> { // 1. 查询向量化 let query_embedding = self.embedder.embed(query).await?; // 2. 从长期记忆检索 let mut memories = self.store .search_by_embedding(&query_embedding, limit, threshold) .await?; // 3. 从短期记忆检索 for entry in self.short_term.iter_recent() { if let Some(ref embedding) = entry.embedding { let similarity = cosine_similarity(&query_embedding, embedding); if similarity >= threshold { memories.push(entry.clone()); } } } // 4. 按相关性排序 memories.sort_by(|a, b| b.relevance_score().partial_cmp(&a.relevance_score()).unwrap()); // 5. 限制返回数量 memories.truncate(self.config.retrieval_limit); Ok(memories)}
流程图:

实战示例
基本使用
use agent_io::memory::{ MemoryManager, MemoryConfig, MemoryType, InMemoryStore, MockEmbedding};#[tokio::main]async fn main() -> Result<()> { // 1. 创建存储和向量化服务 let store = Arc::new(InMemoryStore::new()); let embedder = Arc::new(MockEmbedding::new(384)); // 2. 创建记忆管理器 let config = MemoryConfig { short_term_size: 20, enable_long_term: true, retrieval_limit: 5, relevance_threshold: 0.7, ..Default::default() }; let mut manager = MemoryManager::new(config, store, embedder); // 3. 存储记忆 manager.remember("用户喜欢 Rust 编程语言", MemoryType::LongTerm).await?; manager.remember("用户是软件工程师", MemoryType::Semantic).await?; manager.remember("上次讨论了异步编程", MemoryType::Episodic).await?; // 4. 检索相关记忆 let memories = manager.recall("编程").await?; for memory in memories { println!("相关记忆: {}", memory.content); } // 5. 构建上下文 let context = manager.recall_context("用户的技术背景").await?; println!("上下文: {}", context); Ok(())}
使用 SQLite 持久化
use agent_io::memory::SqliteStore;// 创建文件数据库let store = Arc::new(SqliteStore::open("./data/memories.db")?);// 或使用内存数据库(测试用)let store = Arc::new(SqliteStore::new()?);
自定义排序权重
use agent_io::memory::{MemoryRanker, RankingWeights};let weights = RankingWeights { similarity: 0.5, // 更重视语义相似 importance: 0.3, recency: 0.1, frequency: 0.1,};let ranker = MemoryRanker::with_weights(weights) .with_recency_half_life(24.0 * 3.0); // 3天半衰期
设计亮点总结
架构设计
| 特性 | 实现方式 |
|---|---|
| 存储抽象 | Trait + 多后端实现 |
| 短期/长期分离 | RingBuffer + Store 双层架构 |
| 语义搜索 | Embedding 向量化 + 余弦相似度 |
| 混合检索 | FTS 全文 + 向量相似度 |
| 相关性排序 | 多因子加权评分 |
性能优化
- • 异步设计:所有 I/O 操作都是 async,支持高并发
- • 批量嵌入:
embed_batch支持批量向量化,减少 API 调用 - • 连接池:SQLite 使用
Arc<Mutex<Connection>>安全共享 - • 索引优化:SQLite 创建了 memory_type、importance、created_at 索引
可扩展性
// 自定义存储后端impl MemoryStore for MyCustomStore { ... }// 自定义嵌入服务impl EmbeddingProvider for MyEmbeddingService { ... }
未来展望
当前的实现已经相当完善,但仍有一些可以改进的方向:
-
- 向量数据库集成:对于大规模记忆,可集成 Qdrant、Milvus 等专业向量数据库
-
- 记忆压缩:使用 LLM 总结压缩旧记忆,减少存储空间
-
- 遗忘机制:基于 DecayConfig 实现自动清理低重要性记忆
-
- 多模态记忆:支持图片、音频等多模态记忆存储
-
- 记忆推理:基于记忆进行推理,生成新的知识
结语
这套记忆系统设计体现了认知科学原理与工程实践的结合。通过分层架构、存储抽象、多因子排序等设计,实现了既灵活又高效的 AI 记忆能力。
希望这些设计思路能为你的 AI Agent 开发提供参考。
完整代码请访问GitHub 仓库:
https://github.com/lispking/agent-io
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线科技企业深耕十二载,见证过太多因技术卡位而跃迁的案例。那些率先拥抱 AI 的同事,早已在效率与薪资上形成代际优势,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在大模型的学习中的很多困惑。我们整理出这套 AI 大模型突围资料包:
- ✅ 从零到一的 AI 学习路径图
- ✅ 大模型调优实战手册(附医疗/金融等大厂真实案例)
- ✅ 百度/阿里专家闭门录播课
- ✅ 大模型当下最新行业报告
- ✅ 真实大厂面试真题
- ✅ 2026 最新岗位需求图谱
所有资料 ⚡️ ,朋友们如果有需要 《AI大模型入门+进阶学习资源包》,下方扫码获取~
① 全套AI大模型应用开发视频教程
(包含提示工程、RAG、LangChain、Agent、模型微调与部署、DeepSeek等技术点)
② 大模型系统化学习路线
作为学习AI大模型技术的新手,方向至关重要。 正确的学习路线可以为你节省时间,少走弯路;方向不对,努力白费。这里我给大家准备了一份最科学最系统的学习成长路线图和学习规划,带你从零基础入门到精通!
③ 大模型学习书籍&文档
学习AI大模型离不开书籍文档,我精选了一系列大模型技术的书籍和学习文档(电子版),它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础。
④ AI大模型最新行业报告
2025最新行业报告,针对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。
⑤ 大模型项目实战&配套源码
学以致用,在项目实战中检验和巩固你所学到的知识,同时为你找工作就业和职业发展打下坚实的基础。
⑥ 大模型大厂面试真题
面试不仅是技术的较量,更需要充分的准备。在你已经掌握了大模型技术之后,就需要开始准备面试,我精心整理了一份大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。

以上资料如何领取?

为什么大家都在学大模型?
最近科技巨头英特尔宣布裁员2万人,传统岗位不断缩减,但AI相关技术岗疯狂扩招,有3-5年经验,大厂薪资就能给到50K*20薪!

不出1年,“有AI项目经验”将成为投递简历的门槛。
风口之下,与其像“温水煮青蛙”一样坐等被行业淘汰,不如先人一步,掌握AI大模型原理+应用技术+项目实操经验,“顺风”翻盘!

这些资料真的有用吗?
这份资料由我和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理,现任上海殷泊信息科技CEO,其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证,服务航天科工、国家电网等1000+企业,以第一作者在IEEE Transactions发表论文50+篇,获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。
资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的技术人员,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。

以上全套大模型资料如何领取?

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)