Day 008:Agent 记得越多越好吗?短期与长期记忆的底层逻辑
系列: 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,绝不当做用户偏好 |
| 用户的薄弱点是错误处理 | 长期推断 | 评测数据支持,且必须标明是“推断” | 新一轮评测后可被直接覆盖 |
| 密码、密钥或身份证信息 | 🛑 禁止写入 | 规则引擎强制拦截 | 永远不进入记忆系统 |
这里隐藏了一个极其重要的工程细节:必须把“事实”和“推断”分开。
用户自己说的叫“事实”;系统根据几道错题推测出来的叫“推断”。推断出来的东西,必须保存证据和置信度,且优先级永远低于事实。
⚙️ 一条靠谱的记忆写入流水线
为了避免把垃圾数据和敏感数据写入记忆,在落盘前我们需要一条标准的流水线:
如果你现在就想动手敲代码,别急着一上来就搞向量数据库(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 隔离,再按相关性提取,最后检查 status 和 expires_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(过期时间)了吗? - 你的系统能区分出“用户事实”和“模型推断”吗?
- 检索记忆时,你是全量丢给大模型,还是做过业务过滤了?
更多推荐



所有评论(0)