ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

AdaMem:让LLM智能体学会选择性记忆,实现个性化长程对话

AdaMem:让LLM智能体学会选择性记忆,实现个性化长程对话 1. 从“通用”到“专属”长程LLM智能体的记忆困境与AdaMem的破局最近在折腾一些长对话的LLM应用比如让AI扮演一个长期的私人助理或者构建一个能持续陪伴和学习的虚拟角色。一个核心的痛点很快就浮现出来记忆。不是简单的“记住上一条消息”而是在跨越数天、数周甚至数月的交互中智能体如何能像老朋友一样记住关于“我”的重要细节、习惯偏好甚至是那些琐碎但充满个人色彩的对话片段。通用的LLM比如ChatGPT每次对话都是相对独立的它没有持久的、个性化的记忆。而当我们试图为它外挂一个向量数据库作为记忆库时新的问题来了随着对话轮次horizon的拉长记忆条目爆炸式增长每次与LLM交互时到底该从海量记忆中召回哪些内容一股脑全塞给模型会严重超出上下文窗口并引入大量噪声随机选或者只选最新的又可能丢失关键的个人化信息。这正是“AdaMem: Learning What to Remember for Personalized Long-Horizon LLM Agents”这个研究标题所直指的核心问题。它不是一个简单的记忆检索工具而是一个学习型记忆管理器。它的目标不是“存储所有”而是学会“记住什么”。对于长期、个性化的LLM智能体而言AdaMem试图解决的是如何动态、自适应地从不断膨胀的个人历史中筛选出对当前对话最相关、最有价值的记忆片段。这听起来像是给智能体装上了一套“注意力”机制但它的对象不是输入的Token而是外部存储的、关于用户的海量记忆条目。想象一下一个陪伴了你三个月的健康管理助手。它记录了你每天的饮食、运动、睡眠和心情。今天你问它“我感觉最近有点疲惫该怎么办”一个笨拙的记忆系统可能会召回你昨天吃了什么、上周的运动记录等几十条信息。而AdaMem要做的是学会判断在当前“疲惫”的语境下你过去一个月睡眠质量的变化趋势、近期工作压力的相关记录远比上周二午餐的具体内容更重要。它通过学习建立了一种对记忆价值的评估能力从而实现精准、高效的记忆投喂让LLM智能体真正变得“善解人意”且“记性过人”。这不仅是技术优化更是实现高度个性化、长期可信赖的人机交互的关键一步。2. AdaMem的核心架构一个可学习的记忆检索与价值评估系统要理解AdaMem如何工作我们需要把它拆解开来。它本质上是一个插入在LLM智能体与原始记忆库比如一个向量数据库之间的智能中间层。这个中间层不是静态的规则过滤器而是一个可训练的模块其核心任务是根据当前的对话状态Context预测哪些历史记忆对生成下一步回复最有帮助。2.1 系统组成与数据流一个典型的基于AdaMem的个性化长程LLM智能体其数据流通常遵循以下路径原始记忆库存储所有历史交互的片段。每条记忆可能包含时间戳、对话内容、用户表达的情感或意图、提取出的实体如人名、项目名、偏好项等。这些记忆通常被编码成向量以便进行相似度检索。AdaMem 模块这是核心。它接收两个输入当前对话上下文即最新的用户查询加上最近几轮的对话历史一个短的上下文窗口。从原始记忆库中初步检索到的候选记忆集通常系统会先用一个基础的检索器如基于当前查询的向量相似度搜索从海量记忆中召回一个Top-K的候选集合例如50条。这一步是为了缩小范围。记忆价值评分与重排序AdaMem模块的核心是一个评分模型。它会对这K条候选记忆逐一进行评分这个分数代表了该条记忆对于当前对话上下文的价值。评分不是基于简单的语义相似度而是基于一个更复杂的目标“如果LLM智能体在生成回复时参考了这条记忆是否能显著提升回复的质量如个性化程度、准确性、有用性”选择性记忆注入根据评分AdaMem会选择分数最高的N条N远小于K例如3-5条记忆与当前对话上下文一起构成LLM的最终输入提示Prompt。LLM生成与反馈循环LLM基于增强了精选记忆的提示生成回复。整个交互的成败例如用户满意度、任务完成度会作为一个反馈信号用于持续训练和优化AdaMem的评分模型。这个架构的关键在于记忆的选择标准评分模型是通过学习得到的而非人工预设的。系统通过大量的交互数据逐渐学会在什么情况下什么样的记忆更有价值。2.2 可学习的评分模型价值函数的具体实现那么这个评分模型具体是什么在论文中它通常被实现为一个轻量级的神经网络例如一个多层感知机MLP。它的输入是当前对话上下文和单条记忆的联合表征输出一个标量分数。输入表征的构建对话上下文编码将当前的用户查询和短历史通过一个编码器可以是与LLM共享的也可以是一个独立的轻量编码器转换为一个固定维度的向量C。记忆编码每条候选记忆也通过编码器转换为向量M_i。联合特征评分模型的输入不仅仅是C和M_i的拼接往往还会加入一些手工设计的特征这些特征对于学习“价值”至关重要记忆年龄记忆产生的时间距离现在有多久一般来说新鲜的记忆可能更相关但某些长期偏好如食物过敏无论多久都极其重要。记忆类型这条记忆是关于“用户偏好”、“事实信息”、“情感状态”还是“待办任务”类型信息可以作为类别特征嵌入。历史访问频率这条记忆在过去被成功召回的次数多吗高频被访问的记忆可能具有基础重要性。与上下文的原始相似度作为基础检索依据的向量相似度分数也是一个重要的输入特征。模型训练与奖励信号 训练AdaMem评分模型是整个系统最精妙的部分因为它需要一个合适的“奖励”来定义什么是“好”的记忆。常见的训练方式包括强化学习RL将记忆选择视为一个序列决策问题。智能体AdaMem选择一组记忆LLM基于此生成回复然后从用户交互中获得奖励如任务成功、用户明确的正面反馈。通过策略梯度等方法AdaMem学习调整其评分策略以最大化长期奖励。监督学习SL这需要构建一个标注数据集。一种方法是利用专家演示给定一个对话上下文和一堆候选记忆让人工标注员选出最有助于生成高质量回复的几条记忆。然后用这些配对数据直接训练评分模型进行二分类相关/不相关或排序学习。离线偏好学习收集大量上下文 记忆集 LLM回复的三元组以及人类对回复质量的偏好评判如回复A比回复B更好。然后训练评分模型使得它选出的记忆所产生的回复更符合人类的偏好。注意在实际工程中纯粹使用RL训练可能样本效率低且不稳定。一个更实用的混合策略是先用少量监督数据或启发式规则如回复中若正确引用了用户偏好则给予正奖励进行预训练再通过在线交互进行微调。3. “学习记住什么”背后的关键技术挑战与设计抉择实现AdaMem并非易事其中涉及几个深层次的技术挑战每一个挑战的设计抉择都直接影响系统的最终效果。3.1 挑战一价值目标的模糊性与多维度性什么是一条“有价值”的记忆这个定义本身是多维且模糊的。相关性记忆内容与当前对话在语义上是否相关这是基础。特异性这条记忆是泛泛而谈的还是高度个性化的例如“用户喜欢咖啡”不如“用户每天上午9点必须喝一杯不加糖的燕麦拿铁”有价值。新鲜度与衰减有些信息会过时如“用户本周在忙项目A”有些则历久弥新如“用户对花生严重过敏”。系统需要学习不同类别信息的价值衰减曲线。信息增益这条记忆是否提供了当前对话上下文中缺失的关键信息避免选择那些从已有上下文中就能推断出来的冗余记忆。AdaMem的应对评分模型的设计必须能够融合这些维度。除了使用联合特征输入还可以在模型结构上做文章例如使用多任务学习让模型同时预测相关性分数、特异性分数等最后加权汇总。更重要的是训练数据的构建和奖励函数的设计必须体现这些多维目标。例如在构建监督数据时要求标注员不仅选出相关记忆还要标注其重要性等级在RL奖励中可以设计分项奖励如对正确使用个性化信息的回复给予额外奖励。3.2 挑战二训练数据的稀缺与冷启动问题这是一个经典的“鸡生蛋”问题要训练一个好的记忆选择器需要大量高质量的人机交互数据但在系统初期记忆选择器很差导致交互质量低难以收集高质量数据。工程实践中的解决方案规则引导的冷启动在系统上线初期不使用复杂的AdaMem而是采用一套基于规则的混合策略。例如基于关键词/实体的精确匹配如果当前查询中提到“我妈妈”则优先召回所有包含“妈妈”的记忆。基于时间的衰减加权将记忆的相似度分数与其新鲜度如指数衰减进行加权。类型优先级为“健康预警”、“个人禁忌”等类型的记忆设置较高的基础优先级。 这套规则系统可以作为初始的“记忆选择器”运行同时收集交互日志。合成数据与模拟环境在特定领域如任务型对话可以构建模拟用户和环境通过规则生成大量的模拟对话和记忆用于对AdaMem模型进行预训练。主动学习与在线学习系统运行后可以设计机制主动识别“不确定”的情况例如AdaMem对几条记忆的评分很接近将这类交互优先提交给人工审核快速获得高质量标注数据用于模型的迭代更新。3.3 挑战三计算效率与实时性要求长程对话要求响应迅速。如果每次用户发言AdaMem都需要对成千上万条记忆进行深度神经网络推理评分延迟将不可接受。性能优化策略两阶段检索架构如前所述这是标准做法。第一阶段用快速、轻量的检索器如基于FAISS的向量相似度搜索从全量记忆中召回一个较小的候选集如100-200条。第二阶段AdaMem只对这个候选集进行精细评分和重排序。第一阶段承担了“粗筛”大部分无关记忆的任务。模型轻量化AdaMem的评分模型必须足够轻量。通常采用浅层的MLP或小型Transformer并且可以使用知识蒸馏技术用一个大型教师模型在离线数据上训练来指导一个小型学生模型的学习在精度和速度间取得平衡。缓存与索引对于高频出现的对话模式或用户常见查询可以缓存AdaMem的评分结果。同时可以为记忆建立更丰富的索引如基于实体、情感、话题的索引使得第一阶段的粗筛更加精准进一步减少候选集大小。4. 构建你自己的AdaMem原型一个简化的实践指南理解了原理我们可以尝试构建一个极度简化的AdaMem原型来验证其核心思想。假设我们正在为一个“个人阅读助手”智能体构建记忆系统它能记住你读过的书、你的评论和偏好。4.1 环境与数据准备我们使用Python主要依赖transformers库用于文本编码sentence-transformers库用于向量化faiss库用于向量检索以及一个轻量级的机器学习库如scikit-learn或PyTorch来构建评分模型。首先模拟一些记忆数据。每条记忆是一个字典memories [ {id: 1, text: 用户读了《三体》评价说对黑暗森林法则的设定感到震撼但觉得人物塑造有些单薄。, type: book_review, entity: [三体], timestamp: 2023-10-01, embedding: None}, {id: 2, text: 用户表示不喜欢翻译腔过重的小说喜欢文字流畅自然的译本。, type: preference, entity: [], timestamp: 2023-10-05, embedding: None}, {id: 3, text: 用户最近对科幻小说和历史传记类书籍感兴趣。, type: interest, entity: [科幻, 历史传记], timestamp: 2023-10-10, embedding: None}, {id: 4, text: 用户读了《人类简史》认为作者视角宏大启发思考。, type: book_review, entity: [人类简史], timestamp: 2023-10-15, embedding: None}, # ... 更多记忆 ]使用sentence-transformers为所有记忆文本生成向量嵌入embedding并存入FAISS索引。4.2 实现基础检索器与AdaMem评分器基础检索器根据当前用户查询进行向量相似度搜索。from sentence_transformers import SentenceTransformer import faiss import numpy as np # 加载编码模型 encoder SentenceTransformer(all-MiniLM-L6-v2) # 轻量且效果不错的模型 # 为所有记忆生成嵌入向量并构建FAISS索引 memory_texts [m[text] for m in memories] memory_embeddings encoder.encode(memory_texts, convert_to_numpyTrue) dimension memory_embeddings.shape[1] index faiss.IndexFlatL2(dimension) index.add(memory_embeddings) def base_retriever(query, top_k10): query_embedding encoder.encode([query], convert_to_numpyTrue) distances, indices index.search(query_embedding, top_k) retrieved_memories [memories[i] for i in indices[0]] # 为每条记忆附上原始相似度分数转换为相似度距离越小相似度越高 for mem, dist in zip(retrieved_memories, distances[0]): mem[base_similarity_score] 1 / (1 dist) # 简单转换 return retrieved_memories简化版AdaMem评分器我们将实现一个基于逻辑回归的评分模型它学习结合多个特征来预测记忆价值。首先我们需要定义特征和制造一些训练数据。import torch import torch.nn as nn from sklearn.preprocessing import StandardScaler import datetime class SimpleAdaMemScorer(nn.Module): def __init__(self, input_dim): super().__init__() self.net nn.Sequential( nn.Linear(input_dim, 64), nn.ReLU(), nn.Linear(64, 32), nn.ReLU(), nn.Linear(32, 1), nn.Sigmoid() # 输出0-1之间的价值分数 ) def forward(self, x): return self.net(x) def extract_features(context, memory): 提取用于评分的联合特征 features [] # 1. 基础语义相似度 (已由基础检索器提供) features.append(memory.get(base_similarity_score, 0)) # 2. 记忆新鲜度 (距离现在的天数取负对数使得越新鲜值越大) mem_date datetime.datetime.strptime(memory[timestamp], %Y-%m-%d) days_old (datetime.datetime.now() - mem_date).days freshness -np.log1p(days_old) # 加1防止log(0) features.append(freshness) # 3. 记忆类型编码 (这里简单用one-hot实际可学习嵌入) type_map {book_review: [1,0,0], preference: [0,1,0], interest: [0,0,1]} features.extend(type_map.get(memory[type], [0,0,0])) # 4. 实体匹配度 (检查记忆中的实体是否出现在当前上下文中) context_lower context.lower() entity_match 0 for entity in memory.get(entity, []): if entity.lower() in context_lower: entity_match 1 break features.append(entity_match) return np.array(features, dtypenp.float32) # 假设我们有一些训练数据 (上下文 记忆 标签) # 标签1表示该记忆对生成回复很有价值0表示价值不大。 # 这里手动构造一些示例 train_data [ (context有什么科幻小说推荐吗, memory_id1, label1), # 《三体》的评论相关 (context有什么科幻小说推荐吗, memory_id2, label0), # 翻译偏好此时相关性较弱 (context有什么科幻小说推荐吗, memory_id3, label1), # 兴趣声明高度相关 (context我喜欢读起来流畅的书, memory_id2, label1), # 直接匹配偏好 (context我喜欢读起来流畅的书, memory_id1, label0), # 书评此时不直接相关 ]4.3 训练与集成接下来我们用这些训练数据来训练我们简化的AdaMem评分器。# 准备训练数据 X_train [] y_train [] for context, mem_id, label in train_data: memory next(m for m in memories if m[id] mem_id) # 注意这里需要为memory计算base_similarity_score我们简化处理假设在基础检索阶段已计算 # 为了示例我们这里模拟一个基础分数 # 在实际中这个分数应该在调用base_retriever时获得 memory[base_similarity_score] 0.5 # 模拟值 features extract_features(context, memory) X_train.append(features) y_train.append(label) X_train np.stack(X_train) y_train np.array(y_train) # 特征标准化 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) # 转换为PyTorch张量 X_tensor torch.FloatTensor(X_train_scaled) y_tensor torch.FloatTensor(y_train).unsqueeze(1) # 初始化模型、损失函数和优化器 model SimpleAdaMemScorer(input_dimX_train.shape[1]) criterion nn.BCELoss() optimizer torch.optim.Adam(model.parameters(), lr0.01) # 简单训练循环 model.train() for epoch in range(100): optimizer.zero_grad() outputs model(X_tensor) loss criterion(outputs, y_tensor) loss.backward() optimizer.step() if epoch % 20 0: print(fEpoch {epoch}, Loss: {loss.item():.4f})现在我们可以将AdaMem集成到检索流程中def adamem_retrieve(query, top_k_base10, top_k_final3): # 1. 基础检索 candidate_mems base_retriever(query, top_ktop_k_base) # 2. 为每条候选记忆提取特征并评分 scored_mems [] for mem in candidate_mems: # 确保有基础相似度分数 if base_similarity_score not in mem: # 临时计算实际应与基础检索步骤合并 query_embedding encoder.encode([query], convert_to_numpyTrue) mem_embedding encoder.encode([mem[text]], convert_to_numpyTrue) dist np.linalg.norm(query_embedding - mem_embedding) mem[base_similarity_score] 1 / (1 dist) features extract_features(query, mem) # 注意这里用query作为简化上下文 features_scaled scaler.transform(features.reshape(1, -1)) with torch.no_grad(): score model(torch.FloatTensor(features_scaled)).item() mem[adamem_score] score scored_mems.append(mem) # 3. 按AdaMem分数重排序并选择Top N scored_mems.sort(keylambda x: x[adamem_score], reverseTrue) final_memories scored_mems[:top_k_final] return final_memories # 测试 query_test 我想找一本像《三体》那样设定宏大的书但人物塑造要好一些。 selected adamem_retrieve(query_test) print(AdaMem精选的记忆) for mem in selected: print(f- ID:{mem[id]}, Score:{mem[adamem_score]:.3f}, Text:{mem[text][:50]}...)在这个例子中对于这个查询AdaMem评分器应该会给记忆1《三体》评论提到了“人物塑造单薄”和记忆2翻译偏好可能与“人物塑造”的阅读体验间接相关较高的分数而不仅仅是依赖基础语义相似度。记忆3兴趣也可能获得不错分数。通过结合新鲜度、类型、实体匹配等特征模型学会了进行更智能的选择。实操心得这个原型极度简化真实系统中的特征工程要复杂得多例如需要考虑记忆之间的关联性、用户反馈的隐式信号如用户在采纳建议后的后续行为。训练数据的获取是最大的瓶颈。一个可行的启动策略是先利用规则系统运行记录下每次召回的记忆和最终的人工审核结果或用户满意度反馈逐步积累数据来迭代这个评分模型。5. 超越基础检索AdaMem带来的范式转变与未来方向AdaMem所代表的“学习型记忆管理”思路不仅仅是对检索环节的优化它实际上在推动LLM智能体架构范式的转变。从“存储-检索”到“记忆-推理”协同传统的外挂记忆是静态的数据库LLM是查询者。AdaMem引入了一个动态的、可学习的“记忆工作台”。这个工作台会根据当前任务的思维状态由对话上下文体现主动准备好最相关的“工具”记忆片段供LLM在推理时使用。记忆成为了推理过程的一个主动参与者。实现长期一致的个性化人格对于角色扮演、虚拟伴侣等应用维持长期、一致的性格和关系记忆至关重要。AdaMem可以学习优先召回那些定义角色核心特质如“性格乐观”、“讨厌谎言”的记忆以及在当前对话中能强化角色关系如“上次用户分享秘密时表示了信任”的记忆从而让智能体的表现更加连贯和可信。降低幻觉与提高事实性通过精准召回相关的个人事实记忆如“用户的母亲叫Lisa”可以约束LLM的生成减少在个性化信息上“胡编乱造”的情况。AdaMem学会了哪些记忆是“硬事实”需要在相关场景下被强制唤起。未来的演进方向分层与抽象记忆当前的记忆单元多是原始的对话片段。未来系统可能会自动对记忆进行分层和抽象形成“记忆纲要”、“用户画像向量”、“长期目标”等高阶表征。AdaMem则需要学习在不同抽象层次上选择和组合记忆。多模态记忆记忆不仅是文本还包括图像、音频甚至传感器数据。AdaMem需要发展出处理和理解多模态记忆关联性的能力。用户可控与可解释性记忆是高度隐私和敏感的。未来的系统需要让用户对“什么被记住”、“什么被使用”有感知和控制权。AdaMem的评分机制需要具备一定的可解释性让用户理解为什么某条记忆被选中。跨智能体的记忆共享与迁移在用户授权下一个智能体学习到的关于用户的记忆模式能否安全地迁移到另一个为不同任务服务的智能体上这涉及到记忆价值的泛化学习。在我自己的项目实践中引入类似AdaMem的思考后最深刻的体会是记忆管理的核心不是容量而是“相关性”的判断力。早期我们总想着存下一切结果导致检索效率低下和提示词噪声巨大。后来我们开始为记忆打上结构化标签类型、实体、情感极性并设计简单的启发式规则进行过滤效果立竿见影。而AdaMem将这一步推向了自动化与最优化。它提醒我们构建有“长期记忆”的AI不仅仅是增加一个数据库更是要为它配备一个不断进化的“记忆中枢神经系统”这个系统懂得取舍懂得在正确的时间唤醒正确的往事。这或许是实现真正个性化、人性化AI交互的必经之路。
返回列表