找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1750

积分

0

好友

236

主题
发表于 9 小时前 | 查看: 3| 回复: 0

上周我遇到了两个截然不同的对话体验,这直接引发了我对 AI 记忆系统的思考。

场景一:使用普通 AI Agent

我:帮我优化一下 Redis 配置
AI Agent:好的,请告诉我你的 Redis 版本、内存大小、使用场景...
我:(输了一堆信息)
AI Agent:明白了,建议你...
(第二天)
我:上次那个 Redis 优化还有个问题
AI Agent:请问你之前问的是什么 Redis 问题?能再说一下你的配置吗?

我又把昨天的背景说了一遍。这让我很沮丧——大部分 AI Agent 的记忆,似乎只存在于当前对话窗口里。

场景二:使用 OpenClaw

我:帮我优化一下 Redis 配置
OpenClaw:好的,请告诉我...
(隔了好几天,中间聊了很多别的事)
我:对了,上次 Redis 那个 maxmemory-policy 改成 allkeys-lru 之后,又遇到新问题了
OpenClaw:你是说那个 4GB 内存、用作缓存的 Redis 实例吗?我看看之前的配置...

我愣了一下——它居然记得。而且不是模糊的“你之前问过 Redis”,是精确到“4GB、缓存”这些细节。

这是怎么做到的?我翻了一遍 OpenClaw 的源码和文档,发现它的 Memory 机制设计得挺有意思。

1. 记忆存储:答案简单到出乎意料

我原本以为会有一个向量数据库,或者什么复杂的知识图谱。

结果打开 ~/.openclaw/workspace/ 目录一看:

memory/
├── 2026-02-23.md
├── 2026-02-22.md
└── MEMORY.md

就是几个 Markdown 文件。

我的第一反应是:这能行?

后来我用了一段时间才明白,这个设计其实很聪明:

第一,我可以直接修改。 有一次 OpenClaw 记错了我的服务器 IP,我直接用 VS Code 打开 MEMORY.md 改了一行,问题解决。如果记忆存在向量数据库里,我连在哪修改都找不到。

第二,可以用 Git 管理。 我把 workspace/ 目录放进了 Git 仓库,每次 AI 学到了新东西,我就能看到 diff。有一次它莫名其妙记了一条“用户喜欢吃香菜”,我立刻 git checkout 回滚了。

第三,迁移机器直接拷贝。 不需要导出导入,cp -r 就行。

当然,这只是存储。真正让它能回忆起来的,是后面的搜索机制。

2. 两层记忆结构:分工明确

OpenClaw 默认采用两层结构来存储记忆:

OpenClaw Memory 架构概览:双层记忆与混合搜索

每日日志memory/2026-02-23.md

这个文件是仅追加(append-only)的,不修改。每次对话开始时,系统会自动加载今天和昨天的日志。

为什么要加载昨天的?因为大部分情况下,你今天问的问题跟昨天有关,跟上个月关系不大。这个设计很实用——不会塞太多无关内容,又不会漏掉近期的上下文。

长期记忆MEMORY.md

这个文件需要手动维护,用来存储那些值得长期记住的东西——比如你的个人偏好、常用配置、重要决策。

有一个细节让我印象深刻:MEMORY.md只在私聊中加载,群聊时不会读取。

我试了一下,确实如此。在群里问 OpenClaw “我的服务器 IP 是多少”,它说不知道;私聊问,它立刻回答。这个安全设计很关键——你不会想在群里暴露自己的敏感信息。

OpenClaw 工作区记忆结构图

3. 混合搜索:向量与关键词缺一不可

OpenClaw 提供了 memory_searchmemory_get 两个工具供 AI Agent 调用。

memory_search 是语义搜索,memory_get 是按文件路径精确读取。

但真正让我感兴趣的是它的混合搜索——同时使用向量相似度和 BM25 关键词匹配。

我做过一个测试:

搜索 REDIS_PASSWORD 这个环境变量名。

纯向量搜索:找不到。因为 REDIS_PASSWORDredis 密码配置 在语义上确实不像。

混合搜索:立刻定位到。因为 BM25 精确匹配了这个词。

反过来,搜索“之前那个性能问题”:

纯 BM25:找不到。因为记忆里写的是“响应时间太慢”,没有“性能”两个字。

混合搜索:找到了。向量搜索能理解“性能问题”和“响应时间太慢”是一回事。

这个组合确实比单一方案更靠谱,它平衡了语义理解和精确匹配。

OpenClaw 混合搜索架构流程图

4. 时序衰减:最惊艳的功能设计

这部分是我觉得 OpenClaw Memory 最用心的设计。

我之前维护过一个持续半年的项目,记忆文件积累了几百个。搜索“部署流程”,返回的结果全是半年前的——早就废弃了。

时序衰减解决的就是这个问题:新记忆权重高,老记忆权重低

原理很简单:halfLife 参数的意思是“多少天后权重降到一半”。比如设成 14 天,那 14 天前的记忆就剩 50% 权重,28 天前剩 25%,以此类推。

我用的配置是 halfLifeDays: 14

  • 今天:100%
  • 两周前:50%
  • 一个月前:约 22%
  • 三个月前:约 1%,基本不出现了

但有个例外——MEMORY.md 和非日期文件(比如 memory/projects.md)不会衰减。这些是永久记忆,不会因为时间久了就消失。

时序衰减效果对比 (Temporal Decay Comparison)

另一个相关功能是 MMR 多样性重排

我搜索“数据库优化”,以前返回的 10 条结果有 8 条都在讲索引——同一个角度重复了。MMR 会刻意打散结果,让它们涵盖索引、连接池、查询重写等不同方向。

这两个功能都需要在配置里显式开启,后面我会给出具体例子。

5. 什么时候考虑 QMD 后端?

默认的 SQLite 索引器够用,但如果你要索引的目录比较多、文档量比较大,可以考虑 QMD。

QMD 是一个独立的搜索服务,把 BM25、向量搜索、重排序整合在一起。性能比 SQLite 好,但需要额外安装。

我用过一段时间,检索速度确实快。不过它目前还是实验性功能,正式环境用之前建议先充分测试。

好了,原理讲得差不多了。下面是实操部分——三个典型场景的配置示例,都是我踩过坑总结出来的。

6. 场景一:完全离线,不依赖云服务

如果你和我一样,不想把任何数据传到云端,可以使用本地嵌入模型。

前置工作

pnpm approve-builds
# 选择 node-llama-cpp
pnpm rebuild node-llama-cpp

这一步是编译本地推理引擎,第一次会有点慢。

配置文件 ~/.openclaw/config.json5

{
  agents: {
    defaults: {
      memorySearch: {
        provider: "local",
        local: {
          // 首次使用会自动下载,模型约 600MB
          modelPath: "hf:ggml-org/embeddinggemma-300m-qat-q8_0-GGUF/embeddinggemma-300m-qat-Q8_0.gguf"
        },
        fallback: "none",  // 本地失败不回退到远程

        query: {
          hybrid: {
            enabled: true,
            vectorWeight: 0.7,
            textWeight: 0.3
          }
        },

        // 除了默认的 memory/ 目录,还想索引哪些
        extraPaths: [
          "~/notes/tech",
          "~/projects/docs"
        ],

        cache: {
          enabled: true,  // 开启缓存,避免重复索引
          maxEntries: 50000
        }
      }
    }
  }
}

我踩过的坑

  1. 模型下载慢:国内网络可能要挂代理,或者手动下载到本地再指定路径。
  2. 首次索引慢:几十个文件可能要几分钟,后面有缓存就快了。
  3. 内存占用:本地推理需要 1-2GB 内存,小机器慎用。

7. 场景二:索引多个目录,使用 QMD 后端

如果你想索引的目录不止 memory/,还有项目文档、技术笔记等,可以考虑 QMD 后端。它比默认的 SQLite 性能更好,但需要额外安装。

安装 QMD

bun install -g https://github.com/tobi/qmd
brew install sqlite  # macOS 需要支持扩展的版本
qmd --version

配置

{
  memory: {
    backend: "qmd",
    citations: "auto",

    qmd: {
      searchMode: "search",
      includeDefaultMemory: true,

      // 索引额外的目录
      paths: [
        { name: "projects", path: "~/projects", pattern: "**/*.md" },
        { name: "notes", path: "~/notes", pattern: "**/*.md" }
      ],

      update: {
        interval: "5m",
        debounceMs: 15000,
        onBoot: true
      },

      limits: {
        maxResults: 10,
        timeoutMs: 4000
      }
    }
  }
}

我的经验

  • QMD 会自动管理索引,不需要手动触发。
  • 文件修改后,最多等 15 秒(debounceMs)就会重新索引。
  • 如果 QMD 服务挂了,OpenClaw 会自动回退到内置索引器,不会完全不可用。
  • 缺点是配置稍微麻烦,而且目前还是实验性功能。

8. 场景三:长期项目,需要时序衰减

这是我目前在用的配置,适合持续数月的项目:

{
  agents: {
    defaults: {
      memorySearch: {
        provider: "openai",
        model: "text-embedding-3-small",
        remote: {
          apiKey: "${OPENAI_API_KEY}"
        },

        query: {
          hybrid: {
            enabled: true,
            vectorWeight: 0.6,
            textWeight: 0.4,

            mmr: {
              enabled: true,
              lambda: 0.7  // 偏向相关性
            },

            temporalDecay: {
              enabled: true,
              halfLifeDays: 14
            }
          }
        },

        extraPaths: [
          "~/projects/main-project/notes"
        ]
      }
    }
  }
}

效果对比

场景 以前(无衰减) 现在(有时序衰减)
搜索部署流程 返回 3 个月前的旧流程 返回上周更新的
搜索 API 配置 新旧混在一起,难以分辨 近期配置排前面
查历史决策 需要手动翻找 历史还在,只是权重低

9. SQLite 还是 QMD,该怎么选?

上面介绍了 QMD 后端,你可能会问:那我到底该用哪个?

简单说一下我的理解:

SQLite 后端(默认)
开箱即用,不需要额外配置。适合个人使用、文档不太多(几百个以内)的场景。

QMD 后端
需要单独安装,但性能更好。适合文档比较多、想索引多个目录的场景。缺点是配置稍微麻烦一点,而且目前还是实验性的。

我的选择

  • 文档不多:SQLite 后端够用了。
  • 文档多、目录多:QMD 后端,性能更稳。

不管选哪个,记忆的源头都是本地的 Markdown 文件——我能看到、能改、能用 Git 管理。这正是 OpenClaw Memory 最打动我的地方。

10. 几个实用小技巧

1. 定期清理每日日志
用久了 memory/ 目录会很大,我每月归档一次:

mkdir -p memory/archive/2026-01
mv memory/2026-01-*.md memory/archive/2026-01/

2. 敏感信息只放 MEMORY.md
MEMORY.md 只在私聊加载,群聊看不到。密码、地址这类敏感信息,只往这里写。

3. 善用 extraPaths
除了 memory/ 目录,我还会把项目文档、技术笔记都加到 extraPaths 里。这样搜索时,AI 能同时参考历史对话和项目资料,思考更全面。

4. 如果不需要高级搜索
如果只想用简单的文件存储功能,不需要向量搜索,可以直接禁用记忆插件:

{
  plugins: {
    slots: {
      memory: "none"
    }
  }
}

写到这里,我想回到开头的那个场景。

那个关于 Redis 配置的问题,后来我用 OpenClaw 解决了。它不仅记得我之前的配置,还记得我当时说“这个实例主要做缓存,对一致性要求不高”——这句话我自己都快忘了。

一个真正好用的记忆系统,就应该是这样:你不需要刻意提醒,它会自己记住关键上下文;当你想找的时候,它能在合适的时间点把合适的信息递给你。

OpenClaw Memory 离完美还有距离(比如本地嵌入模型的首次配置还是有点繁琐),但它的设计思路是对的——用最简单的技术(Markdown + 本地文件),解决最实际的问题(AI 的长期记忆)。

如果你也在寻找或构建一个有长期记忆能力的 AI Agent,不妨去它的 GitHub 仓库 看看,或许能给你带来一些启发。

相关资源

你对 AI 智能体的记忆系统有什么看法或实践经验?欢迎在 云栈社区 与更多开发者交流探讨。




上一篇:AI Agent如何搅动2028年宏观经济?我们仔细盘点了这篇爆款文的关键论点与硬伤
下一篇:运营复盘:决定项目成败与个人成长的决定性瞬间
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-25 19:43 , Processed in 0.757411 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表