被OpenClaw(原Clawdbot/Moltbot)看上的向量数据库是?

OpenClaw (原名 Clawdbot/Moltbot)是当下超级火爆的(截止目前Github Star数 161K)、开源、可自托管的个人 AI 智能体(Agent)框架。其官方唯一实现的第三方memory plugin就是——LanceDB! 本文将为你剖析 OpenClaw 的 LanceDB memory plugin 的实现。

OpenClaw的核心定位是让 AI 成为能实际操作用户设备、拥有持久化记忆并能主动发起任务的“数字助手”,而不只是一个聊天机器人。在过去几周持续爆火:

picture.image

架构和核心组件

OpenClaw的架构图:

picture.image

由架构图可以看出 Agent Runner是其中最关键的组件之一。在与 Agent Runner 交互时,高质量的上下文供给是其能否准确理解意图、完成复杂任务的关键。广义上,Agent Runner 的上下文主要来自四个方面:

  • 长期知识 (Durable Knowledge) :这是 Agent Runner 关于世界、特定领域或用户的持久化事实与偏好,如同其“固定记忆”,例如用户的技术栈偏好或固有的写作风格。
  • 任务记忆 (Task Memory) :在执行一个长周期、多步骤任务时,Agent Runner 会产生并记录一系列中间产物、决策和观察,这些构成了任务记忆,确保了复杂工作的连续性。
  • 会话历史 (Conversational History) :即与用户的完整对话记录,它不仅包含显式的指令,也蕴含了需要模型理解的隐式意图,是上下文最直接的来源。
  • 外部资源 (External Resources) :包括代码库、技术文档、API 规范、网页等 Agent Runner 在执行任务时需要动态查阅的外部资料,为其提供超出自身知识范围的信息。

这四类上下文通过不同的机制被检索、注入、持久化或更新,共同构成了 Agent Runner 理解和执行任务的基础。下图已包含各类上下文对应的典型目录位置。

picture.image

在 OpenClaw 项目中,这四类上下文分别通过不同的文件、目录和代码模块进行管理。

  • 长期知识(Durable Knowledge)

    • 目录/文件位置

      • 工作区~/.openclaw/workspace 是核心工作目录。
      • 精选记忆MEMORY.md 文件用于存放精选的长期记忆,仅在私聊时加载。
      • 每日记忆memory/YYYY-MM-DD.md 文件作为每日记忆日志。
      • 索引存储~/.openclaw/memory/<agentId>.sqlite 是内置的 SQLite 索引文件。
      • QMD 备选~/.openclaw/agents/<agentId>/qmd/… 用于存放 QMD 后端的索引与配置。
  • 任务记忆(Task Memory)

    • 目录/文件位置memory/YYYY-MM-DD[-slug].md 文件由钩子生成,作为特定任务或会话的快照。
  • 会话历史(Conversational History)

    • 目录/文件位置

      • 状态目录~/.openclaw/agents/<agentId>/sessions/
      • sessions.json:存储会话元数据,如 sessionId、token 计数、memoryFlush 状态等。
      • <sessionId>.jsonl:以仅追加(Append-only)的 JSONL 格式记录完整的对话树,包括消息、工具调用和压缩摘要。
  • 外部资源(External Resources)

    • 配置与挂载

      • agents.defaults.memorySearch.extraPaths:此配置项允许递归地索引外部的 Markdown 文件夹,将其纳入记忆搜索范围。
      • memory.qmd.paths:用于声明 QMD 的集合源,使其可以索引任意位置的文档。
Memory

接下来,我们将聚焦于memory模块,解读openclaw在该模块的设计。整体上,我们将memory的实现分为两类:

  • File/backend based:基于文件系统上裸存的markdown文件,以及backend充当索引与检索的存储引擎;
  • LanceDB based:基于面向多模的Lance文件格式而构建的轻量级LanceDB数据库一体化实现;

File/Backend Based

定义

OpenClaw 的 Memory 被明确定义为存储在 Agent 工作区(workspace)中的纯文本 Markdown 文件。这些文件是记忆的“真实之源”(Source of Truth),模型仅通过读写这些文件来“记忆”信息。其内容来源(MemorySource)主要有两种:持久化的 Markdown 文件(memory)和临时的会话历史记录(sessions)。

picture.image

说明

  • memory 是OpenClaw记忆系统的持久化核心,通过本地Markdown文件长期存储用户偏好、关键信息等;
  • session 是临时会话层,用于保存单次交互的上下文历史,支持即时对话连续性。

两者共同构成OpenClaw的记忆数据来源,分别对应长期记忆与短期会话上下文。

memory 不仅仅是原始文本,其在系统中的表示还包含结构化信息。例如,一次搜索结果 MemorySearchResult 会包含文件路径、起止行号、相关度分数、文本片段和来源等元数据,这使得 Agent 可以精确地引用和读取记忆内容。

分层

  • 当前实现:分为两层核心的 Markdown 文件结构:

    • 日常日志层: memory/YYYY-MM-DD.md,用于记录每日的、时序性的信息, bersifat append-only。
    • 核心记忆层: MEMORY.md,用于存放经过提炼的、更为稳定和持久的核心事实与偏好。
~/.openclaw/workspace/
  memory.md                    # small: durable facts + preferences (core-ish)
  memory/
    YYYY-MM-DD.md 
  • 实验性的研究:扩展出bank/ 目录,下设 world.md(客观事实)、experience.md(Agent 自身经历)、opinions.md(主观判断)以及 entities/(实体信息库)等:
~/.openclaw/workspace/
  memory.md                    # small: durable facts + preferences (core-ish)
  memory/
    YYYY-MM-DD.md              # daily log (append; narrative)
  bank/                        # “typed” memory pages (stable, reviewable)
    world.md                   # objective facts about the world
    experience.md              # what the agent did (first-person)
    opinions.md                # subjective prefs/judgments + confidence + evidence pointers
    entities/
      Peter.md
      The-Castle.md
      warelay.md
      ...

Backend

Backend 是指负责处理 Memory 文件索引、查询和管理的底层引擎。它的存在是为了解决直接操作大量、分散的 Markdown 文件在检索效率和语义理解上的不足。通过 backend,系统能将非结构化的文本转化为可快速、精确、甚至语义化查询的结构化索引,核心是为了提升“召回”(Recall)能力。

OpenClaw 提供了两种 backend 实现:

  1. builtin:内置的默认后端。它使用 SQLite 作为索引数据库,结合 fts5 扩展实现全文检索(BM25 算法),并能通过 sqlite-vec 扩展支持向量搜索。
  2. qmd (实验性):一个外部的、本地优先的搜索 sidecar 工具。它提供了更高级的混合搜索能力,集成了 BM25、向量搜索和重排序(reranking)。

索引

核心流程是:文件扫描与变更检测 → 内容分块(Chunking)→ 文本嵌入(Embedding)→ 数据写入 SQLite。它支持对 memorysessions 两类源进行索引,通过混合使用向量索引(sqlite-vec)与关键词索引(FTS5)实现语义加关键词的混合检索。

picture.image 索引类别和存储的核心设计:

  1. 基础表

    1. files: 存储已索引文件的元数据,如路径、哈希值、修改时间等。
    2. chunks: 存储文本分块(chunk)的核心信息,包括分块文本内容、来源文件路径、起止行号,以及最重要的嵌入向量(以 JSON 字符串形式存储)。
  2. 关键词索引

    1. chunks_fts:这是一个基于 chunks 表创建的 FTS5 (Full-Text Search) 虚拟表,专门用于高效的关键词检索和 BM25 排序。
  3. 向量索引

    1. chunks_vec:这是一个基于 sqlite-vec 扩展创建的虚拟表,存储分块的 ID 和其对应的向量数据(通常为 FLOAT[dims] 类型),用于快速计算向量间的距离(如余弦相似度)。
  4. 辅助表

    1. embedding_cache:用于缓存文本哈希到嵌入向量的映射,避免对相同内容重复进行嵌入计算。
    2. meta:存储索引的元信息,如创建索引时使用的模型、分块参数等,用于判断是否需要全量重建。

LanceDB Based

LanceDB memory 是一条完全独立的链路:它取代了文件系统存memory原始文件 + backend 这套体系。形成了一套完全独立的实现(自己存储文本内容以及embedding,并提供索引、检索能力)。

基于LanceDB实现的memory是以Plugin挂载并让Agent、CLI来识别的。接下来我们先介绍一下什么是plugin。

Plugin

Plugin的作用:决定是否、以及以什么形态把这种查询能力暴露给 agent 和 CLI。

目前,提供两个plugin(memory plugin是排他的,当前只能选择一个):

  • memory-core: 是系统内置的基础内存插件。它本身不包含复杂的存储和 embedding 逻辑,而是作为 openclaw 核心内存管理框架的入口,负责将其能力(如基于 SQLite 的搜索)暴露为标准的 Agent 工具和 CLI 命令。
  • memory-lancedb: 是一个 可选的、功能完备的第三方长时记忆解决方案。它自带了独立的存储(LanceDB)、独立的 embedding 能力(OpenAI API)和一套更高级的记忆操作工具(memory_recall, memory_store, memory_forget)。它通过钩子(Hooks)实现了记忆的自动捕获(auto-capture)和自动召回(auto-recall),提供了一种“开箱即用”的智能记忆体验。

LanceDB plugin

其核心思想是将非结构化的文本信息,转换为高维度的向量,并利用向量间的距离来衡量信息的相似度。整个系统的数据流清晰而高效,涵盖了从信息输入、处理、存储到最终利用的全过程。

picture.image Memory 插件的定义包含如下要素:

  • Tool:

    • memory_recall:search
    • memory_store:save
    • memory_forget:delete
  • CLI commands:

    • list
    • search
    • stats
  • Lifecycle Hooks:

    • before_agent_start:如果开启自动回忆(autoRecall),在每次对话前自动检索相关记忆,注入到 prompt 上下文;
    • agent_end:如果开启自动抽取(autoCapture),会在对话结束后自动从消息中抽取“值得记住”的句子并写入 LanceDB;
  • Service:

    • start/stop

该插件的逻辑主要集中在几个关键文件中,各司其职:

openclaw/extensions/memory-lancedb/

  index.ts: 插件主入口。定义了整个插件的生命周期、工具、CLI 命令和服务。所有核心逻辑的编排都在这里完成。

  config.ts: 配置模型与解析。定义了插件所需的配置项(如 OpenAI API Key、数据库路径等)的数据结构、默认值和解析逻辑。

  openclaw.plugin.json: 插件元数据。向 OpenClaw 核心系统声明插件的 ID、类型、配置 Schema 以及在 UI 上的显示提示(uiHints),使得插件可以被正确加载和配置。

  index.test.ts: 单元与端到端测试。确保插件的各个功能模块(配置解析、工具执行、钩子逻辑等)按预期工作。

  • LanceDB memories 表结构

所有捕获的记忆最终都存储在 LanceDB 的 memories 表中。该表结构为向量化检索和元数据过滤提供了基础。

字段名类型含义约束 / 默认值示例检索相关说明
idString每条记忆的唯一标识符。主键,由插件自动生成的 UUID。"a1b2c3d4-e5f6-..."用于通过 memory_forget 工具精确删除记忆。
textString记忆内容的原始文本。非空。"我偏好使用 TypeScript。"该文本是生成向量嵌入的来源。
vectorNumber[]text 生成的浮点数向量。非空。[0.1, -0.05, ...]向量维度取决于所选的 OpenAI embedding 模型,例如 text-embedding-3-small1536 维。
importanceNumber记忆的重要性评分,范围 0 到 1。默认值为 0.70.9可用于未来对检索结果进行加权排序,但当前检索逻辑主要依赖相似度分数。
categoryString记忆所属的类别。必须是 MemoryCategory 枚举中的一个值。"preference"可作为检索时的元数据过滤条件(虽然当前 memory_recall 未直接暴露此功能)。
createdAtNumber记忆创建时的 Unix 时间戳(毫秒)。由插件在写入时自动生成(Date.now())。1678886400000可用于实现基于时间的检索策略,例如“最近的记忆”。
  • 记忆类别(MemoryCategory)

MemoryCategory 是一个预定义的枚举类型,用于对捕获的记忆进行分类。分类主要依赖于对文本内容的启发式规则匹配,也可以在调用 memory_store 工具时手动指定。

类别名含义解释自动捕获判定信号(正则语义)典型示例如何覆盖
preference用户的个人偏好、喜好或厌恶。这类记忆帮助模型更好地适应用户的个性化需求。包含明确表达偏好的词汇,如 “喜欢 (like)”、“偏爱 (prefer)”、“讨厌 (hate)”、“想要 (want)” 等。 `/preferradšilike
fact关于世界或特定领域的客观事实、陈述。包含常见的系动词,如 “是 (is/are)”、“有 (has/have)” 等,用于构成事实陈述句。 `/isarehas
decision由用户或模型做出的明确决定、计划或结论。包含表示决策或意图的词汇,如 “决定 (decided)”、“将使用 (will use)” 等。 `/rozhodlidecidedwill use
entity指代具体实体的信息,如联系方式、名称、标识符等。包含电话号码、电子邮件地址,或 “被称为 (is called)” 等标识性短语。 `/+\d{10,}@[\w.-]+.\w+is called
other无法归入以上任何类别的其他记忆,作为默认兜底项。当文本不匹配任何其他类别的判定规则时,会被归为此类。“昨天天气不错。”调用 memory_store 时设置 category: "other",或不提供 category 参数。

Memory跟其他组件的交互

  1. Agent 工具 (Tools) :Agent 在执行任务时,可以主动调用 memory_searchmemory_get 工具来查询和读取记忆库。这是最直接的使用方式。
  2. CLI 命令行:用户可以通过 openclaw memory 系列命令手动管理内存,包括查看状态 (status)、触发索引 (index) 和执行搜索 (search)。
  3. 自动同步/索引 (Auto Sync/Indexing) :系统通过文件监视(watch)和定时任务(interval)自动检测 Memory 文件的变更,并异步更新索引,确保记忆库的时效性。
  4. 自动内存刷新 (Auto Memory Flush) :在会话历史过长、即将被压缩(compaction)前,系统会自动触发一个静默的 Agent turn,提示模型将当前重要的上下文信息存入 Memory 文件,以防止关键信息因压缩而丢失。
  5. 钩子 (Hooks) :通过 session-memory 钩子,在 /new 命令执行时,系统会自动将上一个会话的摘要存档到 memory/ 目录中,实现会话的自动归档
总结

OpenClaw 的 memory-lancedb 插件为我们展示了一个优雅而实用的长时记忆系统设计。它不仅提供了强大的基础能力——将文本转化为可检索的向量记忆,更通过巧妙的生命周期钩子设计,实现了记忆的“自动驾驶”,极大地提升了智能体的实用性和用户体验。我们相信 OpenClaw 在众多 memory 库的实现中选择了LanceDB,源于 LanceDB 的一些非常优秀的特性:

  • 本地优先(Local-First):LanceDB作为一个极其轻量的嵌入式数据库,无服务,安装即可用;
  • 多模态存储:支持各种类型(图片、文档、音视频)知识的存储;
  • 多类别索引与混合检索:支持标量、向量、全文索引以及多索引混合检索;

在 Agent 时代,存在海量非结构化的知识需要存储、加工、检索,构建版本管理用于回溯与分析。既可以轻量级本地开发,又可以on cloud无限横向扩展!而 LanceDB/Lance 无疑是非常优秀的选择。另外,大家也可以关注一下,围绕Lance构建的两个生态项目:

0
0
0
0
评论
未登录
暂无评论