摘要 :大语言模型(LLM)本身是无状态(Stateless)的概率推理引擎,单次请求结束后即失去上下文。要让 Agent 具备跨会话的持续进化、个性化交互与复杂长任务规划能力,必须为其构建一套类脑的长短期记忆系统(Memory System)。
许多开发者对 Agent 记忆的理解仅停留在"把历史聊天记录塞进 Prompt"或"把对话存进向量数据库做 RAG"。这种粗放的做法会导致上下文迅速溢出、记忆检索噪声巨大、知识冲突以及严重的灾难性遗忘。
本文将系统剖析 Agent 记忆系统的核心工程架构:
长短期记忆系统怎么做? 认知科学记忆模型(Working / Episodic / Semantic Memory)在大模型上的架构映射;
记忆是怎么存的? 键值缓存、向量库、知识图谱与分层树状存储的物理与逻辑 Schema 设计;
粒度是多少? 从原始 Token、消息轮次(Turn)、原子命题(Atomic Proposition)到会话摘要与用户画像的层级拆解;
记忆怎么用? 记忆抽取沉淀、三维检索打分(时效性、重要性、相似度)、艾宾浩斯遗忘曲线、冲突消解与动态 Prompt 注入;
主流框架对比:Stanford Generative Agents、MemGPT(Letta)与 Mem0 架构剖析;
生产级代码实战:一套开箱即用、包含完整记忆生命周期的 Python 端到端工程实现。
前言:无状态模型与有状态智能体的鸿沟
大语言模型(LLM)的本质是一个基于 Transformer 架构的自回归函数:输入一段 Token 序列,预测下一个 Token 的概率分布。一旦 HTTP 请求断开,GPU 显存释放,模型就会瞬间"失忆"。
但在实际业务中,我们期望的 Agent 往往需要扮演长期伴随的智能助手、私人理财顾问或自主软件工程师:
-
用户说 :"我下周要去北京出差,帮我订一张我常坐的航班。"------Agent 必须记得用户的出行偏好与历史航司偏好。
-
用户说 :"继续我们上个月讨论的项目架构,第二模块改用 Rust 重构。"------Agent 必须调取数周前的技术决策记录,而不是要求用户重新复述一遍背景。
如果单纯依赖长上下文窗口(Long Context Window),将所有历史记录一股脑塞入 Prompt,不仅会带来高昂的 Token 计费和推理延迟,还会引发严重的"中间丢失(Lost in the Middle)"与注意力稀释问题。
因此,构建一套分层、自进化、低延迟的外部记忆系统,是让 LLM 从"玩具 Demo"迈向"生产级智能体"的核心分水岭。
┌────────────────────────────────────────────────────────────────────────┐
│ Agent 记忆系统全生命周期 │
└────────────────────────────────────────────────────────────────────────┘
│
1. 记忆感知与抽取 用户对话/环境反馈 ➔ 信息清洗 ➔ 实体/原子命题抽取 ➔ 重要度评估
│
2. 结构化存储沉淀 工作内存(Buffer) ➔ 向量索引(Vector) ➔ 实体图谱(Graph) ➔ 抽象画像(Profile)
│
3. 动态检索与唤醒 三维相关度打分 (语义相似度 + 时间衰减 + 重要性) ➔ 混合多路召回
│
4. 反思与固化更新 多轮记忆反思(Reflection) ➔ 冲突检测与覆盖 ➔ 艾宾浩斯遗忘衰减
│
5. 上下文组装应用 Token 预算裁剪 ➔ 记忆结构化注入 System Prompt ➔ LLM 执行决策
一、 长短期记忆系统怎么做的?(认知架构与技术映射)
人类的记忆系统经过了数百万年的生物进化,形成了高度精妙的分层协作机制。当前主流的 Agent 记忆系统,在架构设计上深度借鉴了认知心理学经典的 Atkinson-Shiffrin 记忆模型 与 Tulving 多重记忆系统理论。
┌─────────────────────────────────────────────────────────────────────────────┐
│ 认知心理学记忆模型 vs LLM Agent 技术映射 │
├──────────────────┬─────────────────────────────┬────────────────────────────┤
│ 认知记忆分类 │ 人类大脑机制 │ LLM Agent 对应技术实现 │
├──────────────────┼─────────────────────────────┼────────────────────────────┤
│ 感官记忆 │ 毫秒级保留视觉/听觉原始信号 │ 多模态输入缓冲区 / Token │
│ (Sensory Memory) │ │ 序列暂存区 │
├──────────────────┼─────────────────────────────┼────────────────────────────┤
│ 工作/短期记忆 │ 容量有限(7±2块),当前思考所 │ LLM Context Window、KV │
│ (Working Memory) │ 需的活跃信息 │ Cache、Scratchpad、当前会话│
├──────────────────┼─────────────────────────────┼────────────────────────────┤
│ 长期情景记忆 │ 个人亲身经历的特定时空事件 │ 向量数据库、多轮历史对话 │
│ (Episodic Memory)│ (带时间戳、场景、因果上下文)│ 日志、会话事件流 (Event DB)│
├──────────────────┼─────────────────────────────┼────────────────────────────┤
│ 长期语义记忆 │ 去除时空情境的通用知识、概念│ 结构化知识图谱、用户画像表 │
│ (Semantic Memory)│ 、事实与规则 (如常识、偏好) │ (User Profile)、精炼指标库 │
├──────────────────┼─────────────────────────────┼────────────────────────────┤
│ 程序/技能记忆 │ 无意识掌握的技能与操作流程 │ 工具定义 (Tool Definitions)│
│ (Procedural) │ (如骑车、写代码的固定范式) │ 、Few-Shot 提示词、SFT 权重│
└──────────────────┴─────────────────────────────┴────────────────────────────┘
1.1 短期记忆(Short-term / Working Memory)
短期记忆是大模型正在进行推理与决策的"工作台"。
-
载体 :当前请求发送给大模型的 Context Window 以及推理引擎中的 KV Cache。
-
特点:访问速度极快(毫秒级,直接参与 Attention 矩阵计算),容量受限于上下文窗口大小(如 8K、32K、128K),生命周期仅限于当前单次请求或当前单次连续会话。
-
管理手段:
-
滑动窗口(Sliding Window):仅保留最近 N 轮对话。
-
动态摘要压缩(Context Summarization):当 Context 达到阈值(如 80%)时,后台调用小模型将早期对话浓缩为一段摘要,替换旧消息。
-
Scratchpad(临时草稿纸):供 Agent 进行 ReAct(Reasoning + Action)多步推演时暂存中间思考步骤(Thinking Chain)。
-
1.2 长期记忆(Long-term Memory)
长期记忆是存储在外部持久化介质中的庞大知识与经验库,Agent 在需要时通过检索算法按需将其"唤醒"并加载到短期工作内存中。
长期记忆在逻辑上进一步解耦为两个核心分支:
1. 情景记忆(Episodic Memory)------"发生了什么"
记录 Agent 与用户或环境交互的具体历史事件。
-
特点 :具有明确的时空属性(时间戳、地点、上下文),以"事件流"的形式存在。
-
示例:"用户在 2026 年 8 月 10 日询问了关于 PyTorch 显存优化的代码,最终采用了梯度累积方案。"
2. 语义记忆(Semantic Memory)------"规律与概念是什么"
从海量情景记忆中经过抽象、提炼、归纳后形成的泛化事实与核心认知。
-
特点:剥离了具体的单次事件细节,形成了稳定的实体属性、用户偏好与业务规则。
-
示例:"用户是一名精通 Python 的算法工程师,偏好使用 PyTorch 而非 TensorFlow,习惯深夜写代码。"
二、 记忆是怎么存的?(存储介质与数据结构 Schema)
许多团队在做 Agent 记忆时,往往只使用一个 Chroma 或 Milvus 向量库,把所有文本做 Embedding 后存进去。这种单一存储模式在实际应用中会迅速崩溃(无法按时间精确排序、无法修改错误事实、无法表示实体间复杂关系)。
生产级 Agent 记忆系统通常采用多模态混合存储架构(Polyglot Persistence Architecture)。
┌─────────────────────────────────────────┐
│ Agent 统一记忆管理引擎 │
└────────────────────┬────────────────────┘
│
┌───────────────────────────┬──────────────┴────────────┬───────────────────────────┐
▼ ▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ 热数据缓存层 │ │ 向量索引存储 │ │ 图谱拓扑存储 │ │ 结构化实体画像 │
│ (Working Store) │ │ (Embedding Store)│ │ (Graph Memory) │ │ (Entity Profile) │
├──────────────────┤ ├──────────────────┤ ├──────────────────┤ ├──────────────────┤
│ - Redis / 内存 │ │ - Qdrant / Milvus│ │ - Neo4j / Nebula │ │ - PostgreSQL / │
│ - 当前会话消息栈 │ │ - 原始情景事件 │ │ - 实体-关系-实体 │ │ JSONB 文档 │
│ - Scratchpad 草稿│ │ - 语义片段向量 │ │ - 深度关联推理 │ │ - 用户/系统画像 │
└──────────────────┘ └──────────────────┘ └──────────────────┘ └──────────────────┘
2.1 存储介质全景选型
-
键值与内存存储(Redis / In-Memory):用于维护短期会话状态、会话锁、近期 Message 队列,提供亚毫秒级的读写性能。
-
向量数据库(Qdrant / Milvus / Pgvector):存储情景记忆的文本分块与高维向量,用于支持非结构化文本的语义相似度检索(Dense Retrieval)。
-
关系型与文档数据库(PostgreSQL / SQLite):存储结构化元数据(时间戳、用户 ID、会话 ID、引用计数、重要度评分)以及用户 Profile。
-
知识图谱(Neo4j / Memgraph) :存储实体与关系的拓扑三元组
(Subject, Predicate, Object),解决跨越多个事件的长链路推理问题。
2.2 生产级记忆数据实体 Schema 设计
在数据建模上,一条合格的记忆不能仅仅是一段纯文本,必须包含完整的元数据描述(Provenance)、时空属性、认知打分与生命周期管理字段。
{
"memory_id": "mem_20260829_0981aef4",
"user_id": "usr_tech_lead_01",
"agent_id": "agent_code_assistant",
"session_id": "sess_20260829_dev",
"memory_type": "episodic",
"granularity": "atomic_proposition",
"content": "用户倾向于在 FastAPI 项目中使用 Pydantic v2 进行数据校验,因其基于 Rust 核心性能更优。",
"keywords": ["FastAPI", "Pydantic v2", "Rust", "数据校验", "技术偏好"],
"embedding": [0.0124, -0.0451, 0.0892, "... 1536 维向量 ..."],
"cognitive_metadata": {
"importance_score": 0.85,
"confidence_score": 0.95,
"emotional_valence": "neutral",
"access_count": 4,
"created_at": 1787961600,
"last_accessed_at": 1787965200,
"decay_rate": 0.05
},
"associations": {
"source_message_ids": ["msg_101", "msg_102"],
"derived_from_reflections": ["ref_20260810_01"],
"related_entities": ["ent_pydantic", "ent_fastapi"]
},
"lifecycle": {
"status": "active",
"is_pinned": false,
"expired_at": null
}
}
三、 记忆的切分粒度是多少?(从 Token 到原子事实与画像)
记忆粒度(Granularity)是决定记忆系统成败的最关键参数。粒度过粗会导致检索噪声泛滥,粒度过细则会导致语义碎片化、丧失上下文背景。
3.1 记忆粒度五层金字塔模型
▲
╱ ╲
╱ ╲
╱ 1. ╲ 用户/Agent 核心画像 (Persona Profile)
╱ 画像 ╲ (极高抽象度,全局指导 System Prompt,如:"用户是资深架构师")
╱─────────╲
╱ 2. 概念 ╲ 语义概念与规则 (Semantic Rules / Knowledge Graph)
╱ 与图谱三元组╲ (如:(FastAPI, supports, AsyncIO))
╱─────────────────╲
╱ 3. 原子命题 ╲ 原子事实 (Atomic Propositions / Factlets)
╱ (Atomic Facts) ╲ (自包含、单事实、无代词,如:"用户偏好使用 PostgreSQL")
╱───────────────────────╲
╱ 4. 会话摘要 ╲ 会话/事件级摘要 (Session Summaries)
╱ (Session Summaries) ╲ (如:"2026-08-10 用户与 Agent 共同排查了数据库死锁")
╱─────────────────────────────╲
╱ 5. 原始对话轮次 ╲ 原始消息栈 (Raw Message Turns)
╱ (Raw Dialog Turns) ╲ (包含用户与模型逐字逐句的原始交互记录)
───────────────────────────────────
3.2 粒度权衡与对比矩阵
| 记忆粒度层级 | 典型 Token 长度 | 存储与索引形式 | 核心优势 | 核心缺陷与局限 |
|---|---|---|---|---|
| L1: 核心画像 (Profile) | 50 ~ 200 | Key-Value / JSON 文档 | 极低 Token 占用,全局稳定,直击用户核心偏好 | 缺乏细节与上下文,无法支撑复杂历史追溯 |
| L2: 语义图谱 (Graph Triples) | 10 ~ 30 | 图数据库实体/边 | 支持跨事件多跳关联推理,关系清晰 | 构建与更新成本高,对非结构化表达兼容差 |
| L3: 原子命题 (Propositions) | 20 ~ 60 | 向量数据库 + 标量元数据 | 检索精度最高,语义无稀释,指代消解完整 | 丢失部分会话发生的先后叙事因果关系 |
| L4: 会话摘要 (Summaries) | 200 ~ 500 | 关系型数据库 / 向量库 | 保留事件全貌与上下文,信息密度高 | 细节容易被概括丢失,向量检索容易模糊 |
| L5: 原始轮次 (Raw Turns) | 500 ~ 2000+ | 顺序日志 / 文本缓冲区 | 100% 原始真实,不丢失任何细节与语气 | 严重消耗 Token 窗口,注意力噪声极大 |
3.3 核心技术攻坚:原子命题(Atomic Proposition)提取算法
在先进的 Agent 记忆系统(如 Mem0、Zep)中,L3 级别的原子命题(Atomic Proposition)是长期情景记忆的最佳存储粒度。
原始对话往往包含大量口语化、代词指代(他/它/那个库)以及无关寒暄。直接向量化原始对话会导致检索极其不准。
提取规则:利用轻量级 LLM,将一段多轮对话解构为满足以下三个条件的原子事实列表:
-
单点事实性(Atomic):每个命题只阐述一个独立的、不可分割的事实。
-
指代消解(Coreference Resolution):将"他"、"该工具"、"之前提到的方案"替换为确切的名词。
-
自包含性(Self-contained):该命题脱离原始对话后,任何人阅读依然能明确理解其完整含义。
[原始多轮对话片段]
User: "我最近在用那个写微服务的框架,就是 Go 语言很火的那个,感觉它的中间件设计挺好。"
Agent: "您指的是 Gin 框架还是 Go-Zero?"
User: "Gin。我们团队准备把它定为 Q4 的统一标准。"│ 调用 LLM 进行原子命题解构与指代消解 ▼[提取沉淀的原子命题列表 (Atomic Propositions)]
- 用户正在使用 Go 语言的 Gin 框架进行微服务开发。
- 用户对 Gin 框架的中间件设计评价良好。
- 用户团队计划在 2026 年第四季度将 Gin 框架定为团队的统一开发标准。
四、 记忆是怎么用的?(检索、唤醒、遗忘与上下文注入)
有了结构化的记忆存储,Agent 在面对用户的新提问或新任务时,如何准确、高效地将相关的记忆"唤醒"并应用到决策中?
4.1 记忆检索的三维联合打分机制
不能仅依靠向量相似度(Vector Cosine Similarity)来检索记忆。例如:用户 3 年前喜欢吃苹果,但昨天刚刚明确表示"我现在对苹果过敏,只吃香蕉"。如果单纯按语义相似度检索"水果偏好",两条记录都会被召回,模型就会产生混淆。
在 Stanford 开源的著名智能体框架《Generative Agents》中,确立了经典的三维记忆联合打分机制:
Final_Score = α * Score_Relevance + β * Score_Recency + γ * Score_Importance
其中系数通常设置满足:α + β + γ = 1.0(如 0.5, 0.2, 0.3)。
┌─────────────────────────────────────────┐
│ 用户输入 Query │
└────────────────────┬────────────────────┘
│
┌─────────────────────────────────────────┼─────────────────────────────────────────┐
▼ ▼ ▼
┌───────────────────────────┐ ┌───────────────────────────┐ ┌───────────────────────────┐
│ 1. 语义相关度 (Relevance) │ │ 2. 时间衰减 (Recency) │ │ 3. 固有重要度 (Importance)│
├───────────────────────────┤ ├───────────────────────────┤ ├───────────────────────────┤
│ 计算 Query 向量与记忆向量 │ │ 基于艾宾浩斯遗忘曲线: │ │ 记忆沉淀时由 LLM 给出的 │
│ 的余弦相似度 Cosine Sim │ │ S_recency = e^(-λ * Δt) │ │ 认知权重 (0.0 ~ 1.0) │
└─────────────┬─────────────┘ └─────────────┬─────────────┘ └─────────────┬─────────────┘
│ │ │
└─────────────────────────────────────────┼─────────────────────────────────────────┘
▼
┌─────────────────────────────────────────┐
│ 综合加权得分计算 (Final Score) │
│ 排序并截取 Top-K 高价值记忆 │
└─────────────────────────────────────────┘
1. 语义相关度(Score_Relevance)
计算当前用户 Query 向量与记忆库中各候选向量的余弦相似度:
Score_Relevance = Cosine_Similarity(Vector_query, Vector_memory)
2. 时效性与时间衰减(Score_Recency)
人类大脑的遗忘遵循艾宾浩斯遗忘曲线。距离当前时间越近的记忆,其被唤醒的基础概率越高。衰减函数通常建模为指数衰减模型:
Score_Recency = e^(-λ * Δt)
-
Δt:当前时间与记忆最后一次被访问/创建时间的差值(如以天/小时为单位)。 -
λ:遗忘衰减系数(Decay Factor,通常设为0.005 ~ 0.05)。
3. 固有重要度(Score_Importance)
并非所有信息都具有同等价值。"用户说了句'早上好'"与"用户公布了自己的家庭住址或核心技术选型"重要性截然不同。 在记忆写入阶段,由 LLM 对该条信息的重要性进行离线评分(0.0 到 1.0):
-
0.1~0.3(低价值):日常寒暄、暂时的过渡性状态(如"我正在喝水")。
-
0.4~0.7(中价值):一般的业务探讨、具体任务的操作细节。
-
0.8~1.0(高价值):核心原则、长期偏好、关键安全信息、用户身份属性。
4.2 记忆固化与反思机制(Memory Reflection)
如果 Agent 只是无休止地堆积原子事实,记忆库将迅速充满冗余甚至互相矛盾的信息。
反思(Reflection)机制模拟人类在睡眠时大脑对白天的经历进行梳理与固化的过程:
[海量低阶情景记忆 (Episodic Memories)]
- 事件 1: 用户在 8月1日 优化了 MySQL 慢查询 SQL
- 事件 2: 用户在 8月3日 配置了 Redis 缓存击穿防护
- 事件 3: 用户在 8月7日 排查了 Kafka 分区再均衡延迟
│
▼ 定期触发 LLM 反思聚合 (Reflection Agent)
[高阶抽象语义记忆 (Semantic Insight)]
"用户正在主导高并发、高可用架构的稳定性治理,重点关注存储与消息队列中间件调优。"
-
触发时机:当近期新增记忆的重要性得分累加超过阈值(如累计达到 50 分),或处于系统闲时。
-
生成高阶提问:Agent 扫描最近的 50 条记忆,向自身发问:"根据这些最近的事件,能够归纳出关于该用户的哪 3 个最重要的核心结论/宏观画像?"
-
提取 Insight 写入长期存储 :将反思生成的高阶认知作为
Semantic Memory存入画像层,并与底层的子事件建立关联引用指针。
4.3 记忆冲突消解与主动遗忘(Conflict Resolution & Forgetting)
当用户的信息发生变更时,记忆系统必须具备自我修正 与覆盖更新机制,防止模型在两个互相冲突的记忆之间产生幻觉。
旧记忆: "用户使用的手机型号为 iPhone 13" (创建于 2024 年)
新输入: "我昨天刚换了华为 Mate 60"
│
▼ 执行记忆更新管道 (Memory Pipeline)
1. 实体链接: 锁定目标实体属性 "user.device.phone"
2. 语义冲突检测: 识别到同一实体的同类属性发生互斥更新
3. 状态变更:
- 旧记忆标记为 status="deprecated" 或降权
- 插入新记忆: "用户当前使用的手机型号为 华为 Mate 60"
4.4 动态 Prompt 组装与 Token 预算控制
检索出的记忆不能无限量塞入 Prompt。生产级 Agent 必须具备 Token 预算管理器(Token Budget Manager):
┌────────────────────────────────────────────────────────────────────────┐
│ 总 Context Window (e.g. 8192 Tokens) │
├────────────────────────────────────────────────────────────────────────┤
│ 1. 核心系统角色指令 (System Prompt) │ 预留 1000 Tokens (固定) │
├──────────────────────────────────────────────┼─────────────────────────┤
│ 2. 长期记忆注入区 (Long-term Profile & Context) │ 限制 1500 Tokens (动态) │
│ - 用户核心画像 (Profile) │ │
│ - 检索召回的 Top-K 命题 (Propositions) │ │
├──────────────────────────────────────────────┼─────────────────────────┤
│ 3. 短期工作内存区 (Short-term Working Dialog) │ 限制 3500 Tokens (滑动) │
│ - 最近 N 轮对话原始记录 │ │
├──────────────────────────────────────────────┼─────────────────────────┤
│ 4. 模型生成预留区 (Max Completion Tokens) │ 预留 2192 Tokens (生成) │
└──────────────────────────────────────────────┴─────────────────────────┘
五、 经典开源记忆框架深度拆解
当前开源社区涌现出了多个优秀的 Agent 记忆框架,其核心架构思想极具借鉴意义:
5.1 Stanford Generative Agents(记忆流与反思树)
- 核心贡献:首次提出记忆流(Memory Stream)概念,将所有观察转化为包含时间戳的事件列表;首创了"时效性 + 重要性 + 相似度"三维打分公式,以及层次化的反思树(Reflection Tree)架构。
5.2 MemGPT / Letta(操作系统分层虚拟内存机制)
-
核心贡献:将计算机操作系统的虚拟内存管理(Virtual Memory Paging)思想引入大模型:
-
Core Memory(相当于 RAM) :始终驻留在 System Prompt 中的关键信息(如 Human Persona, Agent Persona),Agent 可通过调用内置 Tool(如
edit_core_memory)自主主动修改该区域。 -
Recall Memory(相当于内存缓存):按时间顺序排列的历史对话。
-
Archival Storage(相当于磁盘硬盘) :无限容量的外部向量存储,Agent 可通过
archival_memory_search和archival_memory_insert工具自主翻阅与持久化归档。
-
5.3 Mem0(混合图向量记忆范式)
- 核心贡献:将传统的 RAG 升级为"向量检索 + 图拓扑关联 + 自动事实抽取"的三合一架构。在写入数据时自动提取实体三元组并与现有节点关联,检索时同时拉取语义相近的事实以及与其相连的实体子图。
六、 生产级 Agent 记忆系统端到端代码实战
下面提供一个使用纯 Python 编写的生产级 Agent 记忆系统完整实现。
该实现包含:
-
工作内存(Working Memory):带 Token 限制的滑动窗口与对话栈;
-
原子命题抽取器(Proposition Extractor):将对话解构成原子事实;
-
长期情景记忆库(Episodic Store):支持余弦相似度、时间衰减与重要性三维加权检索;
-
统一记忆调度引擎(Unified Memory Engine):实现端到端的记忆提取、持久化、打分检索与 System Prompt 动态注入。
6.1 核心代码实现
import time
import math
import uuid
from typing import List, Dict, Any, Optional
from dataclasses import dataclass, field
# ==================== 1. 记忆数据模型定义 ====================
@dataclass
class MemoryItem:
memory_id: str
content: str
embedding: List[float]
importance: float # 0.0 ~ 1.0
created_at: float # 时间戳
last_accessed_at: float
metadata: Dict[str, Any] = field(default_factory=dict)
# ==================== 2. 工具函数与向量计算 ====================
def mock_embedding(text: str, dim: int = 8) -> List[float]:
"""模拟文本向量化生成 (生产环境替换为 OpenAI text-embedding-3 或 BGE-M3)"""
hash_val = hash(text)
raw_vec = [math.sin(hash_val + i) for i in range(dim)]
norm = math.sqrt(sum(x * x for x in raw_vec))
return [x / norm for x in raw_vec] if norm > 0 else raw_vec
def cosine_similarity(v1: List[float], v2: List[float]) -> float:
"""计算余弦相似度"""
dot = sum(a * b for a, b in zip(v1, v2))
norm_a = math.sqrt(sum(a * a for a in v1))
norm_b = math.sqrt(sum(b * b for b in v2))
if norm_a == 0 or norm_b == 0:
return 0.0
return dot / (norm_a * norm_b)
# ==================== 3. 长期情景记忆引擎 (带三维打分) ====================
class LongTermMemoryStore:
def __init__(self, decay_rate: float = 0.01, alpha: float = 0.5, beta: float = 0.2, gamma: float = 0.3):
self.memories: List[MemoryItem] = []
self.decay_rate = decay_rate # 艾宾浩斯时间衰减系数
self.alpha = alpha # 语义相关度权重
self.beta = beta # 时效性权重
self.gamma = gamma # 固有重要性权重
def add_memory(self, content: str, importance: float = 0.5, metadata: Optional[Dict[str, Any]] = None):
now = time.time()
vec = mock_embedding(content)
item = MemoryItem(
memory_id=f"mem_{uuid.uuid4().hex[:8]}",
content=content,
embedding=vec,
importance=max(0.0, min(1.0, importance)),
created_at=now,
last_accessed_at=now,
metadata=metadata or {}
)
self.memories.append(item)
print(f"[长期记忆沉淀] ID: {item.memory_id} | 重要度: {importance} | 内容: {content}")
def retrieve(self, query: str, top_k: int = 3) -> List[MemoryItem]:
if not self.memories:
return []
now = time.time()
query_vec = mock_embedding(query)
scored_items = []
for item in self.memories:
# 1. 语义相似度计算 (归一化到 0~1)
sim = cosine_similarity(query_vec, item.embedding)
sim_score = (sim + 1.0) / 2.0 # 映射从 [-1, 1] 到 [0, 1]
# 2. 时间衰减得分 (指数衰减)
delta_hours = (now - item.last_accessed_at) / 3600.0
recency_score = math.exp(-self.decay_rate * delta_hours)
# 3. 固有重要度得分
importance_score = item.importance
# 4. 三维加权总得分
final_score = (
self.alpha * sim_score +
self.beta * recency_score +
self.gamma * importance_score
)
scored_items.append((final_score, item))
# 按综合得分降序排序
scored_items.sort(key=lambda x: x[0], reverse=True)
top_results = []
for score, item in scored_items[:top_k]:
item.last_accessed_at = now # 唤醒后刷新访问时间
top_results.append(item)
return top_results
# ==================== 4. 短期工作内存 (Working Memory) ====================
class WorkingMemory:
def __init__(self, max_turns: int = 5):
self.max_turns = max_turns
self.messages: List[Dict[str, str]] = []
def add_turn(self, role: str, content: str):
self.messages.append({"role": role, "content": content})
# 维持滑动窗口
if len(self.messages) > self.max_turns * 2:
self.messages = self.messages[-(self.max_turns * 2):]
def get_messages(self) -> List[Dict[str, str]]:
return self.messages
# ==================== 5. 统一 Agent 记忆管理中枢 ====================
class ProductionAgentMemorySystem:
def __init__(self, user_persona: str):
self.user_persona = user_persona # 核心静态画像
self.working_memory = WorkingMemory(max_turns=3)
self.long_term_memory = LongTermMemoryStore(decay_rate=0.05)
def extract_atomic_propositions_and_save(self, user_input: str, agent_reply: str):
"""
模拟调用轻量模型提取原子命题事实并沉淀入库
(生产环境中通过特定 Prompt 交由小模型如 Qwen-2.5-7B 执行抽取)
"""
# 模拟规则抽取 (示例)
if "偏好" in user_input or "喜欢" in user_input or "习惯" in user_input:
self.long_term_memory.add_memory(
content=f"用户表达了偏好事实:{user_input}",
importance=0.9,
metadata={"category": "user_preference"}
)
elif "项目" in user_input or "技术栈" in user_input:
self.long_term_memory.add_memory(
content=f"用户当前技术栈背景:{user_input}",
importance=0.8,
metadata={"category": "tech_stack"}
)
def build_augmented_prompt(self, current_query: str) -> str:
"""
核心装配流水线:根据当前 Query 检索记忆并动态拼装完整的上下文
"""
# 1. 唤醒相关的长期情景记忆
retrieved_memories = self.long_term_memory.retrieve(current_query, top_k=2)
memory_snippets = "\n".join([f"- {m.content}" for m in retrieved_memories]) if retrieved_memories else "无相关历史记忆"
# 2. 组装增强的 System Prompt
system_prompt = f"""你是一位具备持续记忆与进化能力的智能技术顾问。
【用户基础认知画像】
{self.user_persona}
【从长期记忆中唤醒的相关事实与历史背景】
{memory_snippets}
请结合上述历史记忆与短期对话上下文,以精准、连贯、专业的语气回答用户。
"""
return system_prompt
def step(self, user_query: str) -> str:
"""Agent 单步执行回路"""
print(f"\n==================== 用户新输入: '{user_query}' ====================")
# 1. 检索记忆并构造 System Prompt
augmented_prompt = self.build_augmented_prompt(user_query)
print("--- [动态组装生成的 System Prompt] ---")
print(augmented_prompt.strip())
# 2. 模拟 LLM 推理生成
simulated_reply = f"已收到您的提问。基于对您的技术习惯与历史记忆的了解,我建议按照规范方案执行。"
# 3. 更新短期工作内存
self.working_memory.add_turn("user", user_query)
self.working_memory.add_turn("assistant", simulated_reply)
# 4. 异步抽取沉淀原子记忆
self.extract_atomic_propositions_and_save(user_query, simulated_reply)
return simulated_reply
# ==================== 6. 端到端运行与生命周期演练 ====================
if __name__ == "__main__":
print("=== 初始化生产级 Agent 记忆系统 ===")
user_profile = "用户姓名:张工;职业:后端首席架构师;专注于分布式高并发与架构治理。"
agent_memory = ProductionAgentMemorySystem(user_persona=user_profile)
# 会话 1:沉淀核心技术偏好
agent_memory.step("我们在新项目中更偏好使用 Rust 和 Go,请以后回答问题都以此为基准。")
# 会话 2:沉淀业务背景
agent_memory.step("我们当前负责的电商微服务项目目前正在进行 Q4 性能重构。")
# 会话 3:跨越一段时间后的新提问(触发长期记忆的精准唤醒)
agent_memory.step("帮我写一个高并发订单校验模块的代码骨架。")
七、 生产落地避坑指南与最佳实践
在将 Agent 记忆系统部署至大规模生产环境时,有四个高频"深水坑"必须防范:
1. 记忆幻觉与错误级联(Memory Poisoning)
-
风险:如果 Agent 在某一轮对话中产生了幻觉,而记忆抽取模块未经校验直接将这段"虚假事实"沉淀为长期记忆,后续所有会话都将基于该错误事实进行推理,产生严重的连锁中毒。
-
防范:
-
置信度校验(Confidence Filtering):仅允许由用户明确声明的事实(User-stated Facts)直接写入长期记忆;对 Agent 自行推论的内容,设定极低的初始权重。
-
引入人工审核与修正 API:在客户端 UI 上提供"记忆管理仪表盘(Memory Center)",允许用户查看、编辑或一键删除 Agent 记录的个人偏好。
-
2. GDPR、合规与"被遗忘权"(Right to be Forgotten)
-
风险:欧盟 GDPR 及数据安全法规要求用户有权要求平台彻底清除其个人隐私数据。在向量库与图数据库混合存储中,简单的物理删除极难完全清理关联碎片。
-
防范 :在数据 Schema 中强制建立统一的
user_id索引隔离。执行删除指令时,通过事件总线(EventBus)向向量库、图数据库、关系表与 Redis 缓存同时下发原子删除指令。
3. 并发写入冲突与会话竞态(Race Condition)
-
风险:用户在多端(手机 App、Web 网页)同时向同一个 Agent 发起并发提问,导致工作内存与记忆提取管道产生写冲突与脏读。
-
防范 :基于 Redis 实现基于
session_id的分布式锁(Distributed Lock),保证单会话内部的"感知 ➔ 抽取 ➔ 写入"为严格串行流水线。
八、 总结与未来趋势
Agent 记忆系统的演进,正在彻底重塑人机交互的形式与边界:
┌─────────────────────────────────────────────────────────────────────────┐
│ Agent 记忆系统三大演进纪元 │
├─────────────────────────────────────────────────────────────────────────┤
│ 1. 原始时代 (Raw Context) :单纯依赖超长窗口滑动,缺乏结构与长期记忆 │
│ 2. 混合工程时代 (Hybrid RAG):向量库 + 图谱 + 艾宾浩斯衰减 + 虚拟内存 │
│ 3. 原生状态演进 (Stateful) :通过强化学习与隐式状态,模型内生状态自演化│
└─────────────────────────────────────────────────────────────────────────┘
从短期工作台的滑动窗口,到长期情景记忆的三维打分(相关度、时效性、重要性),再到以原子命题为核心的精细切分,构建一套健壮、自愈、可解释的记忆系统,是大模型从"单次问答工具"进化为"具备长期伙伴关系的超级智能体"的核心基石。