返回

为什么你的AI Agent其实什么都记不住

RSS TiDB Blog AI 逐段翻译 发布 2026-09-18 00:14 收录于 09-19

有效阅读仅保存在当前浏览器,用于「为你」推荐;暂停或清除记录。

DataHot 速览

本文探讨AI Agent的记忆问题,指出持久化只是最简单的部分,真正的难点在于记忆的选择、压缩、衰减与污染防控。作者以客服Agent为例:用户周一咨询账单问题,周三回来继续对话时Agent却完全失忆,不知道用户是谁、之前的问题是什么、已尝试过什么、承诺过什么。文章区分了记忆与幂等性、工作流状态、事务一致性三者的不同,并指出记忆逻辑应存在于查询中,包括读取时的衰减、置信度加权与污染过滤。

原收录理由(待核验):Agent记忆是构建可生产Data Agent/分析Agent的核心工程难题,本文明确了记忆与幂等、状态机的边界,并给出读取时记忆逻辑的实现思路,对做Agent的从业者有直接借鉴价值。

本文目录 9 节
  1. 核心要点
  2. 首先,记忆不是什么
  3. 记忆实际上是什么
  4. 一个有用的分类法
  5. 为何单一用途存储不够用
  6. 模式,以及诚实的注意事项
  7. 反映真实记忆行为的回忆查询
  8. 更新记忆:乐观和悲观模式
  9. 状态持久化不是记忆,但记忆需要它

译文

AI 逐段翻译

编者注:本文最初发表于 The New Stack,经许可后重新发布。原始版本可在此处查看 此处。

核心要点

  • 持久化是简单的部分。选择、压缩、衰减和防污染才是智能体崩溃的地方。
  • 幂等性和状态机保证操作正确;它们不会给智能体带来历史感。
  • 键值存储无法回答情景式查询;向量存储无法处理精确谓词。
  • 记忆逻辑存在于查询中:在读取时进行衰减、置信度加权和污染过滤。

几个月前,我在审查一个客户支持智能体时,发现它有一种奇怪的故障模式。用户在周一与它聊天讨论账单问题,解决方案进行到一半,然后在周三回来继续。周三的对话会从零开始。智能体不知道用户是谁、之前的问题是什么、已经尝试过什么,或者承诺过什么。

该团队将智能体建立在一个坚实的基础之上。操作端点上有幂等键。多步骤流程有工作流状态机。任何涉及账单的操作都有事务性写入。保证正确性的基础设施是存在的。他们缺少的是让智能体回忆和推理自身历史的方式,无法知道这个用户两天前曾被承诺过一笔尚未发放的退款。

这就是我想讨论的问题。不是智能体可靠性中优秀系统工程已经解决的部分。而是它们之上更难的层面:智能体的记忆能力。

首先,记忆不是什么

太多关于智能体记忆的架构讨论之所以跑偏,是因为人们以不同的方式使用这个词。让我澄清其中三种。

记忆不是幂等性。如果你的智能体因为同一个请求两次到达你的端点而两次执行相同操作,解决办法是幂等键。智能体不需要记住;系统需要识别重复。记忆不是工作流状态。如果你的智能体处于流程中间,解决办法是一个记录当前步骤并限制合法转换的状态机。记忆不是事务一致性。如果两个智能体即将对同一数据采取行动,解决办法是数据库级隔离。

这三者都是必要的。它们都不是记忆。它们保持单个操作正确;它们不会给智能体带来历史感。

记忆实际上是什么

我逐渐认为智能体记忆具有五种必须协同工作的能力。持久存储是其中之一,而且是最简单的。其他方面才是大多数生产智能体不足之处。

  • 持久化:智能体的历史在会话结束、进程重启和部署后仍然存在。通过写入数据库解决。
  • 选择:智能体决定什么值得记住。永远存储每次对话的每个 token 既昂贵又适得其反。它会在回忆时稀释信号。
  • 压缩:原始历史被总结成有用的东西。两小时的对话变成一段话加上结构化事实。没有压缩,检索成本会随交互时间线性增长。
  • 衰减与遗忘:旧记忆不如近期记忆重要,有些应该被遗忘。没有衰减,过时信息与新鲜信息权重相同,这正是 RAG 管道对你说谎的方式,我上一篇文章的主题。
  • 防污染:错误记忆比没有记忆更糟。坏事实一旦存储,就会污染未来的每一个决策。真正的记忆系统会标记不确定的记忆,在被矛盾时降低其权重,并在被证明错误时将其隔离。

大多数关于智能体记忆的讨论将这五种全部归结为第一种。他们争论用哪个数据库存储智能体状态,然后称之为已解决。但是,没有选择的持久化会给你一个缓慢的智能体。没有压缩,会给你一个昂贵的智能体。没有衰减,会给你一个自信地犯错的智能体。而没有防污染,会给你一个随时间变得越来越笨的智能体。这五种都是必要的,而底下的基础决定了你可以构建哪些架构。

一个有用的分类法

记忆是有结构的。从认知科学中借鉴,给了我一套词汇来诊断智能体架构在哪里失败。

  • 工作记忆是上下文窗口:当前任务、当前轮次。快速、短暂。这是当今大多数智能体所拥有的,并将其与一般意义上的记忆混淆。
  • 情景记忆是特定过去交互的历史,带有丰富的元数据:谁、什么、何时以及结果。
  • 语义记忆是提炼后的知识。“这位客户偏好早班航班。”“财务 API 以分为单位返回金额。”按含义查询,而非按时间查询。
  • 程序性记忆是习得的行为:哪些工具序列比其他序列效果更好。几乎还没有人在生产环境中实现这一点。这是另一篇文章的主题。

工作记忆是一个提示字符串。情景记忆需要结构化时间序列查询。语义记忆需要向量搜索。本文的其余部分聚焦于情景记忆和语义记忆,真正的生产差距就在于此。

为何单一用途存储不够用

大多数团队首先想到的是 Redis。快速、熟悉,非常适合工作记忆。问题在于键值存储只给你一种访问模式:按键获取。这对于情景式回忆是失败的,因为情景式回忆需要诸如“我在过去 30 天内为该地区用户发放的每一笔成功退款”这样的查询。这是一个关系查询,不是键查找。

团队其次想到的是向量数据库。嵌入过去的交互,按相似度搜索。这对语义记忆有用,但对于情景式回忆就不够了,因为情景式回忆通常需要精确谓词:特定用户、特定时间窗口、特定结果。当你需要 WHERE 子句时,余弦相似度帮不上忙。而且向量存储通常无法与你的应用数据连接,这意味着智能体无法在用户是谁的上下文中对记忆进行推理。

然后是污染处理。当发现某个记忆是错的,你需要更新或使其失效。在向量存储中,那就是重新索引。在键值存储中,是大规模缓存失效。而在支持向量的关系型数据库中,那就是一条 UPDATE。记忆系统的成败取决于坏记忆被清理的可靠性。

模式,以及诚实的注意事项

这是一个参考模式,用于在单个数据库中处理情景记忆和语义记忆的层。

-- Episodic memory: what happened, with outcomes
CREATE TABLE episodic_memory (
  id            BIGINT PRIMARY KEY AUTO_INCREMENT,
  agent_id      VARCHAR(64) NOT NULL,
  user_id       BIGINT NOT NULL,
  session_id    BIGINT NOT NULL,
  action_type   VARCHAR(100) NOT NULL,
  summary       TEXT,           -- compressed form
  raw_payload   JSON,           -- full detail, kept for audit
  outcome       ENUM('success','failure','pending'),
  confidence    FLOAT DEFAULT 1.0,
  superseded_by BIGINT NULL,    -- contamination invalidation
  created_at    DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  embedding     VECTOR(1536),
  INDEX idx_agent_user_time (agent_id, user_id, created_at),
  INDEX idx_embedding USING HNSW (embedding)
);
-- Semantic memory: distilled knowledge, with decay metadata
CREATE TABLE semantic_memory (
  id                BIGINT PRIMARY KEY AUTO_INCREMENT,
  agent_id          VARCHAR(64) NOT NULL,
  user_id           BIGINT,
  fact              TEXT NOT NULL,
  confidence        FLOAT DEFAULT 1.0,
  source_count      INT DEFAULT 1,
  last_confirmed_at DATETIME NOT NULL,
  contradicted_at   DATETIME NULL,
  created_at        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  embedding         VECTOR(1536),
  INDEX idx_embedding USING HNSW (embedding)
);

有几个细节,是一年前我会写的更简单的模式所没有的:

  • 同时包含 summary 和 raw_payload 两列。压缩不是可选项。智能体在回忆时读取 summary;raw_payload 则保留用于审计和重新摘要。
  • confidence 和 superseded_by。记忆不是不可变的。superseded_by 是针对污染的软删除指针。当记忆 A 被记忆 B 反驳时,A 指向 B,并被排除在回忆之外。原始记录不会被删除;审计很重要。
  • source_count 和 last_confirmed_at。一个被十次交互确认的事实,比只被确认一次的事实更可靠。一个上次确认于两年前的事实,其权重应低于昨天确认的事实。这些会馈入一个在回忆时而非写入时应用的衰减函数。
  • 数据保留;其权重改变。这是贯穿上述所有内容的原则。记忆记录不会被重写或删除。它们被标注、衰减或被取代。

反映真实记忆行为的回忆查询

有了这个模式,回忆查询能表达比“查找相似内容”更难的行为。这包括诸如按新近度和置信度加权的相似度等度量,同时排除受污染的记忆。

-- Semantic recall with decay and contamination filtering
SELECT fact,
       confidence
       * EXP(-DATEDIFF(NOW(), last_confirmed_at) / 90.0) AS effective_weight,
       VEC_COSINE_DISTANCE(embedding, @task_vec) AS distance
FROM semantic_memory
WHERE (user_id = @user_id OR user_id IS NULL)
  AND contradicted_at IS NULL
  AND VEC_COSINE_DISTANCE(embedding, @task_vec) < 0.30
ORDER BY distance, effective_weight DESC
LIMIT 10;

衰减项 EXP(-days/90) 大约是 60 天的半衰期。客户偏好衰减缓慢。库存事实衰减很快。真实的记忆系统会按记忆类型来调整这个参数。

这些查询在做真正的记忆工作。它们不只是检索行。它们在建模置信度如何衰减、污染如何传播、新近度如何与相关性交互。数据库是基底。智能存在于查询中,而不是行中。

更新记忆:乐观和悲观模式

记忆不是一次写入的。随着新证据到来,置信度会更新。记忆会被取代。这些更新可能并发发生,因此我们需要对并发控制保持审慎。两种模式很常见,而它们之间的差异很重要,因为二者常常被混为一谈。

悲观锁先获取锁,并在操作期间一直持有。在预期会有争用且操作很短时使用:

-- Pessimistic: lock the row, then update
BEGIN;

SELECT confidence, source_count
FROM semantic_memory
WHERE id = @memory_id
FOR UPDATE;

-- Application computes new confidence

UPDATE semantic_memory
SET confidence = @new_confidence,
    source_count = source_count + 1,
    last_confirmed_at = NOW()
WHERE id = @memory_id;

COMMIT;

乐观并发控制采取不同的方法。读取时不加锁;相反,你记录所读取行的版本,并在写入时断言版本未变。如果已变,则更新失败,应用程序重试。在争用很少且读者远多于写者时使用:

-- Optimistic: read with version, write conditionally

SELECT confidence, source_count, version
FROM semantic_memory
WHERE id = @memory_id;

UPDATE semantic_memory
SET confidence = @new_confidence,
    source_count = source_count + 1,
    last_confirmed_at = NOW(),
    version = version + 1
WHERE id = @memory_id
  AND version = @read_version;

-- If 0 rows affected, another transaction won the race; retry.

两者都有效。来自人工审核者的记忆更新(低频、高关注)适合悲观锁。来自后台摘要任务、跨数百万条记录的记忆更新(高频、低争用)适合乐观并发。在单个事务中粗心地混合它们(FOR UPDATE 再加上对你刚刚锁定的同一行做版本检查)会做冗余工作,并表明你对承诺采用哪种模型感到困惑。

重点不在于用哪一种。而在于数据库两者都支持,它们都符合 ACID,并且智能体不在应用代码中实现任何一种。

状态持久化不是记忆,但记忆需要它

让我以一个区分来收尾,这个区分比大多数架构讨论所承认的更重要。

我在本文大部分内容中描述的,是一个状态与知识持久化层。它是基底。仅凭它本身,并不是完整意义上的记忆。记忆是当一个智能系统很好地利用该基底时发生的事情:选择要记住什么,摘要要保留什么,权衡旧与新,识别它曾相信的东西何时是错的,并在正确的时刻带来正确的回忆。基底不做这些事情。智能体做。但没有一个支持这些事情的基底,智能体也无法做这些事情。

我会问任何构建生产级智能体的团队的问题,不是“用哪个向量数据库”或“我们该不该用 Redis”。而是你智能体下方的基底是否支持你在十二个月内将需要的全套记忆行为。持久化,是的。但还包括:针对情景历史的结构化查询。对压缩摘要的向量回忆。在读取时计算的置信度衰减。作为一等操作的污染失效。悲观和乐观并发。随着智能体集群增长而水平扩展。

这就是我们在演进 TiDB 以支持智能体工作负载时一直在思考的问题。不是“一个也能做 SQL 的向量数据库”,也不是“一个硬塞进向量功能的关系型数据库”。而是一个能处理真实记忆系统所需所有存储模式的基底,并具备分布式 SQL 的一致性和规模特性。模式是容易的部分。基底所支持的模式,才是智能体实际记忆所在。

工作负载是新的。这门纪律比它更古老。

文章 Why Your AI Agent Doesn’t Actually Remember Anything 首次发表于 TiDB。

这篇内容对你有用吗?

反馈只用于改善内容筛选,不等同于收藏

分享这条资讯
分享海报
保存图片
iOS 也可以长按图片保存