跳转至

第 6 章:Short-Term、Long-Term 与 Profile Memory

1. 为什么“memory”这一个词反而会妨碍你

只要系统里出现了 memory,团队就会很容易用一个词去指代所有“当前 prompt 装不下的东西”。这对讨论来说很方便,但对架构来说是个糟糕抽象。

在实践里,你几乎总会有至少三层不同的东西:

  • short-term memory,用于当前 run 或一小串步骤;
  • long-term memory,用于长期知识、summaries 和 facts;
  • profile memory,用于某个具体用户或账号的偏好、角色和习惯。

如果这几层不拆开,agent 很快就会:

  • 把太多旧噪音重新塞回 prompt;
  • 把用户偏好和世界事实混为一谈;
  • 把 transient observations 存成长期真相;
  • 破坏 explainability,因为你已经说不清某段上下文到底从哪来。

2. Short-term memory 是工作台,不是档案馆

最适合把 short-term memory 想成 agent 的工作台。它不是“永远的历史”,而是帮助 agent 不丢失当前线索的地方。

通常这里会放:

  • 中间计划;
  • 最近的 tool call 结果;
  • 临时 hypotheses;
  • 为当前 run 选出的上下文片段;
  • 多步 workflow 的状态。

一个好的 short-term memory 有三个特征:

  • 大小是受限的;
  • 生命周期很短;
  • 任务结束后就算丢掉,也不会太痛。

如果“永久记录”开始住进 short-term memory,那通常说明你没有 data model,只有一个被塞满的 buffer。

3. Long-term memory 不是拿来装一切的,而是装稳定知识的

Long-term memory 适合保存那些价值能跨过一次对话或一次 workflow 的记录。

它可能包括:

  • 某个业务实体的已确认事实;
  • 上一次会话的 summary;
  • 某个长期 case 的累积知识;
  • 为未来 retrieval 提前提取并规范化的笔记。

但这里有一个重要过滤条件:如果某条记录离开完整原始上下文以后就无法被合理复用,那它大概率不该进入 long-term memory。

团队经常会在这里高估“原始保存”的价值。Long-term memory 更适合存有意义、可类型化的记录,而不是无穷无尽的原始流。

4. Profile memory 不是 knowledge base

Profile memory 特别容易被做坏,因为它听起来很无害,好像只是“用户偏好”。但到了 production,它很快就会变成一个敏感层。

这里通常包括:

  • 交流语言;
  • 回复格式;
  • 工作角色;
  • 允许的动作渠道;
  • 稳定的界面或交互偏好。

关键区别是,profile memory 回答的问题是“系统应该怎样更好地和这个人协作”,而不是“世界上什么是真的”。

如果 agent 开始往里面塞任意事实,profile memory 很快就会变成 personalization、流言和偶然观察的混合物。

不同类型的记忆解决不同问题,不应该挤进同一个 storage

flowchart LR
    A["Current run"] --> B["Short-term memory"]
    A --> C["Long-term memory"]
    A --> D["Profile memory"]
    B --> E["Planner state"]
    B --> F["Recent tool outputs"]
    C --> G["Validated facts"]
    C --> H["Session summaries"]
    D --> I["Preferences"]
    D --> J["User constraints"]

5. 好的架构会给每一层一个明确问题

这会极大帮助设计:

  • short-term memory:为了不丢任务,现在必须记住什么?
  • long-term memory:什么值得被保存,因为以后还会有用?
  • profile memory:关于这个用户或账号,什么是真正稳定而且有用的?

如果一条记录对这些问题都答不上来,那它可能根本不该被保存。

6. 每一层都应该有自己的读写规则

这里最常见的架构错误,是同一个 pipeline 用完全一样的方式去读写所有 memory types。但这几乎总是错的。

例如:

  • short-term memory 可以更自由地读,但保存时间应该极短;
  • long-term memory 应该要求 provenance 和 tenant checks;
  • profile memory 应该对 privacy、consent 和 explainability 更严格。

一个正常系统不仅知道自己存了 什么,还知道每一类东西 如何 进入 prompt。

memory_classes:
  short_term:
    ttl: "2h"
    read_path: "runtime_only"
    write_policy: "immediate"
  long_term:
    ttl: "90d"
    read_path: "retrieval_with_filters"
    write_policy: "validated_only"
  profile:
    ttl: "365d"
    read_path: "personalization_only"
    write_policy: "explicit_or_high_confidence"

这段 YAML 不一定就是最终实现,但它逼着团队做一个重要决定:memory 不能在“反正就是数据库里的一段文本”这个层面被管理。

7. 什么通常应该放进 short-term memory

一个很有用的 practical rule:short-term memory 应该帮助 agent 现在行动,而不是变成长期真相的来源。

好的候选:

  • 当前计划;
  • 子任务状态;
  • 最近两三次工具调用的结果;
  • 关于哪些事情已经检查过的 working notes;
  • 临时的 candidate summaries。

不好的候选:

  • “永远有效”的用户偏好;
  • 没清洗过的原始文档;
  • 巨大的日志;
  • 没有 TTL 的敏感数据;
  • 后面会被重复当成真相的不确认事实。

8. 什么通常应该放进 long-term memory

Long-term memory 的意义是复用知识,而不是归档所有活动。

合理的内容包括:

  • 已确认事实;
  • 带 provenance 的仔细 summaries;
  • 长期 case 的状态;
  • 规范化后的 knowledge records;
  • 指向文档的链接,而不是把巨大 payload 原样塞进去。

一个很实用的原则是:在 long-term memory 里,通常更值得存一个紧凑 record 加 source 链接,而不是把存储层做成永久 dump。

9. 什么通常应该放进 profile memory

Profile memory 最有价值的时候,是它让 agent 更好用,但不会开始基于不可靠猜测替用户做决定。

好的例子:

  • “偏好简短回答”;
  • “通常用俄语工作”;
  • “修改 production 数据时需要确认”;
  • “喜欢在一天结束时收到报告”。

不好的例子:

  • 对动机或性格的推断;
  • 只来自一次会话的随机猜测;
  • 没有明确理由的敏感个人数据;
  • 后面会被当成事实使用的猜测。

10. 一个简单的 memory routing 代码模板

下面是一个很简单的例子,展示核心想法:记录先分类,再进入对应的 storage。

from dataclasses import dataclass


@dataclass
class MemoryRecord:
    kind: str
    content: str
    confidence: float


def select_memory_bucket(record: MemoryRecord) -> str | None:
    if record.kind in {"plan_step", "tool_result", "working_note"}:
        return "short_term"
    if record.kind in {"validated_fact", "session_summary", "case_state"} and record.confidence >= 0.8:
        return "long_term"
    if record.kind in {"language_preference", "format_preference", "approval_preference"}:
        return "profile"
    return None

这个例子故意写得很直白。实践里规则会更丰富,但核心思想不该变:memory 要先分类,而不是直接丢进一个共享容器。

11. 团队最常坏在哪里

常见问题通常长这样:

  • profile memory 开始替代 authorization;
  • long-term memory 被噪音填满;
  • short-term memory 变得又大又贵;
  • retrieval 返回内容时不考虑 class;
  • 没人能解释为什么这段上下文会出现在答案里。

这些都不是“模型问题”,而是 memory layer 的架构问题。

12. 实用检查清单

如果你想快速检查设计,可以问:

  • 你是否真的理解 short-term memory 和 long-term memory 的区别?
  • profile memory 是否有独立语义,而不只是独立表?
  • 每种记录类型的 TTL 能不能解释清楚?
  • 哪一层 memory 会直接进 prompt,哪一层只能通过 retrieval,是否清楚?
  • 长期记录是否有 provenance?
  • 记录能不能被安全删除或修正?

如果这些问题都很难回答,那 memory 架构值得被简化,并按职责重新拆开。

13. 接下来读什么

这一部分接下来的自然步骤,就是讨论 agent 如何把正确片段拉回 prompt,以及为什么 compaction 有时候比“更多 retrieval”更重要。