Agent 的记忆不是向量数据库:三种记忆架构的真实取舍

举报
yd_289817328 发表于 2026/10/31 09:11:39 2026/10/31
【摘要】 向量检索只解决了「找回原话」,解决不了「记住结论」。拆解短期记忆、结构化记忆、压缩摘要三种方案,附可运行的分层记忆实现。

做 Agent 的人迟早会撞上同一个问题:对话一长,它就开始忘事。

常见的第一反应是「上向量数据库」。文档切片、embedding、检索 Top-K,一套下来,Agent 好像真的记住了。但用两周你会发现:它能翻出你上周说过的那句话,却不记得你已经否决过的方案;能检索到「预算 50 万」,却不知道这个数字后来改成了 30 万。

向量检索擅长「找回原话」,不擅长「记住结论」。 这是两件事。

一、先把「记忆」拆开

Agent 的记忆至少有三个层次,混在一起就会做错决策:

层次 内容 生命周期 适合的存储
工作记忆 当前任务的中间状态 分钟级 上下文窗口
情景记忆 发生过什么、结论是什么 天/周级 结构化文件或表
知识记忆 领域事实、文档 长期 向量库 / 全文索引

大多数「Agent 记不住」的问题,其实是情景记忆缺失——它没有记录「用户否决了什么」,而不是知识检索不够。

二、三种架构的真实取舍

方案 A:全量上下文(最朴素,也最容易被低估)

把历史全部塞进上下文。缺点是成本随轮次线性增长,长任务会爆 token。

但它的优点很硬:零检索误差。在 50 轮以内的任务里,它往往比任何 RAG 方案都准。

所以第一步不该是上向量库,而是先回答:这个任务真的需要跨会话记忆吗?如果只是单次任务,把窗口开大就够了。

方案 B:结构化情景记忆(我最推荐)

不存原文,存「结论 + 状态」。用一张简单的表或 JSON 文件:

import json
from datetime import datetime

class EpisodicMemory:
    def __init__(self, path="./memory.json"):
        self.path = path
        try:
            self.data = json.load(open(path, encoding="utf-8"))
        except FileNotFoundError:
            self.data = {"facts": [], "decisions": []}

    def remember(self, kind, content, source="user"):
        item = {"content": content, "source": source,
                "ts": datetime.now().isoformat(timespec="seconds")}
        self.data[kind].append(item)
        json.dump(self.data, open(self.path, "w", encoding="utf-8"),
                  ensure_ascii=False, indent=2)

    def recall(self, keyword=None, limit=10):
        items = self.data["facts"] + self.data["decisions"]
        if keyword:
            items = [i for i in items if keyword in i["content"]]
        return items[-limit:]

用法很直接:用户说「预算改成 30 万」,Agent 记一条 decision;下次涉及预算,先查 decisions,而不是去全文检索里翻旧对话。

关键设计:决策类信息必须带时间戳,并且允许覆盖。向量库做不到「这条作废」,结构化记录可以。

方案 C:压缩摘要(成本最低的折中)

每 N 轮把对话压缩成一段摘要,替换掉原始记录:

def compress(history, llm):
    prompt = ("把下面的对话压缩成要点,保留:已确认的结论、被否决的方案、"
              "未解决的问题。不要保留闲聊和重复内容。\n\n" + history)
    return llm(prompt)

优点是省 token,缺点是有损。压缩掉的细节可能正是后面要用的。所以它适合「长周期、低精度要求」的陪伴型 Agent,不适合严谨任务。

三、我的组合方式

实际项目里我用的是分层:

  1. 工作记忆:当前任务放上下文,不额外存
  2. 情景记忆:结构化文件,只存结论和决策,带时间戳
  3. 知识记忆:文档走向量检索,只在需要查资料时调用

每次调用模型前拼三样东西:任务目标 + 最近的情景记忆 + 按需检索的知识片段。

这样做的效果是可解释的:Agent 说「预算 30 万」,你能立刻在 memory.json 里找到那条决策记录,而不是去猜它是从哪个文档片段里拼出来的。

四、三个容易踩的坑

1. 把所有东西都塞进向量库。
决策、偏好、否决记录放进向量库,检索时和文档混在一起,噪声极大。这类信息应该是结构化查询,不是语义检索。

2. 记忆没有时间维度。
「预算 50 万」和「预算 30 万」同时被检索出来,模型只能猜哪个新。必须带时间戳,并明确「后者覆盖前者」。

3. 不记录「否决」。
用户说「不要用 Kafka」,这句话比任何文档都重要。但它往往被当成闲聊丢掉,导致 Agent 下次又推荐一遍。

结语

Agent 的记忆问题,本质是信息组织问题,不是检索算法问题。

先想清楚你要记的是「原话」还是「结论」,再决定用向量库还是用一张表。多数情况下,一个带时间戳的 JSON 文件,比一套 RAG 流水线更能解决「它怎么又忘了」。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。