Agent 的长短期记忆系统

摘要 :大语言模型(LLM)本身是无状态(Stateless)的概率推理引擎,单次请求结束后即失去上下文。要让 Agent 具备跨会话的持续进化、个性化交互与复杂长任务规划能力,必须为其构建一套类脑的长短期记忆系统(Memory System)

许多开发者对 Agent 记忆的理解仅停留在"把历史聊天记录塞进 Prompt"或"把对话存进向量数据库做 RAG"。这种粗放的做法会导致上下文迅速溢出、记忆检索噪声巨大、知识冲突以及严重的灾难性遗忘。

本文将系统剖析 Agent 记忆系统的核心工程架构:

  1. 长短期记忆系统怎么做? 认知科学记忆模型(Working / Episodic / Semantic Memory)在大模型上的架构映射;

  2. 记忆是怎么存的? 键值缓存、向量库、知识图谱与分层树状存储的物理与逻辑 Schema 设计;

  3. 粒度是多少? 从原始 Token、消息轮次(Turn)、原子命题(Atomic Proposition)到会话摘要与用户画像的层级拆解;

  4. 记忆怎么用? 记忆抽取沉淀、三维检索打分(时效性、重要性、相似度)、艾宾浩斯遗忘曲线、冲突消解与动态 Prompt 注入;

  5. 主流框架对比:Stanford Generative Agents、MemGPT(Letta)与 Mem0 架构剖析;

  6. 生产级代码实战:一套开箱即用、包含完整记忆生命周期的 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 存储介质全景选型

  1. 键值与内存存储(Redis / In-Memory):用于维护短期会话状态、会话锁、近期 Message 队列,提供亚毫秒级的读写性能。

  2. 向量数据库(Qdrant / Milvus / Pgvector):存储情景记忆的文本分块与高维向量,用于支持非结构化文本的语义相似度检索(Dense Retrieval)。

  3. 关系型与文档数据库(PostgreSQL / SQLite):存储结构化元数据(时间戳、用户 ID、会话 ID、引用计数、重要度评分)以及用户 Profile。

  4. 知识图谱(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,将一段多轮对话解构为满足以下三个条件的原子事实列表:

  1. 单点事实性(Atomic):每个命题只阐述一个独立的、不可分割的事实。

  2. 指代消解(Coreference Resolution):将"他"、"该工具"、"之前提到的方案"替换为确切的名词。

  3. 自包含性(Self-contained):该命题脱离原始对话后,任何人阅读依然能明确理解其完整含义。

    [原始多轮对话片段]
    User: "我最近在用那个写微服务的框架,就是 Go 语言很火的那个,感觉它的中间件设计挺好。"
    Agent: "您指的是 Gin 框架还是 Go-Zero?"
    User: "Gin。我们团队准备把它定为 Q4 的统一标准。"

    复制代码
               │  调用 LLM 进行原子命题解构与指代消解
               ▼

    [提取沉淀的原子命题列表 (Atomic Propositions)]

    1. 用户正在使用 Go 语言的 Gin 框架进行微服务开发。
    2. 用户对 Gin 框架的中间件设计评价良好。
    3. 用户团队计划在 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)]
"用户正在主导高并发、高可用架构的稳定性治理,重点关注存储与消息队列中间件调优。"
  1. 触发时机:当近期新增记忆的重要性得分累加超过阈值(如累计达到 50 分),或处于系统闲时。

  2. 生成高阶提问:Agent 扫描最近的 50 条记忆,向自身发问:"根据这些最近的事件,能够归纳出关于该用户的哪 3 个最重要的核心结论/宏观画像?"

  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_searcharchival_memory_insert 工具自主翻阅与持久化归档。

5.3 Mem0(混合图向量记忆范式)

  • 核心贡献:将传统的 RAG 升级为"向量检索 + 图拓扑关联 + 自动事实抽取"的三合一架构。在写入数据时自动提取实体三元组并与现有节点关联,检索时同时拉取语义相近的事实以及与其相连的实体子图。

六、 生产级 Agent 记忆系统端到端代码实战

下面提供一个使用纯 Python 编写的生产级 Agent 记忆系统完整实现。

该实现包含:

  1. 工作内存(Working Memory):带 Token 限制的滑动窗口与对话栈;

  2. 原子命题抽取器(Proposition Extractor):将对话解构成原子事实;

  3. 长期情景记忆库(Episodic Store):支持余弦相似度、时间衰减与重要性三维加权检索;

  4. 统一记忆调度引擎(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) :通过强化学习与隐式状态,模型内生状态自演化│
└─────────────────────────────────────────────────────────────────────────┘

从短期工作台的滑动窗口,到长期情景记忆的三维打分(相关度、时效性、重要性),再到以原子命题为核心的精细切分,构建一套健壮、自愈、可解释的记忆系统,是大模型从"单次问答工具"进化为"具备长期伙伴关系的超级智能体"的核心基石。

相关推荐
北落L16 分钟前
Embedding:从 Token 到向量表示
llm
前端的阶梯17 分钟前
AI Agent 全景知识基础
人工智能
OpenMiniServer20 分钟前
基因的演化动力学——从复制、变异到生命复杂性的形成
人工智能
stuartevil22 分钟前
AI图生视频常见坑:参考图风格不一致怎么解决
人工智能·深度学习·音视频
prog_610326 分钟前
【笔记】cllama:搜罗万象当LLM api server测qwen3.8:flash-next
笔记·大语言模型·agent·vibe-coding·qwen3.8-flash
星核0penstarry28 分钟前
HICOOL 2026深度解读:从四大仪式看北京硬科技生态的底层逻辑
大数据·人工智能·科技·ai·创业创新·ai编程
aichitang202428 分钟前
快乐泛函每一天:希尔伯特空间中的最佳逼近与正交投影定理
人工智能·考研·算法·ai·面试·泛函分析
Python大数据分析@30 分钟前
如何评价openworker办公agent?
人工智能
H03111698531 分钟前
AI任务不中断:支持离线与关机后继续运行的几款工具
人工智能