系列: 100 天系统学习 AI Agent 开发
当前阶段: Agent 基础与环境搭建
今日目标: 搞懂短期记忆与长期记忆的核心差异,建立记忆治理机制。

AI Agent 大模型 Agent开发 LangGraph

很多刚接触 Agent 开发的同学,在加上数据库之后都会有一种错觉:“我的 Agent 终于拥有长期记忆了,它可以记住一切!”

但实操下来往往会遇到这种尴尬场景:学习助手如果每次都问“你学到第几天了”,会显得很智障;可如果它把你随口抱怨的一句“我最近不想学 Python”永久保存,几个月后还在强行给你推 Java 教程,又会显得固执且不可理喻。

“记住一切”听起来很贴心,在工程实现上其实非常危险。

问题不在于有没有记忆,而在于:什么信息该记?保存多久?发生冲突听谁的?谁有权限修改? 今天,我们就来拆解 Agent 的记忆系统。


💡 核心认知:别把聊天记录等同于记忆

很多新手有个误区,觉得放在内存里的叫短期记忆,写进 MySQL/向量数据库里的就叫长期记忆。其实根本不是一回事。真正的区别在于作用域和治理策略。

现在的我,在架构上至少会把记忆拆成这三层:

层次 服务范围 典型内容 生命周期与治理
工作状态 (State) 当前一次任务 已完成的步骤、工具返回的结果、待确认的动作 任务结束即可清理或归档,用完即弃
短期记忆 (Short-term) 当前上下文线程 代词指代(“它”是谁)、用户刚补充的参数、本轮对话摘要 随线程存在,超出上下文窗口可压缩
长期记忆 (Long-term) 跨会话 / 全局 稳定的用户偏好、明确的目标、经确认的事实 需长久落盘,但必须可更新、可过期、可删除

把一整段废话连篇的聊天记录无脑塞进向量数据库,不叫长期记忆,那叫制造上下文噪声和隐私负担。


🛠️ 实战拆解:一个学习 Agent 该怎么存信息?

我以咱们这个「学习助手」为例,盘点了一份记忆分类草案。大家在做自己的业务 Agent 时,可以直接套用这个逻辑来梳理需求:

提取到的信息 记忆类型 写入条件 过期或修正规则(极重要)
当前正在讨论“Day 008” 短期记忆 会话开始 会话结束即丢弃
本轮写文章还缺一个示例 工作状态 任务被 Agent 拆解后 示例补齐后立即删除
用户明确目标是完成100天 长期事实 用户明确确认 永久有效,直到用户主动修改
常用语言为 Python 长期偏好 多次高频出现 / 主动确认 90 天未提及后,使用前需再确认
本轮“联网查询”工具超时报错 工作状态 工具调用失败 写入系统 Log,绝不当做用户偏好
用户的薄弱点是错误处理 长期推断 评测数据支持,且必须标明是“推断” 新一轮评测后可被直接覆盖
密码、密钥或身份证信息 🛑 禁止写入 规则引擎强制拦截 永远不进入记忆系统

这里隐藏了一个极其重要的工程细节:必须把“事实”和“推断”分开。
用户自己说的叫“事实”;系统根据几道错题推测出来的叫“推断”。推断出来的东西,必须保存证据和置信度,且优先级永远低于事实。


⚙️ 一条靠谱的记忆写入流水线

为了避免把垃圾数据和敏感数据写入记忆,在落盘前我们需要一条标准的流水线:

对话或任务事件

大模型提取候选记忆

是否必要且允许保存?
(敏感词/价值判断)

仅留在当前上下文

去重与冲突检查

用户确认或规则验证

带上来源、时间、TTL 落盘

检索时按作用域过滤

到期、修正或删除

如果你现在就想动手敲代码,别急着一上来就搞向量数据库(Vector DB)。先用一个普通的数据结构把约束字段定好。在 Python 里,你的记忆记录实体(Entity)至少应该是这样的:

from dataclasses import dataclass
from datetime import datetime
from typing import Literal

@dataclass
class MemoryRecord:
    user_id: str
    namespace: Literal["profile", "learning", "preference"] # 隔离命名空间
    key: str
    value: str
    source: str               # 来源:用户主动说 / 系统推测
    created_at: datetime
    confidence: float         # 置信度:推测的结果置信度要调低
    expires_at: datetime | None = None  # TTL:很多记忆是会过期的
    status: Literal["active", "superseded", "deleted"] = "active" # 软删除机制

在组装 Prompt 时,先按 namespace 隔离,再按相关性提取,最后检查 statusexpires_at


🤔 踩坑复盘:我目前还在纠结的边界

在设计这套系统时,我发现最棘手的问题是冲突解决机制

偏好变了(比如以前喜欢 Python,现在喜欢 Go),我们可以直接用新记录覆盖老记录。但事实冲突却不能简单以“最新”为准。
比如:用户今天在聊天里吹牛说自己“Day 20 已经做完了”,但底层的进度系统查出来他只打卡到了 Day 8。这个时候 Agent 到底信谁?

我目前的暂定解法是:不同来源的信息要设定“可信等级”(系统 API 数据 > 用户随口说的数据)。遇到冲突时,Agent 不应该悄悄覆盖数据,而是把差异抛出来,向用户发起确认。

记忆系统的温度,不在于它像个舔狗一样每次都说“我记得你”,而在于它永远不会拿错误、过期或不该保存的信息,自作主张地替用户做决定。


📦 今日学习小结

老规矩,梳理成我们的 JSON 知识拼图,作为日后复盘的线索:

{
    "day": 8,
    "topic": "记忆系统入门:短期记忆、长期记忆到底差在哪",
    "why_it_matters": "毫无治理的全局记忆会变成上下文噪声和隐私负担。必须区分工作状态、短期上下文和长期记忆。",
    "today_task": "定义了记忆实体的核心字段,明确了记忆写入流水线中的拦截、去重和过期规则。",
    "pitfall": "将大模型推断的结论直接等同于用户事实。推断数据必须附带置信度且允许被事实覆盖。",
    "next_question": "既然短期和长期记忆理清了,明天该看看主流框架(比如 LangGraph 的 Checkpointer)是怎么在工程上落地这套机制的?"
}

✅ 读者自查清单:

  • 你存记忆的时候,加上创建时间和 expires_at(过期时间)了吗?
  • 你的系统能区分出“用户事实”和“模型推断”吗?
  • 检索记忆时,你是全量丢给大模型,还是做过业务过滤了?
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐