最近在整理多智能体系统相关的论文章节,翻到这篇关于INMS的笔记就停下来了。从标题看,INMS 大概率是某种“跨 Agent 记忆共享机制”的缩写,副标题“Memory Sharing for Large Language Model based Agents”已经把话说得很明白——让各自带着大模型跑任务的 Agent 能互相借用对方已经整理好的记忆,而不是每个智能体都从零开始跟用户重新认识一遍。这个方向我盯了很久,因为凡是做过 Agent 落地的人都会撞上同一个尴尬:单机单 Agent 的记忆再强,换个会话就断片;多 Agent 协作时,A 辛苦积累的上下文,B 完全用不上。这篇笔记记录的是我对这套机制从设计思路到评估指标的拆解,中间有我根据领域背景做的推演,也有动手模拟时的实测记录,希望给正在搭记忆系统的朋友一点参考。
1. 大模型智能体为什么需要记忆共享
1.1 先捋清楚 Agent 记忆到底分几类
在读这篇笔记之前,我觉得有必要先把记忆的分类这件事说清楚,因为后面所有关于共享的讨论都建立在分类之上。通常业界会把大模型智能体的记忆切成四块:情景记忆(Episodic Memory),记的是“哪次对话里用户说过什么”;语义记忆(Semantic Memory),记的是“用户偏好什么、某个业务规则是什么”;程序记忆(Procedural Memory),记的是“遇到某种情况应该调用哪个工具、走哪条流程”;还有工作记忆(Working Memory),就是当前上下文窗口里临时放着的那一小段信息。
INMS 这套方案管的显然不是工作记忆。工作记忆跟着当前会话走,本来就不需要跨 Agent 共享。真正需要拿出来共享的是前两类——情景记忆和语义记忆。原因很简单:这两类记忆一旦沉淀下来,就具备了复用价值。某个 Agent 在上一轮会话里摸清了用户的行业背景、沟通习惯、常见需求倾向,这些东西放到另一个 Agent 面前同样是有效信息。如果每个 Agent 都自己攒一套,等于一群人在同一个房间里各写各的通讯录,效率低到离谱。
1.2 单 Agent 记忆的三种“天花板”
只靠单个 Agent 自己的记忆系统,不管怎么优化,都会撞上三个绕不开的问题。
第一个是记忆退化。大模型 Agent 的记忆通常走“先压缩、后存储、再检索”的路线,上一轮对话内容要先经过提取和改写才能落库。提取阶段一旦丢信息,后面用的时候就会失真。我自己做过实验,让同一个 Agent 连续三小时处理客服类对话,到后面它记住的用户偏好越来越模糊,甚至会把两个用户的诉求混在一起。这种退化在单 Agent 体系里很难根治,因为它缺少“外部校正”的机制。
第二个是经验孤岛。这是我最在意的点。假设你有一套系统,里面有三个 Agent 分别负责售前咨询、售后支持和工单流转。售前 Agent 发现用户特别在意开发文档的完整性,这个洞察如果存在它自己的记忆库里,售后 Agent 在接待同一个用户时完全感知不到,于是又从头问一遍“您这边对文档有什么要求吗”。用户在那一刻的体验就是两个字:智障。经验孤岛造成的不是单次对话质量下降,而是整套系统的智能水平被锁死在“每个 Agent 各自的上限”上。
第三个是上下文窗口挤压。现在的做法为了不丢关键信息,通常会往提示词里塞尽量多的历史记忆片段,但窗口就这么大,塞进去十条记忆就意味着少放两条工具调用说明。结果 Agent 开始犯低级错误——调错参数、漏掉步骤。上下文窗口不是仓库,它是工作台,工作台上只能放当前正在用的东西。真正该做的是把决策需要用到的背景信息提前准备好、放到一个随时能取的地方,而不是临时往工作台上堆。
1.3 共享记忆解决的是“组织协作”层面的问题
把所有 Agent 的记忆打通之后,你会发现问题的性质变了。原来单 Agent 遇到新用户是失忆状态,现在它可以先到共享记忆库里查一下——“这个用户之前有没有别的 Agent 接触过?”有的话直接继承对方积累的画像,开场白都能省掉一半寒暄。这不仅提升了对话质量,更让整个 Agent 集群呈现出一种“团队感”——虽然每个 Agent 干的是不同的活,但它们对同一个用户的认知是一致的,不会出现“前面说你不需要发票,后面又问你要不要发票”这种自相矛盾。
说句实话,记忆共享这个概念单拎出来并不新鲜,数据库本来就能共享。关键难点在于:记忆不是结构化数据,它是大模型在对话中逐步形成的非结构化积累,怎么让一大批 Agent 在这个非结构化的积累上达成共识,才是 INMS 真正要解决的问题。
2. INMS 的核心架构:记忆从“私有属性”变成“网络资源”
2.1 把记忆抽出来,单独做一个服务层
从笔记里梳理出来的整体思路,可以概括成一句话:在 Agent 和它的记忆之间加一个独立的“记忆服务层”。以前 Agent 自己管记忆,想存就存、想读就读,现在所有 Agent 都通过统一的接口跟记忆服务层打交道。这层服务负责接收 Agent 提交的记忆写入请求,也负责响应 Agent 的检索请求。换句话说,记忆不再属于某一个 Agent,而是变成了一张可以按需取用的“网络资源”。
这个设计的第一反应可能会让你觉得多此一举——多一个服务层就多一份延迟,干嘛不让 Agent 直接读写共享库?我的理解是,多出来这个层不是为了存数据,而是为了管规则。如果没有中间层,Agent A 直接把一段记忆写到共享库里,Agent B 拿过来就用,大概率会出问题:A 记的内容可能是错的、可能带权限限制、可能格式跟 B 预期不一致。中间层的价值就是充当一个“审核+翻译+分发”的枢纽,把写入的数据标准化,把读出的数据按 Agent 的需求重新组织。这个思路跟微服务架构里把数据库访问统一收敛到一个数据服务层是一个道理。
2.2 记忆单元长什么样:结构化才是共享的前提
共享的前提是可解析。如果每个 Agent 都用自己的语言风格存记忆,共享库很快就会变成一锅粥。INMS 给我的启示是:记忆必须拆成结构化单元,而且结构要在整个系统层面统一设计。
我按笔记里描述的设计意图,结合自己搭类似系统的经验,整理了一套可行的记忆单元结构:
| 字段 | 作用 | 示例 |
|---|---|---|
| 记忆ID | 全局唯一标识,方便后续更新和删除 | mem_7f3a9c21 |
| 内容主体 | 记忆的具体描述,建议让大模型生成一句完整的话 | “用户偏好周报用中文提交,附PDF附件” |
| 实体标签 | 标注记忆关联的对象,便于精确检索 | 用户ID、项目ID、会话ID |
| 来源 | 记录这条记忆是由哪个Agent在什么场景下写入的 | agent_sales_01 / session_20250312 |
| 时间戳 | 写入时间和最近更新时间 | written: 2025-03-12, updated: 2025-03-13 |
| 时效属性 | 标记这条记忆的有效期限或是否需要定期重新验证 | expire: 2025-06-12 |
| 权限字段 | 控制哪些Agent能读这条记忆 | roles: [sales, support] |
| 可信度 | 这条记忆被验证过的次数或置信评分 | trust: 0.85 |
这八个字段缺一不可。内容主体解决“记住什么”,实体标签解决“怎么找”,来源和时间戳解决“这条记忆是不是过时的”,权限字段解决“谁能看”。后面我在讲检索的时候你会更清楚体会到,没有时间戳和来源的记忆有多么可怕——你根本不知道一条说“客户预算在十万元以内”的记忆是上个月写的还是去年写的,这就是事故源头。
2.3 为什么是“集中式存储+分布式读写”
架构上有一个很有意思的取舍:存储是集中式的,读写入口是分布式的。所有 Agent 通过自己本地的接口模块访问同一个逻辑上的记忆库,但物理上记忆库可以做分片和冗余,不同分片负责不同领域、不同用户的记忆。
我理解是为了同时拿到两头的优势。集中式存储方便统一做去重、一致性和权限校验,这是分布式存储各管各的很难做到的;而读写入口做分布式,是为了不让记忆服务成为整个系统的单点瓶颈。这套思路在工程上并不复杂,本质上是把“写路径”和“读路径”分开优化:写入走队列异步处理,读到热点记忆走缓存,冷门记忆才查主库。实验环境下可能体感不明显,但放到生产上,这个分离设计能救你命。
读完架构部分我的感受是:INMS 没有发明什么玄学的技术,它做对的事情是把数据库设计里的基本素养——schema 设计、权限控制、读写分离——平移到了大模型 Agent 的记忆场景里。这恰恰是很多项目缺的一环,大家忙着调提示词、调模型,却忘了底下那层记忆存储本身需要认真设计。
3. 记忆写入、检索与更新的核心机制拆解
3.1 写什么、什么时候写,比怎么写更重要
记忆系统的第一个关键路口是写入策略。很多失败的 Agent 记忆设计毛病出在一个地方:什么都记。对话里用户随口说了一句“今天天气不错”,系统也提取成记忆存进去,结果库里面全是这种毫无价值的噪声,真正有用的记忆被淹没在垃圾信息里。
从笔记里的设计思路推演,INMS 对写入应该是有严格触发条件的。我按常见方案的逻辑归纳了一下,一条信息要进入共享记忆库,至少要满足下面几个条件之一:它包含可用于后续交互的用户偏好(比如“答复问题前先给结论”);它包含正在进行的任务的关键状态变化(比如“工单升级到 P2 处理中”);它纠正了之前某条记忆的错误内容(比如“用户之前说周五之前提交,现已改到周日”);它涉及多个 Agent 协同需要的背景信息(比如“该用户所在团队的技术栈是 Python 系,不是 Java 系”)。
满足条件的原始对话内容,还需要经过一道“改写”工序。我建议的做法是把原始片段交给大模型,让它按固定模板输出结构化记忆,同时带上前面表格里的元数据字段。这一步做得好不好,直接决定了后面检索的质量。我测试过,同样一段对话,让大模型自由发挥提取记忆,和让它按“主体-实体-时效-来源”模板提取,后者的检索命中率能高出 20 个百分点左右。
3.2 检索:把“对的记忆”在“对的时间”捞出来
检索引擎是整个 INMS 里最让我感兴趣的部分,因为它在技术上承担的任务最重:Agent 发出一个模糊的查询,系统要返回一条精确相关的记忆。这里的平衡点极其微妙。
当前主流的检索策略是混合检索 + 重排序。先跑向量检索,把用户当前问题编码成向量,在记忆库里做语义相似度匹配,召回 top 20 的候选记忆。再跑一层基于时间衰减和实体匹配的排序——语义相似度高的不一定是要用的,比如用户现在问的是“修改合同条款”,系统检索到“用户偏好合同用英文写”,语义上是有点相关,但并不是当下这条操作需要的背景知识,这时就靠实体匹配把候选列表里面含“合同”实体且时效性高的记录往前顶。最后再把 top 5 的记忆作为上下文注入当前 Agent 的提示词。
这中间有个参数值得细调:相似度阈值。阈值设太高,检索结果稀疏,Agent 在这个场景里拿不到任何历史参考;阈值设太低,乱七八糟的噪声记忆全进来,Agent 开始编造前后矛盾的内容。在实际测试里我建议先定在 0.75 附近跑一轮,观察 Agent 决策是否出现明显波动,再上下调。没有统一标准,因为每个项目的记忆库质量差别太大。
3.3 更新与遗忘:共享记忆最怕“永垂不朽”
智能体的记忆跟人的记忆一样,该忘的得忘。INMS 这套系统里,更新和遗忘机制是保证记忆库长期可用性的核心。
先说更新。两条新旧记忆指向同一个实体、且内容冲突时,系统需要有能力判定哪条更可信。我用过的方案里,比较实用的是“人工标注 + 来源权重”双轨制:直接用户确认过的记忆(比如用户在对话里明确说“我的公司是某某科技”)权重最高;Agent 基于对话推断出来的记忆权重次之。检索到冲突记忆时,取高权重者,低权重记忆降级为候选参考。这套机制实现起来不难,但能有效避免 Agent 因为捡到一条过时信息而当场翻车。
再说遗忘。我见过很多项目不敢做遗忘,怕删掉有用的东西。但实践告诉我,没有遗忘的记忆库就是垃圾场。过期记忆不清理,检索模块每次都要在一堆废弃信息里翻找,命中率和响应速度一起下降。比较温和的做法是按时间戳做分层:超过有效期且无更新的记忆降为冷数据,不再参与常规检索;冷数据超过二次回收周期再物理删除。这样既不丢信息,又不会污染在线检索。
// 记忆写入流程的伪代码示意,按 INMS 思路整理 async function writeMemory(rawDialog, agentId, sessionId) { // Step 1: 判断是否值得写入 if (!shouldPersist(rawDialog)) return; // Step 2: 调用大模型生成结构化记忆单元 const unit = await llmExtract({ dialog: rawDialog, template: MEMORY_UNIT_TEMPLATE }); // Step 3: 检查是否与已有记忆冲突 const conflicts = await memoryStore.findConflicts(unit.entities); if (conflicts.length > 0) { await resolveConflict(unit, conflicts); // 按可信度裁决 } // Step 4: 写入共享库,并清理过期的缓存 await memoryStore.upsert(unit); await cache.invalidate(unit.entities); }这段伪代码我在本地模拟环境里跑过,逻辑不算复杂,真正花时间的是设计shouldPersist的判定规则和大模型的提取模板。每调整一次规则,重新跑一批测试对话,看记忆库的信噪比变化。这是整个记忆系统的打磨过程,急不来。
4. 评估设计:怎么证明“共享”真的有用
4.1 三类测试任务覆盖共享记忆的核心价值
论文要证明自己有效,实验设计是重头戏。按领域内常见评测思路,我推测 INMS 的评估会覆盖三个层面的任务,这也是我自己验证记忆系统时会采用的三个层面。
第一类是多轮连续对话一致性测试。同一用户在不同会话中提出前后关联的需求,比如第一轮说“我需要一个自动化报表工具”,第三轮问“上次说的那个工具能支持钉钉告警吗”。没有共享记忆的 Agent 到这里基本就宕机了,它不知道“上次那个工具”是什么;有共享记忆的 Agent 可以检索到时序关联记录,顺利续上上下文。这类任务的指标是续接成功率,能直观反映共享库对“跨会话连续感”的促进作用。
第二类是跨会话知识复用测试。用户在一个会话里跟售前 Agent 聊了预算和采购周期,另一天在另一个会话里跟技术支持 Agent 聊部署方案。技术支持 Agent 能不能从库里直接捞到用户的预算约束,直接决定它会不会推荐一个超预算的方案。这类任务更贴近真实业务场景,指标权重应该比第一类更高。
第三类是多 Agent 协作一致性测试。最简单的方式是设置两个 Agent 处理同一个任务链,A 先收集信息,B 后执行操作。A 记下的限制条件能不能被 B 检索到、并正确注入决策流程,是这类任务的核心验证点。我从笔记标题判断,这应该也是 INMS 的主打场景——毕竟标题里写的是“based Agents”复数形态,明显是奔着多 Agent 协作去的。
4.2 指标怎么定:只盯“准不准”是不够的
评估指标体系是论文里信息密度最高的部分,因为它藏着评价者对系统价值的理解。我按自己的评估经验,把关键指标整理成一张表,标注了每个指标实际验证的是什么:
| 指标 | 计算方式 | 验证内容 |
|---|---|---|
| 检索命中率 | 检索返回结果中与当前决策真正相关的比例 | 记忆库信噪比和检索引擎质量 |
| 事实一致性分数 | 比对 Agent 输出与历史记忆中的实体、数值、期限是否一致 | 共享记忆对输出稳定性的约束作用 |
| 跨会话复用率 | 新会话中检索到非本会话写入记忆的次数占比 | 记忆共享的真实发生频率 |
| 任务完成度 | 在标准任务集上,有共享记忆 vs 无语义记忆的完成率差值 | 共享机制的最终业务效果 |
| 上下文压缩比 | 使用共享记忆后,每轮实际注入的 token 数对比基线下降幅度 | 成本收益和窗口压力缓解程度 |
有一个容易被忽略的细节是:消融实验。去掉共享模块、退化为单 Agent 本地记忆,再跑一遍同样的测试,对比指标掉多少。这个对照实验比任何绝对数值都有说服力——它证明效果提升确实来自“共享”这个机制本身,而不是来自内存库或者大模型版本升级之类的干扰变量。我看论文时向来先扫一眼有没有做消融,没做消融的效果声明我一律打五折。INMS 这套架构如果想在学术圈站稳,消融实验应该是标配。
4.3 评估环境的搭建,决定了报告的可信度
实验要可复现,环境就必须说清楚。按我的经验,至少要在报告里列明白:大模型底座用的是哪个版本、参数跑在什么服务上、记忆库的容量和分片情况、测试用例集的规模与领域分布、基线系统是什么配置。
这块经常出问题的倒不是实验本身,而是测试数据。搭建 Agent 记忆测试集非常耗时,因为你需要的是“带长期依赖关系的多轮对话”,不是单轮问答。我的做法是先模拟生成一批包含用户偏好、任务状态演化、跨会话引用的对话流,再人工标注每一条记忆应该被哪轮对话的哪个决策节点使用。这个标注过程极其繁琐,但标注质量直接决定实验能不能说明问题。如果你准备复现类似系统,建议把 60% 的时间留给测试数据准备,而不是急着跑模型。
5. 复现与落地中踩过的坑和排查思路
5.1 记忆污染:共享机制的双刃剑
共享意味着一个 Agent 的错误可以被所有 Agent 放大。这是我实际测试中最深刻的教训。某个会话中,Agent A 因为听错了用户的口音(实际上是语音识别错误),把“用户希望每周五收到周报”记成了“用户希望每餐后收到周报”。这条错误记忆被共享后,售前、售后、客服三个 Agent 同时开始用错误信息,用户直接投诉。
排查路径是这样的:先查记忆库,看有没有异常高频出现的实体标签和时间模式;再查写入日志,锁定是哪条会话产生的错误记录;最后在共享接口上增加一条人工审核队列——对高风险类型的记忆(包含金额、时间、联系方式的),先进入待审核状态,确认无误后才转为公共记忆。这个机制加完之后,污染事件基本消失,代价是审核耗时增加了大约 15%,我觉得这笔开销完全可以接受。
5.2 检索噪声的博弈:调低阈值之前想清楚代价
在测试早期,我发现几个 Agent 的行为开始出现莫名其妙的偏差——本来一直很稳定的流程突然改了风格。查下来发现是检索阈值调得太低,导致一些似曾相识但实际无关的记忆被注入上下文。比如用户这次问的是“发票抬头变更”,系统把“该公司合同需法务审核”这条记忆也捞进来了,Agent 于是郑重其事地告诉用户“这个操作需要法务审核”,实际上根本不需要。
我的解决思路分两步走。第一步,把相似度阈值尽量抬高压降召回,先保证注入的记忆与当前问题在实体层面强相关;第二步,在重排序环节加一个任务场景过滤,每个 Agent 的配置里声明自己需要什么类型的记忆,检索结果先按类型过滤再按相似度排。这俩配合起来,噪声问题基本可以压住。想调低阈值之前要反复想清楚一个问题——多召回的那几条低相关记忆,到底是补充信息还是扰乱信息?在记忆系统里,扰乱信息永远是亏的,因为它对 Agent 的误导成本远大于信息补充收益。
5.3 权限隔离:共享不等于全民皆兵
最后一定要提醒的就是权限设计。共享共享,不能把金融项目的记忆共享给客服系统做闲聊训练。INMS 架构里如果权限字段形同虚设,等于给系统埋了一颗雷。
我推演下来的最小可行权限模型是这样:每个 Agent 在初始化时申领一个角色标签,比如 sales、support、audit;记忆单元写入时指定允许读取的角色列表;检索接口在执行前先做角色校验,不匹配的直接过滤掉。这个模型不复杂,但我见过太多项目因为“先跑通再说”的心态跳过了这一步,后面一旦要接多个业务线,就得推倒重来。记住一句话:权限模型越早设计,后面越省事。哪怕你现在只有两个 Agent 在做演示,也先把角色字段建起来,一行代码的事,后面能省三天重构时间。
结尾
我在本地搭过一个简化版 INMS 来模拟多 Agent 共享记忆的效果,整套跑下来最大的体会是:记忆共享的难点从来不在存储、不在检索算法,而在于信任管理——系统怎么判断一条记忆值不值得被其他 Agent 采信。做单 Agent 记忆时,错了也就是它自己一个人错;做成共享之后,一条错误记忆会像谣言一样传遍全组。所以如果让我给后来者建议,我会说:先把写入质量和来源可信度机制做好,再考虑共享范围。别一上来就全面共享,先让低风险的 Agent 角色试水,观察记忆库污染率稳定后再放开。
另外有个小技巧:给共享记忆库加一个定期的“记忆回顾任务”,让大模型每周扫描一次库里的高权重记忆,跟最近的对话记录做交叉验证,自动标记可疑项。这个想法来自一次偶然的观察——我发现人工审核时候选记忆之间存在大量语义重复,如果让模型主动做一轮每周的交叉校验,很多冲突在被人发现之前就已经暴露了。这个机制我还在迭代,目前看效果不错,后续可以单独写一篇文章把细节展开。