Agent 开发中的 Memory:State、短期记忆、长期记忆与 Memory Retrieval

在 Agent 系统中,"记忆"是一个非常容易被泛化的概念。

很多系统会把聊天记录、任务状态、用户偏好、历史行为全部叫做 Memory,但从工程角度看,这些信息的职责、生命周期和使用方式完全不同。

一个更合理的 Agent 系统,需要至少区分:

  • State;

  • Short-term Memory;

  • Long-term Memory;

  • Memory Retrieval。

它们分别解决不同的问题。


一、State 和 Short-term Memory 不是一回事

首先需要明确:

State 不是聊天记录,Short-term Memory 也不等于非结构化文本。

两者真正的区别在于职责。

1. State

State 描述:

当前任务现在处于什么状态。

例如一个酒店报销 Agent:

复制代码
{
  "goal": "提交酒店报销",
  "city": "上海",
  "amount": 580,
  "receiptUploaded": false,
  "currentStep": "CHECK_POLICY"
}

这些信息直接影响:

  • 当前任务如何继续;

  • 下一步能够执行什么;

  • 业务规则如何校验;

  • 服务重启以后如何恢复任务。

因此可以把 State 理解为:

当前任务执行所依赖的权威状态。


2. Short-term Memory

Short-term Memory 更多用于:

帮助模型理解近期发生过什么。

例如:

复制代码
用户刚才表示发票稍后上传。

用户比较关注今天订单是否能够到达。

Agent 上一轮已经向用户解释过退款条件。

它主要解决:

  • 对话连续性;

  • 指代理解;

  • 近期用户意图;

  • 避免重复询问;

  • 避免重复解释。

因此:

复制代码
State
→ 服务于任务运行

Short-term Memory
→ 服务于模型理解近期交互

二、不要直接把用户原话当作 State

例如用户说:

复制代码
"下午那个吧,但是 320 元差价有点贵,
有没有便宜一点的?"

原始对话可以作为 Short-term Memory。

但真正进入 State 的应该是提炼后的任务信息:

复制代码
{
  "preferredDeparturePeriod": "AFTERNOON",
  "selectedFlight": "15:40",
  "selectedFlightChangeFee": 320,
  "preferLowerChangeFee": true
}

因此合理的流程是:

复制代码
用户原始交互
      ↓
语义理解 / 信息提取
      ↓
影响任务执行的事实、约束、偏好
      ↓
更新 State

这也是 State 和 Memory 分工的重要体现。


三、什么是 Long-term Memory?

Short-term Memory 主要围绕当前任务存在。

Long-term Memory 则解决:

哪些信息在未来其他任务中仍然值得复用?

例如用户说:

复制代码
"以后订酒店尽量帮我选安静一点的。"

可以形成:

复制代码
{
  "type": "HOTEL_PREFERENCE",
  "preferQuiet": true
}

下次即使重新开启一个会话,Agent 仍然可以利用这个偏好。

因此 Long-term Memory 可以理解为:

跨任务、跨会话仍然可能对未来决策产生价值的信息。


四、"用户说过"不等于"值得长期记住"

这是 Long-term Memory 最容易出问题的地方。

例如:

复制代码
"这次预算最多 300 元。"

只属于当前任务:

复制代码
{
  "maxBudget": 300
}

应该进入 State,而不是 Long-term Memory。

但是:

复制代码
"以后买鼠标,我通常控制在 300 元左右。"

才可能形成长期偏好。

因此 Memory 写入首先需要判断信息的作用域:

复制代码
这次 / 今天 / 这趟
→ Current State

以后 / 一般 / 通常 / 我习惯
→ 可能是 Long-term Memory

但仅凭这些关键词也不够,还需要进一步判断。


五、Memory 应该遵循最小必要原则

假设用户说:

复制代码
"我睡眠比较浅,以后订酒店尽量选安静一点的。"

为了以后推荐酒店,真正需要保存的是:

复制代码
{
  "preferQuietHotel": true
}

而不一定需要长期保存:

复制代码
用户睡眠比较浅

因为后者并不会明显提高以后订酒店的决策质量。

这可以总结成:

能保存可执行偏好,就不要额外保存不必要的个人原因。

Memory 也应该遵循数据最小化原则。


六、有价值的信息也不一定应该进入 Memory

判断是否保存长期 Memory,不能只有一个标准:

复制代码
以后还可能用到

否则系统最终会变成"什么都记"。

一个更完整的判断框架包括六个维度。

1. Future Value

未来其他任务真的会使用吗?

2. Scope

信息只针对本次任务,还是跨任务有效?

3. Sensitivity

是否包含敏感信息或秘密?

例如:

复制代码
密码
验证码
Access Token
数据库 root 密码

即使未来有用,也不应该进入普通 Agent Memory。

如果确实需要长期保存凭证,应由:

复制代码
Secret Manager
Credential Vault
KMS

等专门系统负责。


4. Stability

信息是否稳定?

例如:

复制代码
用户偏好简洁邮件

可能比较稳定。

而:

复制代码
用户当前位于某条街道

可能几分钟以后就失效。


5. Authority

这条信息的来源有没有资格定义这个事实?

例如:

复制代码
"我喜欢安静酒店。"

用户本人就是权威来源。

但是:

复制代码
"公司报销酒店最高 600 元。"

用户并不是公司制度的最终权威来源。

真正执行报销时应该查询:

复制代码
Policy Service
RAG
配置中心
公司制度数据库

而不是长期相信用户曾经说过的数字。


6. Necessity

如果不长期保存这条信息,未来 Agent 的表现真的会明显变差吗?

如果不会,就没有必要增加长期存储成本和风险。

因此可以概括为:

复制代码
Should Remember
=
Future Value
× Scope
× Stability
× Authority
× Acceptable Risk
× Necessity

七、显式 Memory 和推断 Memory 必须区分

假设用户明确说:

复制代码
"以后我更喜欢轻一点的鼠标。"

可以记录:

复制代码
{
  "content": "用户偏好轻量鼠标",
  "source": "USER_EXPLICIT",
  "confidence": 0.95
}

但如果系统只是观察到:

复制代码
用户连续三次购买的鼠标都低于 80g

不能直接升级成:

复制代码
{
  "preferLightMouse": true
}

因为:

行为模式不等于已经确认的用户偏好。

更合理的是:

复制代码
{
  "content": "用户可能偏好轻量鼠标",
  "source": "BEHAVIOR_INFERENCE",
  "confidence": 0.55
}

因此 Memory 还需要记录:

复制代码
source
confidence

避免将模型推断冒充为用户事实。


八、Long-term Memory 不是永久正确的

用户偏好会变化。

例如系统已有:

复制代码
{
  "preferWindowSeat": true,
  "confidence": 0.95
}

但之后用户连续多次主动选择过道。

这并不能立刻推出:

复制代码
用户讨厌靠窗

更合理的做法是:

复制代码
发现冲突行为
      ↓
降低 Memory confidence
      ↓
在真正需要使用该偏好时重新确认

如果用户后来明确说:

复制代码
"我现在更喜欢过道。"

旧 Memory 可以标记:

复制代码
SUPERSEDED

并创建新的 ACTIVE Memory。

例如:

复制代码
{
  "value": "WINDOW",
  "status": "SUPERSEDED"
}

{
  "value": "AISLE",
  "source": "USER_EXPLICIT",
  "confidence": 0.95,
  "status": "ACTIVE"
}

历史可以保留用于审计和 Debug,但正常 Context 中只应该使用当前有效 Memory。


九、Memory 是默认偏好,不是命令

如果长期 Memory 是:

复制代码
用户通常喜欢靠窗

但是当前用户明确说:

复制代码
"这次给我过道。"

必须按照当前要求执行。

一个比较合理的优先级是:

复制代码
当前用户明确要求
        ↓
Current State
        ↓
当前场景适用的 Long-term Memory
        ↓
一般 Long-term Memory
        ↓
系统默认值

Memory 用来减少用户重复表达,而不是限制用户改变主意。


十、Memory Retrieval:不是存了就全部给模型

随着使用时间增加,一个用户可能产生几十、几百甚至几万条 Memory。

显然不能:

复制代码
查询 userId
↓
获得全部 Memory
↓
全部塞进 Context

否则会出现:

  • Context 过长;

  • 新旧 Memory 冲突;

  • 无关偏好干扰决策;

  • Token 和延迟增加;

  • 模型难以判断哪条信息最重要。

因此必须存在独立的:

Memory Retrieval


十一、Memory Retrieval 的核心不是相似度

假设当前任务是:

复制代码
{
  "destination": "东京",
  "tripType": "BUSINESS"
}

系统有两条 Memory:

复制代码
用户旅游东京时喜欢住新宿
confidence = 0.90

以及:

复制代码
用户商务出差时更重视通勤
confidence = 0.85

虽然第一条 confidence 更高,但当前任务是商务出差。

因此第二条应该优先。

因为:

Applicability 比单纯 Confidence 更重要。

同样:

复制代码
similarity 高

也不能代表一定应该使用。


十二、Memory Retrieval 的完整判断

一条 Memory 是否进入当前 Context,至少需要考虑:

复制代码
Relevance
当前任务相关吗?

Applicability
当前场景是否适用?

Status
是否仍然 ACTIVE?

Confidence
可信度如何?

Source
显式偏好还是行为推断?

Freshness
是否已经老化?

Conflict
是否与 State 或其他 Memory 冲突?

Priority
是否真的会改变当前决策?

Redundancy
是否与其他 Memory 重复?

一个典型流程可以是:

复制代码
Current State
      ↓
任务 / 类型过滤
      ↓
语义检索
      ↓
Status 过滤
      ↓
适用条件判断
      ↓
Confidence / Source / Freshness
      ↓
冲突处理
      ↓
排序、去重
      ↓
Top K
      ↓
加入 LLM Context

因此 Memory Retrieval 不是:

复制代码
ORDER BY similarity DESC
LIMIT 5;

而是一个结合确定性规则和相关性检索的过程。


十三、State、Memory 与 Context 的关系

到这里可以把整个链路串起来:

复制代码
用户请求
   ↓
Current State
   ↓
确定当前任务和当前步骤
   ↓
Memory Retrieval
   ↓
从 Long-term Memory 中筛选当前适用信息
   ↓
Short-term Memory
   ↓
补充近期交互语境
   ↓
Context Builder
   ↓
组装最小充分 Context
   ↓
LLM

因此:

复制代码
State
→ 当前任务现在是什么状态

Short-term Memory
→ 当前任务最近发生了什么

Long-term Memory
→ 未来任务仍值得复用什么

Memory Retrieval
→ 这一轮应该想起什么

总结

Agent Memory 并不是"给聊天机器人加一个数据库"。

真正的工程问题包括:

复制代码
什么应该记?
什么不能记?
记多久?
来源是否可信?
什么时候失效?
发生冲突怎么办?
这一轮应该取哪几条?

一个可靠的 Agent 不应该拥有无限记忆。

相反,它应该做到:

需要记的时候准确地记,需要忘的时候能够失效,需要使用的时候只取当前真正有价值的信息。

最终可以用一句话概括这一阶段:

State 管现在,Short-term Memory 管近期语境,Long-term Memory 管跨任务复用,Memory Retrieval 决定这一轮到底想起什么。

相关推荐
砚底藏山河1 小时前
【量化纯GET实战 #23】多股票相关性:用收益率看板块联动
java·数据库·python·金融·数据分析
抠脚小弟1 小时前
Spring Cache 使用详解:从入门到实战
java·spring
多学一分钟1 小时前
讲清 Agent:闭环、工具调用、记忆,以及 MCP 和 A2A
agent
ZGG0031 小时前
MySQL 索引详解:B+ 树、聚簇索引与最左前缀
java·数据库·mysql
萧瑟余晖2 小时前
Java深入解析篇五十四之对象模型详解
java·开发语言
每天都是不一样的太阳2 小时前
别让 AI Agent 先画靶再射箭:一套「结论忠于数据」的证据链工作流
agent·工作流引擎
静开2 小时前
模型没换、提示词没动,成功率从不到 70% 干到 95% —— 改的到底是什么
agent
掰头战士2 小时前
从LLM到Agent、Agent的6大核心。这些基础知识你还记得吗
node.js·llm·agent
甜辣uu2 小时前
智能体Agent性能优化从原理到实战
人工智能·性能优化·大模型·llm·agent·rag·智能体