news 2026/9/7 6:10:08

AI Agent长期记忆系统设计:解决智能体跨会话失忆的工程实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI Agent长期记忆系统设计:解决智能体跨会话失忆的工程实践

AI Agent 长期记忆系统,解决的核心问题不是“让对话窗口变大”,而是让同一个智能体在跨会话、跨任务、跨用户时还能记住关键信息。如果只靠大模型的上下文窗口,用户上次提的需求、管理员配置的业务约束、任务执行到一半的状态,一旦会话结束就全没了。很多团队第一次接触智能体,都会用 Dify、Coze、扣子这类平台快速搭一个聊天机器人,跑起来确实快,但聊到第二轮、第三天就发现问题了:每次对话都要让用户重新说一遍背景,用户确认过的方案也会被模型慢慢忘掉,规则更新之后旧记忆还在干扰输出。这篇内容就是给正在搭建智能体应用、或者已经发现对话机器人“每次都要重新认识用户”的开发者看的。最值得关注的不是某个具体产品,而是一套长期记忆系统的设计思路:先想清楚要记什么,再设计存储和召回,最后才谈技术选型。

这类系统在企业场景里的价值也容易理解。客服智能体需要记住用户的订单编号和投诉进展,销售智能体需要记住客户所在公司、决策链和上一次沟通结论,内部知识助手需要记住员工偏好不同格式、不同权限范围。没有长期记忆,这些智能体就只是在“聊一句算一句”,很难承担真正需要持续追踪的业务。

1. 先搞懂 Agent 的“失忆”到底发生在哪一层

很多项目组排查失忆问题时,第一反应是换更大的模型、加长上下文窗口,结果发现治标不治本。原因很简单:失忆不是单个原因造成的,而是信息链路在不同环节断掉了。要搭长期记忆系统,第一步不是写代码,而是定位你的智能体到底在哪一层失忆。

1.1 “每次都像第一次见面”是会话状态问题

最常见的失忆发生在会话层面:用户和智能体对话一轮后关闭页面,下一次再打开,智能体完全不记得之前聊过什么。你问“上次说的方案怎么样”,它只会回一句“抱歉,我们没有历史记录”。

这类问题的本质是会话没有持久化。很多平台虽然带有“多轮对话”功能,但所谓多轮对话通常只覆盖当前会话窗口内部。一旦会话标识失效、进程重启、负载均衡切换到另一台节点,上下文就丢失了。判断方法也很直接:

  • 连续对话是否正常;关掉页面、重新打开,是否还记得;
  • 重启服务后,是否还记得之前的关键信息;
  • 多副本部署时,同一个用户会不会被不同节点处理导致上下文不连续。

如果上述任何一个答案是“否”,说明你缺的不是模型能力,而是状态存储。

1.2 “聊着聊着忘了业务约束”是上下文容量问题

另一种失忆更隐蔽:单次会话里也记得,但聊到中后段,模型开始忽略之前已经确认过的业务规则。

比如你要求智能体“所有报价必须先经过审批才允许发送”,它前几轮记得,到第十轮可能直接输出报价,把规则忘了。又比如用户先说了“我只考虑上海市的产品”,后续提问里它又开始推荐周边城市。这类现象不是模型“坏掉了”,而是上下文到达一定长度后,模型对早期信息的关注度下降。

长上下文能力可以缓解,但不能彻底解决。作为工程方案,你需要把最重要的信息从冗长历史中提取出来,放到更靠前、更显眼的系统提示词或记忆区里。这也是长期记忆系统要做的关键动作:不是把所有历史都塞给模型,而是把高价值记忆按优先级重新组织。

1.3 会话结束后“全忘了”是持久化缺失

企业级智能体最容易踩的坑,是只在内存里维护记忆。看起来单次运行没问题,一旦服务重启、发布新版本、或者定时任务触发清理,所有记忆全部清空。

我建议在项目一开始就把记忆当作“有状态的业务数据”处理,而不是当作大模型对话的附属品。每条记忆要有独立的存储位置、生命周期、归属用户和更新记录。这样即使换模型、换提示词、换前端界面,记忆数据仍然可以复用。

1.4 多 Agent 之间的信息孤岛

如果业务里不止一个智能体,比如客服机器人、订单查询机器人、售后机器人同时跑,它们之间如果各存各的,就会出现一种奇怪现象:用户在客服那里报了故障,再去找售后机器人,售后完全不理解背景。

这种失忆属于系统架构问题,不是对话历史问题。解决方案通常在数据层:多个 Agent 共享同一套记忆存储,通过用户 ID、业务单据 ID、Agent ID 做权限隔离或联合查询。后面第 5 部分会专门展开。

2. 长期记忆不等于存档:先按用途拆成四类

很多团队搭记忆系统时,第一版就是“把用户对话记录全存进数据库,需要的时候再查”。跑两周后就会发现两个问题:数据量太大,检索太慢;存了很多没用的信息,真正要用的时候又找不到。

拆解记忆类型是避免这个问题的好办法。不同记忆的写入频率、更新方式、召回优先级都不一样,不能用一个字段全装。

2.1 情景记忆:记录发生过什么

情景记忆对应“用户在某次对话里说了什么、系统当时做了什么、结果如何”。比如用户说“我们公司 50 人,需要采购一套 OA 系统”,这句话是情景事实,应该被记录下来。

情景记忆的特点是:事件性、时间敏感。通常建议按会话或事件批量抽取,每条记录带上时间戳。它不需要频繁更新,大多是一次性写入,重复出现时才做合并。

2.2 语义记忆:沉淀业务知识和规则

语义记忆是“关于世界的知识”和“关于业务的规则”。比如公司规定“订单超过 5 万元必须走审批流程”,或者“华东区客户指的是上海、江苏、浙江、安徽这四个省份”。这类信息可能来自管理员配置、知识库文档、历史对话中确认的结论。

语义记忆与情景记忆的区别在于稳定性。业务规则变更时,旧规则必须显式停用或覆盖,否则历史记忆会对模型产生持续干扰。这也是很多知识库场景里“规则改不掉”的原因。

2.3 程序记忆:记录执行流程和技能

程序记忆对应“这件事应该怎么做”。对 Agent 来说,可以理解为工作流、技能脚本、操作 SOP。比如数据标注流程:先检查格式,再抽样评审,再正式标注,最后复核。

在大型语言模型应用里,程序记忆往往放在技能库或工作流引擎里,但企业级记忆系统可以把一部分“如何执行”的经验沉淀下来。比如智能体发现某个调用经常失败后,记录下“这种情况下应该先查日志,再检查权限”,下次遇到同类问题时,它能更快定位。这种记忆更新频率低,但价值很高。

2.4 用户画像与偏好记忆

用户画像记忆是跨会话稳定使用的用户特征。例如:名字、公司、角色、语言偏好、风格偏好、重要限制条件。它与情景记忆的区别是:情景记忆描述的是“一次事件”,画像记忆描述的是“持续状态”。

画像记忆需要更严格的更新机制。用户说一句“我不喜欢太长的回复”,你不能立刻把画像改成“讨厌长文本”,因为可能只是一次性情绪表达。更好的做法是设置阈值,比如同一个偏好出现 2 到 3 次后再写入稳定画像,避免被个别语句带偏。

记忆类型典型内容更新频率召回优先级
情景记忆用户某个需求、某次会话结果当前会话相关时高
语义记忆业务规则、知识库结论
程序记忆操作流程、问题处理经验按技能触发
用户画像偏好、身份、长期约束低但需校正稳定高

3. 企业级记忆系统的核心架构:从写入到召回

到这一步,你已经知道自己要解决哪些类型的失忆。接下来要设计的是系统能力。一个能支撑企业落地的记忆系统,至少要包含五个模块:信息抽取、存储建模、检索召回、更新合并、遗忘清理。

很多开源项目和商业方案都提供了其中部分能力。直接落地的团队可能会用向量数据库加 LangChain 的 memory 模块,或者用 Dify、Coze 这类平台内置的变量和知识库功能。但平台默认能力通常不够企业级,理解底层模块后,才能知道该在哪里补强。

3.1 记忆系统的五个核心模块

信息抽取模块负责从对话文本、业务接口回包、工单结果中提取“值得记住的信息”。它不能只做关键词抽取,还要能判断信息类型:这是用户偏好,还是业务事实,还是任务状态。常见做法是用一个较小的模型做结构化抽取,输出 JSON,再由规则校验。

存储建模模块决定记忆怎么落库。企业场景里几乎不会只用一种存储。短期、高并发的状态用 Redis 或内存;长期稳定的画像和事实用关系型数据库;需要语义检索的内容用向量库;复杂关系网络可能还要上图数据库。

检索召回模块解决的是“该把哪些记忆送回模型上下文”。这里不能只按时间倒序取最后几条,也不能把所有记忆全部塞进去。比较常见的策略是分阶段召回:先用用户 ID 和会话主题过滤,再用关键词或向量做相关性排序,最后按重要性和时效性合并成一段紧凑的上下文。

更新合并模块处理记忆冲突。用户上周说“预算 10 万”,这周说“预算会调整到 15 万”,旧记忆要不要删?建议保留变更记录,同时让“最新值”覆盖“旧值”。直接删除旧记录虽然简单,但审计和追溯时会很被动。

遗忘清理模块是很多团队最晚考虑、最后出问题的模块。随着运行时间变长,记忆数量不断增加,存储膨胀、召回噪声增多、权限风险上升。你需要定义记忆有效期、最大条数、低频访问归档策略。

3.2 存储选型不是越高级越好

常见存储类型和适用场景可以按下表理解:

存储类型适合内容典型工具不擅长
键值存储会话状态、短期上下文Redis复杂条件查询
关系型数据库用户画像、业务事实、权限PostgreSQL、MySQL、SQLite语义相似度检索
向量数据库语义相似的文本、知识片段Milvus、Qdrant、pgvector精确事务和权限管理
图数据库实体关系、知识图谱Neo4j简单高频读写
文件存储文档原文、操作日志对象存储、本地文件实时记忆召回

对初创团队和内部工具来说,SQLite 加一个向量检索组件常常足够了。对还需要支持多写入、高并发、权限隔离的系统,再上 PostgreSQL 加 pgvector 会更稳。不要一上来就上全套组件,先跑通闭环,再按瓶颈补组件。

3.3 检索召回:为什么不能只靠关键词

关键词检索适合精确匹配,比如查“订单号 A10086”。但用户提问经常是语义化的,比如“上次说的那家供应商后来怎么样了”,如果没有关键词“供应商”和“后来”,关键词检索就失效了。

向量检索能把用户问题转成向量,找语义相近的记忆片段。但向量检索也有缺点:对数字、实体名、精确条件不敏感,容易把不同用户的相似内容混在一起。所以企业级系统通常采用混合检索:关键词和向量并行召回,再做重排。

重排策略一般考虑三个维度:

  • 相关性:和当前问题语义相关度;
  • 时效性:近期更新的记忆通常优先;
  • 重要性:用户长期画像、业务规则优先级高于闲聊内容。

3.4 写入时机要克制,不是所有话都值得记

记忆系统最怕存了一堆垃圾。用户随口一句“今天天气不错”被当成画像记忆,对话中模型生成的建议也被当成用户事实写入,最后召回时全是噪声。

我建议设置一套写入规则:

  • 用户明确表达的偏好和约束,必须记;
  • 业务流程中的关键结果,比如订单状态、审批结果,必须记;
  • 模型自己的推测内容,不主动写入,除非用户确认;
  • 寒暄、情绪词、无信息量内容,不写入;
  • 涉及敏感信息时,先确认是否符合权限和合规要求。

3.5 遗忘与清理:记忆膨胀是躲不开的问题

长期记忆系统上线三个月后,大概率会遇到“记忆越来越多,召回越来越不准”的问题。原因不是模型不行,而是记忆中出现了大量过时、重复、低价值内容。

常用清理策略包括:

  • 按类型设定有效期,例如临时会话状态 24 小时过期;
  • 按访问频率归档,超过 90 天未命中的记忆降级;
  • 按冲突逻辑删除,比如用户明确否定旧记忆时,旧值停用;
  • 定期人工审核高权限记忆,比如客户画像和财务信息。

4. 最小闭环:先在单机环境跑通一套长期记忆

不要直接上微服务、消息队列、分布式数据库。第一版先跑通“一个用户、一个 Agent、一次对话、一页记忆面板”的最小闭环。下面这个流程可以用 Python 和 SQLite 实现,我尽量写得贴近实际。

4.1 环境准备与前置条件

我们假设你用的是通用 Python 环境,需要安装的依赖尽量少:

# 示例环境:Python 3.9+ # 基础依赖可以根据需要安装 pip install openai flask # 如果要做向量检索,可以加 sentence-transformers 或使用内置向量库 # 如果只是为了先跑通逻辑,先不加向量库

如果你的项目已经用了 Dify、Coze、扣子这类平台,也可以在平台上先做变量和数据库表,但为了理解原理,我建议本地按下面的思路建一遍。这样以后调试平台配置时,你能更清楚它背后在做什么。

4.2 先设计一张记忆表

不要一开始就设计十几张表。先有一张核心表,字段覆盖记忆场景的关键属性即可:

CREATE TABLE memory ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id TEXT NOT NULL, agent_id TEXT NOT NULL, memory_type TEXT NOT NULL, -- profile / fact / preference / task / skill content TEXT NOT NULL, keywords TEXT, embedding BLOB, importance INTEGER DEFAULT 5, valid_from TIMESTAMP, valid_to TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, access_count INTEGER DEFAULT 0 ); CREATE INDEX idx_memory_user_agent ON memory(user_id, agent_id); CREATE INDEX idx_memory_type ON memory(memory_type);

这里user_idagent_id是隔离维度,memory_type用于区分记忆类型,importance用于召回排序,valid_from / valid_to用于时效控制。access_count可以记录命中次数,方便后续清理低频记忆。

4.3 编写写入模块:从对话中抽取值得记住的信息

最小闭环里不写复杂模型,先做规则抽取加一个大模型的 JSON 输出。下面是伪代码逻辑:

def extract_memory_from_text(text: str, user_id: str, agent_id: str): # 第一步:先判断这段文本值不值得记忆 memory_candidates = [] # 规则:用户明确表达偏好 if "我希望" in text or "我不喜欢" in text or "请记住" in text: memory_candidates.append({ "memory_type": "preference", "content": text.strip() }) # 规则:包含订单号/编号等业务实体 if "订单" in text and "号" in text: memory_candidates.append({ "memory_type": "fact", "content": text.strip() }) # 补充:调用大模型做结构化抽取,让模型输出 JSON # 建议设置 system prompt,只抽取用户明确表达的信息 # 返回示例: [{"type": "preference", "content": "用户希望回复简短"}] for mem in memory_candidates: save_memory(user_id, agent_id, mem) def save_memory(user_id, agent_id, mem): # 检查是否已有类似记忆,避免重复堆积 similar = find_similar_memory(user_id, agent_id, mem["content"]) if similar: update_memory(similar["id"], content=mem["content"], importance=similar["importance"] + 1) else: insert_memory(user_id, agent_id, mem)

核心逻辑并不复杂:先抽取,再查重,再写入。很多人栽在没有查重这一步,同一条信息被存了几十条,召回时噪声极大。

4.4 编写召回模块:拼出对当前回答最有用的记忆

召回时不能把库里所有内容都扔给模型。我一般会做两轮筛选:

第一轮按user_idagent_id缩小范围; 第二轮按记忆类型、关键词相似度、重要性和时效性排序,取前 N 条。

def recall_memory(question: str, user_id: str, agent_id: str, top_k=8): # 1. 先取该用户在该 Agent 下的所有活跃记忆 all_memory = select_active_memory(user_id, agent_id) # 2. 简单关键词打分 for mem in all_memory: score = 0 for kw in mem["keywords"]: if kw in question: score += 1 mem["score"] = score # 3. 按 score、importance、updated_at 综合排序 ranked = sorted( all_memory, key=lambda x: (x["score"] * 2 + x["importance"] * 1.5 + recency_score(x["updated_at"])), reverse=True ) # 4. 返回前 top_k 条 return ranked[:top_k]

如果能接受额外依赖,可以换成向量检索。向量检索适合“语义相近但字面不同”的情况,但关键词得分仍然有保留价值,特别是在精确实体名场景。混合召回、统一排序是当前比较稳妥的工程方案。

4.5 把记忆接入对话

接入位置很关键。记忆应该拼进系统提示词或用户消息之前,让模型在生成时明显看到。简单示例:

def build_prompt(user_id, agent_id, user_message): mem_list = recall_memory(user_message, user_id, agent_id) memory_text = "" if mem_list: memory_text = "## 用户历史记忆\n" for item in mem_list: memory_text += f"- [{item['memory_type']}] {item['content']} (更新时间: {item['updated_at']})\n" system_prompt = "你是企业智能助手。请结合用户历史记忆回答问题,如果记忆中没有相关信息,明确说明你无法确定。" final_prompt = system_prompt + "\n\n" + memory_text + "\n\n用户问题:" + user_message return final_prompt

这里有个容易被忽略的地方:不是所有用户消息都需要完整读取全部记忆。问题越复杂、历史越多,越应该只取相关的部分。我建议在召回结果后面再加上一句话“以下记忆仅为参考,不可编造”,避免模型把不相关记忆当成事实。

5. 进阶改造:多用户、多 Agent 与企业级落地要点

最小闭环跑通后,就要开始处理“能用”和“能上线”之间的差距。这个差距通常体现在数据隔离、异步写入、权限治理三个方面。

5.1 数据隔离:按租户、用户、Agent 三权隔离

企业级记忆系统不能只有一个user_id。如果多个部门、多个客户共用同一套系统,记忆互相可见会酿成事故。建议保留三个隔离字段:

  • tenant_id:租户或企业 ID;
  • user_id:最终用户 ID;
  • agent_id:归属 Agent 或业务线。

每条记忆的访问都要带上三层条件。界面上的记忆面板也要按这三个维度过滤,避免一个管理员看到所有租户的敏感记忆。

5.2 批量任务与异步写入:不要让记忆写入阻塞对话

在实际业务里,记忆系统的写入和召回如果都同步执行,会明显增加对话延迟。特别是在高并发客服场景,一次对话里可能触发多次抽取和多次召回。

我建议把写入链路异步化:对话主流程只负责召回和生成,写入操作放到消息队列或后台任务里执行。这样即使抽取模型偶尔超时,也不会影响用户等待时间。

# 示例:用 Redis Stream 或简单任务队列承接写入 # 伪代码:dialogue_service.respond() 后,仅 enqueue(extract_and_save_memory)

需要注意,异步写入要保证顺序。同一个用户连续两条消息,如果第二条先执行写入,第一条后执行,会出现旧信息覆盖新信息。任务队列里最好按user_id做顺序保证,或者用更新时间戳做乐观锁。

5.3 多 Agent 共享记忆与冲突处理

如果多个 Agent 需要共享记忆,建议不要直接共用一张大表。更稳妥的做法是维护一张“共享记忆授权表”,明确哪些 Agent 可以访问哪些记忆类型。

举例:客服 Agent 可以读用户的订单状态,但不能读财务 Agent 生成的内部成本记忆。即使读写的是同一张表,也要通过权限层过滤。

冲突处理也要有明确规则。两个 Agent 写入同一条用户偏好,一个认为用户偏好“详细报告”,另一个认为“简洁摘要”,系统不能自动判定谁对。我建议设置“最后写入胜出”策略,并把旧记录保留在历史表里,方便人工介入。

5.4 对接业务系统与知识库

真正有价值的企业记忆,不只来自对话,还来自业务系统。一个订单查询 Agent 的记忆,应该能关联 CRM 里的客户等级、ERP 里的订单状态、工单系统里的故障记录。

落地方式通常是:对话记忆只存摘要和关联 ID,详细业务数据仍由原系统提供。不要把所有业务数据都复制进记忆库,否则数据一致性、安全边界、同步链路都会变得复杂。

对接知识库时要注意,知识库内容大多是静态语义记忆,更新频率低,可以单独建索引。常见搭配是把 Dify、MaxKB、企业 Wiki 的内容导入向量库,再与对话记忆联合召回。最近讨论比较多的 RippleMem 思路也点到了一个关键:记忆系统不是检索得越多越好,而是让 Agent 学会在合适的时候回忆该记的那部分。知识库里一大段文档全塞进上下文,既不经济也容易干扰回答。

5.5 权限与安全:什么能进记忆、谁能读到记忆

这是个容易被忽略但必须提前设计的模块。企业级记忆涉及客户隐私、商业数据、员工信息,一旦写入系统,就可能长期存在。

至少要定义三类问题:

  • 哪些信息不允许写入记忆。比如明文密码、身份证号、银行卡号、健康数据,应该提前过滤或脱敏;
  • 谁可以读取记忆。管理员、客服坐席、外部客户,权限都要分开;
  • 用户如何删除自己的记忆。这不仅是产品需求,在很多地区也是基本合规要求。

删除逻辑不能只做物理删除,还要考虑删除后其他 Agent 里缓存的历史记忆。建议实现“记忆删除任务”,删除主记忆的同时触发相关 Agent 缓存刷新。

6. 验收标准:什么样的记忆系统才算合格

很多团队搭完记忆系统后,只会测“连续对话能不能记住”。这个标准太低了。要判断一套长期记忆系统是否合格,至少需要跑通下面几类用例。

6.1 至少要跑通这 5 个用例

测试用例预期结果
同一用户跨会话记住偏好用户新开会话说“我还想要上次那个风格”,系统能定位到之前记录
不同用户记忆不串用户 A 的偏好不出现在用户 B 的上下文中
记忆更新后旧值不干扰用户将预算从 10 万改为 15 万,后续回答按 15 万执行
重启服务后记忆仍在重启后端服务,用户原始记忆完整保留
无关记忆不被召回用户问“今天天气”,系统不把历史采购需求塞进上下文

一个合格的系统不一定每条用例都满分,但至少要能明确说明“为什么没做到”。比如无关记忆没有被召回,是因为关键词过滤生效,还是因为根本没找到?可解释性比单次通过更重要。

6.2 性能与资源判断标准

性能不是“跑得快”这么简单。我建议从四个维度记录数据:

  • P50 / P95 召回耗时:可以接受的量级根据业务定,通常要求不超过几百毫秒;
  • 写入吞吐:异步任务每秒能处理多少条记忆写入;
  • 存储增长:每千次对话新增多少条记忆、多少 MB 存储;
  • 上下文体积:实际拼进系统提示词的平均记忆字符数,避免无限膨胀。

如果发现召回耗时随数据增长明显上升,说明索引或检索策略需要优化,而不是继续加机器。

6.3 回复质量判断标准

长期记忆最终要服务于回复。判断回复是否“真正用上了记忆”,可以看三个信号:

  • 相关性:模型输出是否包含了记忆里的关键实体或结论;
  • 一致性:是否与用户最近一次确认的状态一致;
  • 克制性:对记忆中没有的信息,是否明确说不知道,而不是编造。

建议准备一组固定的测评问题集,每次功能改动后跑一遍回归。没有测评集,你可能连续改坏几版都没发现。

6.4 可观测性:记忆面板和日志必须齐全

企业级记忆系统不能黑盒运行。至少要做一个简单管理界面,能看到:

  • 每个用户当前有多少条记忆;
  • 每条记忆的类型、内容、更新时间;
  • 最近一次对话中实际召回了哪些记忆;
  • 哪些记忆被用户或管理员删除。

有了这些日志,排查问题时可以少走很多弯路。否则用户反馈“它老是记错”,你连它记了什么、为什么这样记都看不到。

7. 常见坑与排查顺序:记忆不生效时先看哪里

记忆系统真正坑人的地方,往往不是模型、不是算法,而是数据流断了。下面这几类问题我几乎每次做项目都会遇到,按照排查顺序整理一下。

7.1 第一类:看起来接了记忆,但回复里完全没用上

先排查召回环节:用户问题从进去到生成回复之间,到底有没有把记忆拼进 prompt。常见原因是user_id没有正确传递。Web 端和 App 端各写各的,用户 ID 标准不一致,导致会话根本查不到历史记忆。

再排查 prompt 拼接顺序。有些团队把记忆放在很靠后的位置,上下文一长,模型对记忆的注意力就会不足。建议把记忆放在系统提示词之后、用户问题之前,并且用分隔标记标清楚。

7.2 第二类:检索出来的内容不相关

如果只有关键词匹配,很容易漏掉语义相似但字面不同的记忆。比如用户之前说“我喜欢简洁”,现在问“能不能直接说重点”,两者语义接近但关键词重叠很少。可以引入向量检索,或者至少加一层同义改写。

如果已经用了向量检索但不相关,优先检查分块策略。长记忆被整体向量化后,语义会被稀释。建议一条记忆一个主题,如果一条记忆里有多个结论,拆成多条再写入。

7.3 第三类:数据越存越多、速度越来越慢

常见原因是所有内容都写入记忆,且没有清理任务。我见过一个内部系统,跑了一个月,单个用户的记忆量已经超过几十页,召回自然越来越慢。

建议给记忆表增加生命周期字段,并写一个定时任务,把超期记忆标记为无效,或者迁移到冷存储。写入时也要做查重,重复内容不要反复插入。经过清理后,用户活跃记忆量一般可以控制在几十条到一两百条范围内,这个量级用简单检索也能很快返回。

7.4 第四类:多用户之间记忆串了

这类问题通常发生在测试环境,多人共用同一套账号,或者代码里的过滤条件只写了agent_id没写user_id

排查顺序建议:

  1. 先看数据库中当前数据的user_id是否属于同一个用户;
  2. 再看查询 SQL 是否真的带了user_id条件;
  3. 再看接口层是否把登录态映射成了正确的用户 ID;
  4. 最后看是否有批量写入任务没有设置隔离维度。

7.5 第五类:用户要求删除记忆,但旧记忆还在影响回答

很多系统的删除只是删了主记录,没有级联清理已经生成的 prompt 缓存、向量索引和日志副本。结果用户说“请忘掉我的数据”,但系统依然能召回旧内容。

建议把删除操作设计成一条“删除指令”,不仅删主记录,还要触发:

  • 向量库中对应 embedding 删除;
  • 缓存和离线副本标记失效;
  • 相关 Agent 的短期上下文刷新。

这类逻辑虽然繁琐,但恰恰是企业级系统必须做到的部分。

长期记忆系统的落地,我的建议始终是先窄后宽:先挑一个真实业务场景,比如客服回归记录、销售客户跟进,用一个用户、一个 Agent、几张表跑通,再逐步扩展到多租户、多 Agent 和批量写入。技术选型上,不要迷信“必须上大数据库”,先把召回逻辑、写入去重、权限隔离和删除机制这四个基础能力做扎实,比堆一堆组件更重要。踩过几次之后你会发现,很多问题不是工具能力不够,而是前置数据链路和权限边界没有整理干净。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 6:10:04

基于RK3588的C++视频监控系统:从V4L2采集到RTSP推流全解析

简介:C视频监控系统开发源码是一套基于MFC框架与C语言实现的多路视频监控工程,适合Windows桌面应用开发者、计算机视觉初学者以及需要快速搭建监控原型的项目人员。工程在VC6.0环境下编写,涵盖摄像头采集、视频显示、录像保存、多路并发预览等…

作者头像 李华
网站建设 2026/9/7 6:09:46

展讯平台刷机工具全解析:从驱动到救砖的实操指南

简介:这是一套面向展讯平台功能机与智能机用户的升级刷机工具集合,适合需要优化系统、修复故障或刷入定制ROM的普通用户和维修从业者。资源共36个文件,压缩包约1.21MB,包含DLoaderR.exe主程序、BMPlatform.dll等动态库、多种ini配…

作者头像 李华
网站建设 2026/9/7 6:09:14

AI自养活实验:用150英镑和三个月验证AI服务的真实价值

如果有人给 AI 150 英镑和三个月时间,让它自己赚回每月的订阅费用,你会怎么设计这个实验?我见过不少类似的项目,真正跑下来之后,结论往往不是“AI能不能赚钱”,而是“人类能不能把任务边界、成本预算和验收…

作者头像 李华
网站建设 2026/9/7 6:09:04

交换机品牌盘点与实战配置:从核心原理到常见坑全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华