Agent Memory核心原理与实战:用Redis构建大模型智能体记忆系统

Agent Memory核心原理与实战:用Redis构建大模型智能体记忆系统 最近不少做 Agent 应用的朋友都在讨论同一个问题Agent 功能写完了对话也能跑但用户一刷新页面它就像失忆了一样什么都不记得。你上午刚和它确认过收货地址、聊过预算范围下午再打开它又问一遍“请问您想买什么”。这种感觉就像你和一个记性极差的人共事每句话都要重复交代。很多人的第一反应是“加大模型上下文窗口”把历史记录全塞进去。但稍微想深一步就会发现这条路走不通上下文再长也有上限成本还会成倍上涨而且真正重要的用户偏好和关键决策信息会淹没在大量无关的闲聊里。真正让 Agent 从“能用”变成“好用”的恰恰是一个很多人没有认真设计过的模块——Agent Memory智能体记忆。这篇文章会把 Agent Memory 从概念到落地完整讲透。我们会先弄清楚记忆到底分几种、分别解决什么问题然后对比不同的存储方案最后用一个电商场景的完整代码案例带你把“记忆的写入、存储、修改、检索”整个闭环跑通。很多教程只教你怎么调 API但真正让你少走弯路的是理解记忆该如何设计以及它在工程上应该放在什么位置。1. 这篇文章真正要解决的问题先说说现在 Agent 开发最普遍的困境。许多初学者给 Agent 接上大模型 API 后就以为大功告成了。测试时发现只要对话一结束所有信息全部归零。于是大家开始手动保存聊天记录每次请求把全部历史拼接进 Prompt。这个方法在小规模演示里可以工作但一旦遇到真实业务场景问题立刻暴露出来。第一个问题是成本失控。用户和客服 Agent 聊了半小时光聊天记录就可能上万 token每次都全量重放接口调用成本成倍上升。第二个问题是关键信息稀释。用户可能在某个犄角旮旯提过“我喜欢简约风、预算五千以内”但这条关键偏好和大量寒暄混在一起模型反而无法从中准确提取。第三个问题是无法跨会话复用。今天的对话记录明天还能用吗如果用户隔了一周再回来Agent 还能记住他的偏好和上次的进度吗这篇文章要解决的正是这三类问题。我们先建立一个清晰的判断Agent 的真正智能不只在模型推理能力更在于它能不能在恰当的时候调用恰当的记忆。模型本身是“大脑”而记忆系统是“海马体”负责把重要的事沉淀下来在需要的时候重新提取出来。读完这篇文章你会得到四样东西一套理解 Agent Memory 的完整框架知道短期记忆、长期记忆、工作记忆分别是什么。一个可落地的技术选型思路明白什么时候用 Redis、什么时候用向量数据库、什么时候用普通数据库。一个电商场景的完整代码实战包含用户偏好记忆、会话摘要记忆、意图与上下文记忆的写入和修改。一套工程化排错清单覆盖记忆不生效、数据格式错误、过期时间踩坑等高频问题。2. Agent Memory 的基础概念与核心原理2.1 为什么记忆对大模型应用如此关键大模型本身有一个天然的局限它不保留状态。你调用一次 API它看到多少上下文它就基于多少内容回答请求结束后一切归零。这在传统软件开发里很好理解——HTTP 协议本身也是无状态的所以要靠 Session、Token、Redis 来维护状态。Agent 应用也一样只是维护的状态从“用户登录信息”变成了“用户偏好、业务上下文、进度节点、历史决策”。从工程角度看记忆的作用可以概括成三件事连续性让多轮对话、跨会话任务可以衔接起来。个性化让 Agent 基于用户画像和行为数据做出定制化响应。效率只把关键信息放入 Prompt减少 token 消耗降低响应延迟。2.2 记忆的四层模型目前业界讨论 Agent Memory 时一般会把它分成几层。这里我用一个更容易理解的“人类大脑记忆”类比来讲。短期记忆Short-Term Memory也叫会话记忆。它对应的是当前这次对话的上下文比如用户刚刚说“我想买一款适合送女朋友的生日礼物”Agent 需要在这个会话里记得这句话。实现方式通常是把最近几轮对话拼进 Prompt或在内存中维护一个消息列表。这个层级的核心诉求是“不丢上下文”。工作记忆Working Memory可以看作是当前任务正在使用的信息集合。比如在电商场景里用户正在比较三款手机工作记忆会记录“用户目前看中了 A 和 B预算在四千到五千比较在意拍照效果”。它不是全部聊天记录而是经过提炼的、服务于当前任务的结构化信息。长期记忆Long-Term Memory对应跨会话、跨任务的持久化存储。用户一周前说过的“我喜欢日系风格”“我家里有两个孩子”等信息会沉淀到这里。长期记忆通常存储在 Redis、MySQL、向量数据库等外部存储中。情景记忆Episodic Memory则记录完整的事件过程。比如“2025 年 12 月 12 日用户投诉过物流延迟三小时”。这类记忆往往用于复盘、个性化服务和异常场景处理。在工程实现上我们不用把每一层都做得很复杂。中小型项目更多是把短期记忆放在程序内存中把长期记忆放在 Redis 或其他数据库里。下面这张表可以帮助你快速理解它们的职责划分记忆类型生命周期存储位置典型内容工程实现方式短期记忆会话期间内存/上下文最近几轮对话List 维护消息记录工作记忆任务期间内存/缓存当前目标、候选方案结构化字典/JSON长期记忆跨会话Redis/MySQL用户偏好、画像、历史行为Key-Value/JSON情景记忆长期数据库/向量库完整事件、重要经历JSON 文档/向量嵌入2.3 记忆的完整生命周期记忆不是“存进去就完了”真正的难点在于管理它的生命周期。一次完整的记忆流需要经历四个阶段。第一阶段是写入。用户说了一句话Agent 需要判断哪些信息值得记住。比如用户说“我不喜欢红色”这就是一条偏好值得入长期记忆“今天天气不错”这种寒暄大概率不需要记录。这种判断可以交给大模型来做也可以基于规则配置关键词。第二阶段是存储。写入的信息需要以合适的结构保存。是用字符串拼接还是用 JSON要不要设置过期时间这个决定会影响后续的检索效率。第三阶段是检索。在后续的对话里Agent 如何知道该调用哪段记忆是按用户 ID 精确查询还是按语义相似度检索如果记忆库里有 100 条偏好是否全部塞进 Prompt显然不行必须做筛选。第四阶段是修改与淘汰。用户的偏好会变记忆需要更新。比如用户说“我现在不喜欢黑色了改成白色”系统是不是该更新原来的偏好还是新增一条“不喜欢黑色”同时过期的记忆需要清理避免干扰判断。如果你只是把聊天记录一股脑存下来然后全部丢给大模型那不叫 Agent Memory那只是一个很笨的日志系统。真正合格的设计至少要能回答这四个问题什么该记、记在哪里、怎么取用、什么时候更新。3. 存储方案选型Redis、向量数据库还是普通数据库3.1 为什么很多人搜“redis agent memory 如何使用”从相关热词来看“redis agent memory 如何使用”是很多人关心的。原因很简单Redis 是当前实现 Agent Memory 性价比最高的方案之一。它天然支持 Key-Value 结构读写速度极快支持设置过期时间还自带内存淘汰机制。对于用户偏好、会话状态这类结构化记忆Redis 几乎是为它们量身定做的。很多人误以为 Agent Memory 一定要上向量数据库。这其实是一个常见的误解。向量数据库解决的是“语义相似检索”问题比如用户问“我能带宠物吗”你需要根据语义去匹配“是否允许携带动物入住”这条记忆关键词匹配做不到。但如果你只需要精确读取某个用户今天的购物车状态直接按用户 ID 查 Redis 就足够了。3.2 三种方案的对比方案适合场景优势劣势Redis用户画像、会话状态、偏好设置速度快、支持过期、结构灵活语义搜索弱关系型数据库MySQL/PostgreSQL复杂的记忆关联查询、审计记录事务支持好、适合结构化数据读写速度相对慢需要建表向量数据库如 Milvus、Qdrant、pgvector语义检索、相似记忆召回能按语义找记忆部署重、查询延迟相对高实际项目里这三者通常配合使用而不是互相替代。最简单的组合是Redis 负责短期状态和用户画像向量数据库负责长期记忆的语义检索MySQL 负责全量的历史归档。但对于一个中小型项目或学习案例先用 Redis 就能解决大部分问题。3.3 一个实用的最小记忆架构在进入代码之前先用一张逻辑图描述我们将要构建的记忆系统。它分为四层接入层接收用户对话和事件例如电商网站里的浏览商品、加入购物车、发起客服咨询。解析层大模型或规则引擎从原始信息中抽取记忆点例如用户偏好、当前意图、任务进度。存储层Redis 中为每个用户维护多个 Key分别存储画像、会话摘要和短期上下文。应用层当用户发起新对话时Agent 先从 Redis 加载记忆并组装 Prompt然后用大模型生成回复。由于我们不允许使用 Mermaid这里用文字描述整个数据流用户行为触发解析层解析结果写入 Redis用户再次发起请求时系统先拉取 Redis 记忆并注入 Prompt大模型基于 Prompt 生成个性化回复回复完成后Agent 根据对话内容更新记忆。4. 环境准备与前置条件这一节我们准备实战环境。为了避免版本差异带来的干扰以下依赖以当前主流稳定版本为准文中不限定死特定版本号。你实际安装时建议使用你工作环境里已有的版本只要保证核心接口一致即可。4.1 需要的软件清单Python 3.10 或更高版本低版本也可以但推荐 3.10 以获得更好的类型支持和异步能力。Redis 6.0 以上本地启动或使用云服务均可。pip 包管理器。一个可访问的大模型 API 服务OpenAI、通义千问、文心一言等均可本文以 OpenAI SDK 为例但核心代码不依赖特定厂商。VS Code 或其他 Python IDE。4.2 安装依赖创建一个项目目录并在其中创建虚拟环境mkdir agent-memory-demo cd agent-memory-demo python -m venv venv source venv/bin/activate # Windows 下执行 venv\Scripts\activate然后安装以下依赖pip install redis openai python-dotenv这里逐个解释redisPython 操作 Redis 的官方客户端库。openai调用 OpenAI 兼容接口的 SDK。如果使用国内大模型服务多数也兼容 OpenAI 的接口格式。python-dotenv读取.env文件中的环境变量方便管理 API Key。4.3 准备 Redis你可以在本地直接启动 Redisredis-server默认监听 6379 端口。生产环境必须设置密码并限制访问来源后面我们会在最佳实践里详细讲。4.4 环境变量配置在项目目录下创建.env文件OPENAI_API_KEY你的API密钥 OPENAI_BASE_URLhttps://api.openai.com/v1 REDIS_HOSTlocalhost REDIS_PORT6379 REDIS_PASSWORD这里要注意.env文件不要提交到 Git 仓库应该加入.gitignore。5. 电商场景核心流程拆解5.1 场景设定假设我们要为一个电商平台开发一个智能导购 Agent。它需要记住以下信息用户的基础偏好比如“喜欢简约风格”“预算三千以内”“家有两个孩子”。当前的购物目标比如“正在找一款适合全家出游的 SUV 模型玩具”。上一轮对话的进度比如“已经推荐了两款用户对其中一款感兴趣”。这个 Agent 在不同会话里都能识别出老用户并直接基于记忆做出个性化推荐而不是每次都从零开始。5.2 核心流程拆解整个流程可以分为五步。步骤一用户触发事件。用户在前端进行了操作比如浏览商品、点击收藏、发送客服消息。每一种操作都可能产生记忆。步骤二事件解析。事件进入记忆解析层由大模型或规则抽取关键信息。例如用户发来消息“我想买个书架最好白色的预算三百左右”解析层需要抽取出“物品书架颜色白色预算300 元”这样的结构化数据。步骤三记忆写入。解析结果写入 Redis。可以使用多个 Key分别存储不同维度的记忆。比如user:123:profile存画像user:123:preferences存实时偏好。步骤四记忆检索与组装。用户下一次发消息时系统先通过用户 ID 从 Redis 读取记忆。然后把这些记忆转成自然语言描述拼接到系统 Prompt 中。大模型基于这个带有历史记忆的 Prompt 生成回复。步骤五记忆更新。对话结束后根据新产生的信息对记忆做增量更新。例如用户说“算了预算提高到五百”就需要修改之前的预算字段。这里要特别强调一下“修改”和“追加”的区别。很多初学者喜欢把记忆全部追加到列表尾部这会导致旧数据和新数据冲突。比如用户先说“喜欢白色”后来又改成“其实米色更好”。如果只追加不修改Agent 就会同时看到两条矛盾的信息从而产生混乱。正确做法是先识别出“颜色偏好”这个字段已被修改然后覆盖旧值。6. 完整示例与代码实现现在进入文章的核心部分。我会带你实现一个最小但完整的 Agent Memory 系统包含记忆写入、修改、检索和应用的全流程。6.1 项目结构agent-memory-demo/ ├── .env ├── config.py # 读取配置 ├── memory_store.py # 基于 Redis 的记忆存储类 ├── memory_parser.py # 基于大模型的记忆解析器 ├── agent.py # Agent 主逻辑组装记忆与调用大模型 └── run_demo.py # 演示入口6.2 配置文件 config.py# 文件路径agent-memory-demo/config.py import os from dotenv import load_dotenv load_dotenv() OPENAI_API_KEY os.getenv(OPENAI_API_KEY) OPENAI_BASE_URL os.getenv(OPENAI_BASE_URL, https://api.openai.com/v1) REDIS_HOST os.getenv(REDIS_HOST, localhost) REDIS_PORT int(os.getenv(REDIS_PORT, 6379)) REDIS_PASSWORD os.getenv(REDIS_PASSWORD, )这个文件的作用是把.env里的配置统一加载进来避免在业务代码里到处读取环境变量。6.3 记忆存储类 memory_store.py这一部分是记忆系统的地基。我们设计一个MemoryStore类用 Redis 存储用户的结构化记忆。# 文件路径agent-memory-demo/memory_store.py import json import redis import config class MemoryStore: 基于 Redis 的 Agent Memory 存储类。 key 设计思路 user:{user_id}:profile 用户长期画像 user:{user_id}:session 当前会话摘要 user:{user_id}:context 短期上下文状态 def __init__(self): self.client redis.Redis( hostconfig.REDIS_HOST, portconfig.REDIS_PORT, passwordconfig.REDIS_PASSWORD or None, decode_responsesTrue, ) def _profile_key(self, user_id: str) - str: return fuser:{user_id}:profile def _session_key(self, user_id: str) - str: return fuser:{user_id}:session def _context_key(self, user_id: str) - str: return fuser:{user_id}:context def set_user_profile(self, user_id: str, data: dict) - None: key self._profile_key(user_id) # 读取旧数据再做覆盖合并 old self.get_user_profile(user_id) old.update(data) self.client.set(key, json.dumps(old, ensure_asciiFalse)) def get_user_profile(self, user_id: str) - dict: key self._profile_key(user_id) raw self.client.get(key) if raw: return json.loads(raw) return {} def update_user_profile(self, user_id: str, updates: dict) - dict: 更新用户画像中指定的字段这是记忆修改的核心入口。 例update_user_profile(123, {preferred_color: 米色}) self.set_user_profile(user_id, updates) return self.get_user_profile(user_id) def set_session(self, user_id: str, session_data: dict, ttl_seconds: int 3600) - None: key self._session_key(user_id) self.client.set(key, json.dumps(session_data, ensure_asciiFalse), exttl_seconds) def get_session(self, user_id: str) - dict: key self._session_key(user_id) raw self.client.get(key) if raw: return json.loads(raw) return {} def set_context(self, user_id: str, context_data: dict) - None: key self._context_key(user_id) self.client.set(key, json.dumps(context_data, ensure_asciiFalse)) def get_context(self, user_id: str) - dict: key self._context_key(user_id) raw self.client.get(key) if raw: return json.loads(raw) return {} def clear_user_memory(self, user_id: str) - None: 清空某个用户的全部记忆一般用于隐私删除或测试环境。 self.client.delete( self._profile_key(user_id), self._session_key(user_id), self._context_key(user_id), )这个类有几处设计值得你注意第一set_user_profile里做了“覆盖合并”而不是直接覆盖整个 key。这样可以防止并发写入把一个维度的更新冲掉另一个维度。比如用户画像包含color: 白色和budget: 300如果一次只更新budget合并操作能保留color。第二update_user_profile是记忆修改的对外入口。当用户说“我不喜欢白色了”系统会调用这个方法把颜色字段改成新的值而不是追加一条新记忆。第三会话记忆设置了 TTL。客服场景里一次会话的摘要通常只需要保留几分钟到几小时。设置过期时间可以防止垃圾数据堆积。6.4 记忆解析器 memory_parser.py这部分负责判断“什么内容值得记忆”。最简单的做法是写规则如果检测到“我喜欢”“我不喜欢”“我的预算是”等句式就抽取对应偏好。但更通用、更贴近 Agent 玩法的做法是调用大模型做信息抽取。# 文件路径agent-memory-demo/memory_parser.py import json from openai import OpenAI import config client OpenAI( api_keyconfig.OPENAI_API_KEY, base_urlconfig.OPENAI_BASE_URL, ) SYSTEM_PROMPT 你是电商场景的对话信息抽取助手。用户会提供一段客服对话或用户行为描述。 请从文本中抽取值得长期记忆的结构化信息并输出 JSON。 要求 1. 抽取字段包括preferred_style(偏好风格)、preferred_color(偏好颜色)、budget(预算数字)、shopping_goal(当前购物目标)、special_notes(特殊备注)。 2. 如果某个字段在文本中未出现统一设为 null。 3. 只输出 JSON不要输出任何解释。 .strip() def parse_memory_from_text(user_text: str) - dict: 调用大模型从用户文本中抽取记忆点。 response client.chat.completions.create( modelgpt-4o-mini, # 具体模型名以你实际可用的 API 为准 messages[ {role: system, content: SYSTEM_PROMPT}, {role: user, content: user_text}, ], temperature0.0, response_format{type: json_object}, ) raw response.choices[0].message.content return json.loads(raw)大模型抽取比规则抽取的优点在于泛化能力强。规则只能识别固定的句式而大模型能理解“我想要一个白色的书架但三百以内能买到的最好”这种信息密度很高的自然语言直接把颜色、物品、预算全部抽出来。需要说明的是response_format{type: json_object}并不是所有 API 服务都支持。如果你用的服务不支持可以把这一行删掉然后自行从返回文本中解析 JSON。我建议给json.loads外面包一层try...except防止模型偶尔输出格式错误时把整个程序中断。6.5 Agent 主逻辑 agent.py接下来把记忆存储和解析组装成一个完整的 Agent。它的工作流程是接收用户输入和用户 ID。从 Redis 拉取该用户的画像、会话摘要和上下文。把所有记忆转成自然语言描述注入系统 Prompt。调用大模型生成回复。对用户输入做记忆抽取把新信息写回 Redis。# 文件路径agent-memory-demo/agent.py from openai import OpenAI import config from memory_store import MemoryStore from memory_parser import parse_memory_from_text client OpenAI( api_keyconfig.OPENAI_API_KEY, base_urlconfig.OPENAI_BASE_URL, ) def build_memory_prompt(user_id: str, store: MemoryStore) - str: 把用户记忆组装成 Prompt 片段。 profile store.get_user_profile(user_id) session store.get_session(user_id) context store.get_context(user_id) memory_lines [] if profile: memory_lines.append(用户长期画像 str(profile)) if session: memory_lines.append(最近会话摘要 str(session)) if context: memory_lines.append(当前对话上下文 str(context)) if not memory_lines: return return \n.join(memory_lines) def chat_with_agent(user_id: str, user_message: str) - str: store MemoryStore() # 第一步获取该用户的历史记忆并组装到 Prompt 中 memory_prompt build_memory_prompt(user_id, store) system_prompt 你是一个电商智能导购助手语气专业且友好。 if memory_prompt: system_prompt \n\n以下是用户过去的记忆信息请在回答时充分利用\n memory_prompt # 第二步调用大模型生成回复 response client.chat.completions.create( modelgpt-4o-mini, messages[ {role: system, content: system_prompt}, {role: user, content: user_message}, ], temperature0.7, ) answer response.choices[0].message.content # 第三步解析用户输入中的记忆点 try: parsed parse_memory_from_text(user_message) if parsed: # 过滤掉空字段 updates {k: v for k, v in parsed.items() if v} if updates: store.update_user_profile(user_id, updates) except Exception as e: print(f[Memory Parser Warning] {e}) # 第四步把当前轮次的关键信息写入上下文 ctx store.get_context(user_id) ctx[last_user_message] user_message ctx[last_reply] answer store.set_context(user_id, ctx) return answer def end_session_summary(user_id: str, session_text: str) - None: 在会话结束时把整场对话的摘要写入长期记忆。 store MemoryStore() summary { session_summary: session_text, ended_at: 2026-01-01 12:00:00 # 实际项目用当前时间 } store.set_session(user_id, summary, ttl_seconds7200)这里有一个地方容易踩坑parse_memory_from_text内部调用了大模型如果这个调用频繁执行会增加不少延迟和费用。更稳妥的方案是只在用户消息里出现明显偏好信号时才调用解析器例如包含“我喜欢”“不要”“预算”“想买”等关键词时触发。你也可以用规则先做一次粗筛再决定是否需要大模型深入抽取。6.6 演示入口 run_demo.py# 文件路径agent-memory-demo/run_demo.py from agent import chat_with_agent, end_session_summary from memory_store import MemoryStore if __name__ __main__: user_id user_1001 # 第一次对话用户表达偏好 reply1 chat_with_agent(user_id, 我想买个书架白色简约风的预算三百左右。) print(Agent 回复1, reply1) # 模拟浏览行为更新上下文 store MemoryStore() ctx store.get_context(user_id) ctx[last_viewed_product] 简约白色书架 5 层 store.set_context(user_id, ctx) # 第二次对话用户修正偏好 reply2 chat_with_agent(user_id, 算了预算提高到五百白色改成原木色吧。) print(Agent 回复2, reply2) # 第三次对话模拟隔天用户回来验证记忆是否跨会话生效 reply3 chat_with_agent(user_id, 还记得我之前想买什么吗) print(Agent 回复3, reply3) # 打印最终存储的用户画像便于检查 print(\n用户画像, store.get_user_profile(user_id))7. 运行结果与效果验证7.1 运行方式在项目根目录执行python run_demo.py7.2 预期效果分析正常运行时你应该能看到以下现象第一轮回复会针对“白色书架、预算三百”给出推荐。第二轮回复会感知到预算和颜色变化并给出更新后的推荐。第三轮回复中Agent 应该能主动说出“您之前想买一个原木色的书架预算约五百元”之类的话。这就证明了记忆已经跨会话生效Agent 在第三次对话中依然记得第二次修正后的信息。程序最后会打印出用户的完整画像例如{ shopping_goal: 书架, preferred_style: 简约风, preferred_color: 原木色, budget: 500 }注意preferred_color最终应该是“原木色”而不是“白色”因为第二轮对话里我们通过update_user_profile覆盖了旧值。如果最终画像里两个颜色同时存在说明你的记忆写入逻辑可能没有做合并覆盖需要检查set_user_profile的实现。7.3 如何判断成功判断记忆系统是否正常工作可以看三个点跨会话一致性关闭程序后重新运行用户数据仍然能从 Redis 里读到。修改覆盖正确用户修正后的偏好能覆盖旧偏好不产生矛盾记忆。Prompt 组装正确如果你在build_memory_prompt里加一个print(memory_prompt)会看到组装后的记忆描述里包含用户画像和上下文而不是空字符串。7.4 验证记忆持久化你可以单独用 Redis 命令来查看存储的数据redis-cli KEYS user:user_1001:* GET user:user_1001:profile如果返回了 JSON 字符串说明数据确实写入 Redis 了。这一步是验证记忆系统是否工作的最直接方式。8. 常见问题与排查思路Agent Memory 开发中很多问题看着像“大模型不够聪明”实际是记忆系统的数据链路出了问题。下面按高频到低频列出排查表。问题现象可能原因排查方式解决方案Agent 完全记不住用户说过的话记忆未写入 Redis 或 Prompt 未注入检查 Redis Key 是否存在检查build_memory_prompt返回内容在代码里打日志打印组装后的 Prompt用户改了偏好Agent 仍按旧偏好回答更新逻辑是 append 而不是覆盖查看user:{id}:profile的 JSON 是否同时存在新旧值使用 profile 合并更新逻辑同名字段直接覆盖Agent 回答时上下文爆炸token 开销大把所有历史记录全量塞进 Prompt检查 System Prompt 长度只将提炼后的结构化记忆注入而不是原始聊天记录Redis 中数据量持续增长未设置过期时间长期会话 key 堆积查看INFO keyspace观察 key 数量对会话级记忆设置 TTL定期清理大模型返回信息抽取格式错误部分 API 不支持response_format或模型不擅长 JSON 输出打印解析前原始返回内容用try...except兜底或改用开源本地小模型做抽取程序能跑但跨会话不生效重启程序后 Redis 数据丢失检查 Redis 持久化配置生产环境开启 AOF 或 RDB 持久化连接 Redis 报错密码未配置或网络隔离查看连接异常堆栈配置正确的 Redis 密码和访问地址在排查记忆问题时最推荐的方式是在 Prompt 组装和记忆写入两处都加日志。如果你能清楚看到“用户输入被解析成了什么”“写入了什么字段”“组装进 Prompt 时长什么样”那么问题基本能定位到具体链路而不是在大模型和 Redis 之间反复猜测。9. 最佳实践与工程建议9.1 记忆内容需要结构化不要把原始聊天记录当作记忆直接存储。原始记录噪声太多还会导致 token 浪费。更合理的做法是先从对话里提炼出结构化的画像和偏好再存入 Redis。这样存储体积小后续检索快且不会把互相矛盾的原始表达同时推给模型。一个用户的记忆体可以这样划分维度基础属性性别、年龄段、城市、会员等级。偏好属性颜色偏好、风格偏好、价格带、品牌偏好。行为属性最近浏览品类、加购商品、历史订单摘要。状态属性当前购物目标、当前会话进度、待确认事项。9.2 记忆修改需要版本意识用户在真实场景里经常改变主意。你需要在更新记忆时具备“覆盖”概念同时保留必要的历史轨迹。比如用户把预算从三百提高到五百画像里的budget字段应该直接变成 500而不是在数组里加一条“用户说预算五百”。如果后续想分析用户的决策变化可以单独维护一个memory_changelog表记录每次修改的时间、旧值和新值。9.3 管理好过期时间和内存不用给所有记忆设置永久 TTL。用户画像可以长期保留但会话摘要通常保留几小时短期上下文保留十几分钟就足够了。Redis 默认有过期策略善用EXPIRE可以让系统自动清理过期数据。如果长期不清理随着用户量增长Redis 内存会持续膨胀最终影响整体性能。9.4 注意隐私与安全边界记忆系统中存储的往往是用户最私密的信息比如家庭住址、偏好、消费能力。这里必须强调几条底线明确告知用户哪些信息会被记录并支持用户查看和删除自己的记忆。不要在记忆里存储明文密码、支付信息、身份证号等高敏数据。对 Redis 设置密码生产环境禁止开放公网访问。删除用户账号时同步调用clear_user_memory清除所有记忆数据。9.5 评估记忆系统需要单独设计评测集很多人以为记忆系统做完就完了实际上它需要一套评测方法。建议准备一组包含以下场景的测试用例用户表达新偏好系统能正确写入。用户修改旧偏好系统能正确覆盖。隔天再问Agent 能记住关键信息。多用户并行数据不串号。这种评测集不需要很庞大二十条覆盖核心场景的用例就足够支撑迭代了。每次修改代码后跑一遍评测集比你手动点一百次对话框更高效。9.6 结合向量检索升级记忆召回当用户的长期记忆超过几十条时全量注入 Prompt 不再现实。这时候需要引入向量检索把所有长期记忆向量化存入向量数据库每次对话时根据用户当前输入做相似度检索只取最相关的几条记忆注入 Prompt。这个方案适合已经跑通基础记忆体系的团队不必在一开始就引入。10. 总结与后续学习方向到什么程度算“学会了 Agent Memory”我认为不是背会了几个概念而是你能回答这几个问题用户的一句话该不该记该记成什么结构存在 Redis 还是向量库里用户改变主意时怎么安全地覆盖旧记忆新一次对话开始时哪些记忆需要被唤醒如果你能清晰回答说明你已经掌握了 Agent 记忆系统的核心设计思路。这篇文章用一个电商导购场景把记忆从概念到代码完整串了一遍。你现在可以做的是把这个最小示例跑起来然后尝试改造它把硬编码的用户 ID 改成真实登录态把记忆抽取从调用大模型改成规则与大模型混合执行把 Redis 换成你已有的缓存服务把用户画像的更新逻辑替换成更适合你业务的字段。每一步改造都会让你对这个系统有更深的理解。接下来值得深入的方向有三个第一个是向量记忆召回学习如何用 Embedding 做长期记忆的语义检索第二个是 Agent 框架中自带的 Memory 组件研究 LangChain、LlamaIndex 等框架里记忆模块的实现原理第三个是多 Agent 场景下的共享记忆比如客服和推荐系统如何共用一份用户画像。这些内容都能在掌握基础概念后自然延伸。建议把文章中的代码克隆到本地先跑通再动手改真正用起来的东西才是你自己的。