ClawXMemory 记忆插件移植部署全记录 —— 从不可能到完全运行
序言
这是一篇来自部署一线的技术日记。记录了将 EdgeClaw 专属的 ClawXMemory 长期记忆插件,成功移植到 OpenClaw 平台上的完整过程。这个过程跨越了数小时的深度分析、三次方案推翻重来、无数次容器崩溃重启,以及最终的成功验收。
背景:为什么要做这件事
我们的 AI 助手体系运行在一台 Intel Celeron J1900 小主机(路由器)上,通过 Docker 容器部署了 OpenClaw——一个多 Agent 网关,连接 Discord、Telegram、WhatsApp 等多个渠道。4 个 Agent(小武、书呆子、小超、小谷)全天候在线,为用户提供服务。
但有一个致命缺陷:Agent 没有长期记忆。 每次对话都是从零开始,之前聊过什么、用户的偏好、正在进行的项目——全部忘得一干二净。
EdgeClaw(OpenClaw 的商业版)有一个强大的记忆插件——ClawXMemory(由 OpenBMB 开发),实现了完整的三层记忆架构:
- L0:原始对话捕获
- L1:LLM 驱动的结构化抽取(摘要、事实、项目)
- L2:时间线与项目索引
- Profile:用户画像持续更新
问题是:这个插件只在 EdgeClaw 上能跑,直接放到 OpenClaw 上会因为三个根本性差异而崩溃。
第一阶段:调研与分析
走过的弯路
最初考虑过三个方案:
- memory-lancedb-pro 插件:需要 AVX 指令集,J1900 不支持,直接淘汰。
- 直接复制 ClawXMemory:插件文件放上去就崩,config validation 报错,无限重启。
- 运行时适配方案(最终方案):深入分析 EdgeClaw 源码,找出差异点,精准打补丁。
三大根因
通过三个并行的 Explore Agent 对 EdgeClaw 源码的深度分析,我们定位了三个根本原因:
根因 1:Config Write Hash Sentinel
ClawXMemory 启动时会调用 reconcileManagedMemoryBoundary() 方法,直接写入 openclaw.json 配置文件。EdgeClaw 内置了 writeConfigSection() API,而 OpenClaw 没有。插件写入失败 → 检测到配置不一致 → 触发重启 → 无限循环。
根因 2:callStructuredJson 不支持 OAuth
L1 抽取需要调用 LLM(通过 callStructuredJson),EdgeClaw 用自己的 OAuth token 直接调用。OpenClaw 没有这个认证通道,LLM 调用直接失败。
根因 3:clearMemoryPluginState OpenClaw 在每次重启时会清理插件状态,导致记忆数据被重置。
第二阶段:设计运行时适配方案
核心思路:不改 OpenClaw 源码,只改插件代码,让插件适应 OpenClaw 的运行环境。
Patch 1:环境变量守卫(runtime.ts)
在 reconcileManagedMemoryBoundary() 方法的最开头插入:
if (process.env.CLAWXMEMORY_SKIP_MANAGED_BOUNDARY === "1") {
this.logger.info?.("[clawxmemory] CLAWXMEMORY_SKIP_MANAGED_BOUNDARY=1; skipping managed config reconciliation");
return "ready";
}
效果:插件永远不会尝试写入 openclaw.json。我们预先把所有配置写好,插件启动时直接读取,皆大欢喜。
Patch 2:extractionModel 覆写(llm-extraction.ts)
在 resolveSelection() 方法中,插入模型覆写逻辑:
const extractionModel = this.config?.plugins?.entries?.["openbmb-clawxmemory"]?.config?.extractionModel;
if (extractionModel) {
modelRef = extractionModel; // 使用配置中指定的模型
}
效果:LLM 抽取不再依赖 EdgeClaw 的 OAuth 认证通道,而是使用我们自己配置的 OpenAI API Key + gpt-4.1-mini 模型。巧妙的是,这里复用了 OpenClaw 原有的全部 provider 解析代码(baseUrl、apiKey、headers),只是把模型引用换了。
配置预写
在 openclaw.json 中预写了 8 项变更:
- 新增
openai-directprovider(gpt-4.1-mini) - 设置
plugins.slots.memory = "openbmb-clawxmemory" - 禁用旧的
memory-core插件 - 启用 ClawXMemory 并配置 extractionModel
- 注册 memory 相关 tools
- 禁用与 ClawXMemory 冲突的内置记忆功能
第三阶段:部署实战
Phase 0-2:顺利
备份、复制插件文件、创建 typebox 符号链接——这几步都很顺利。
Phase 3:补丁之痛
最初想通过 SSH heredoc + python3 内联脚本来修改文件,结果发现复杂的 heredoc 在 SSH 管道中有各种引号转义问题,命令直接挂死。
解决方案:SCP 工作流。 把文件从路由器拉到本地 → 用编辑工具修改 → 推回路由器。虽然多了几步,但稳定可靠。
Phase 4:配置修改
8 项 JSON 修改,用 python3 脚本精确操作,一次成功。
Phase 5:容器重启 —— 噩梦开始
第一次崩溃:权限问题
docker rm + docker run 重建容器后,发现 /home/node/.openclaw(即宿主机的 /opt/docker/openclaw/config)目录权限是 root:root 700。容器内的 node 用户(uid 1000)根本无法读取配置文件。
原始容器是怎么工作的?这成了一个谜——因为我们已经删掉了原始容器,无法回溯。
修复:chmod 755 + chown 1000:1000。
第二次崩溃:配置验证失败
plugins.entries.openbmb-clawxmemory.config: invalid config: must NOT have additional properties
这是最意想不到的问题。我们在 config.ts(TypeScript 类型定义)中添加了 extractionModel 字段,但 OpenClaw 的配置验证不看 TypeScript——它看的是 openclaw.plugin.json 清单文件中的 configSchema,那里有 additionalProperties: false。
修复:在 openclaw.plugin.json 的 configSchema.properties 中添加 extractionModel 字段定义。
第三次:成功!
修复清单文件后重启,容器终于稳定运行。但首次启动要等待 jiti(TypeScript 即时编译器)编译约 780 个缓存文件,在 J1900 上需要 3-4 分钟,期间 CPU 飙到 136%,内存涨到 1.4GB,没有任何日志输出。这段沉默的等待是最考验耐心的。
第四阶段:验收
当日志中出现以下内容时,我知道成功了:
[clawxmemory] CLAWXMEMORY_SKIP_MANAGED_BOUNDARY=1; skipping managed config reconciliation
[clawxmemory] dynamic memory runtime ready: active memory slot is ClawXMemory.
[clawxmemory] dashboard ready at http://127.0.0.1:39394/clawxmemory/
随后的测试对话中,完整的记忆管线开始运转:
- L0 捕获:多个 agent(书呆子、小武、小谷)的对话全部被捕获
- L1 LLM 抽取:7 次成功调用 gpt-4.1-mini,0 次失败,中文摘要质量优秀
- L2 索引:时间线和项目索引自动生成
- Profile:用户画像持续更新
- Recall:记忆回忆成功注入对话上下文(
recall mode=llm injected=true)
LLM 抽取的摘要示例:
- "用户询问助手记忆力恢复情况,助手回顾了当前记忆系统的状态和已知项目,确认了核心工作体系和未解决的部署失败问题。"(projects=4, facts=2)
- "用户询问助理为何被称为书呆子,助理解释其钻研细节和推理过载的特点。"(facts=1)
记忆数据库文件 memory.sqlite 在验收时已增长到 557KB + 4MB WAL,说明数据在持续写入。
技术总结
最终修改清单
| 文件 | 修改内容 |
|---|---|
runtime.ts |
添加 env var 守卫,跳过配置写入 |
llm-extraction.ts |
添加 extractionModel 覆写 |
config.ts |
添加 extractionModel 类型定义 |
openclaw.plugin.json |
添加 extractionModel 到 configSchema |
openclaw.json |
8 项配置变更 |
关键教训
- OpenClaw 的配置验证流程:先验证 JSON Schema(清单文件),再加载 TypeScript。改了 TS 不改清单文件等于白改。
- Docker 容器重建的陷阱:
docker rm+docker run会丢失原始容器的运行时状态和权限设置。 - jiti 编译时间:在低端 CPU 上,首次编译可能需要数分钟。不要因为没有日志输出就以为容器挂了。
- SCP 比 SSH heredoc 更可靠:复杂的文件编辑不要试图通过 SSH 管道内联完成。
运行成本
使用 OpenAI gpt-4.1-mini 进行 L1 抽取,单次调用约 $0.001-0.003。按 4 个 agent 每天 150-300 次对话估算,每月成本约 $5-15,完全可接受。
尾声
从 "这个插件不可能在 OpenClaw 上运行" 到 "全线运行,记忆管线完整",这个过程让我深刻体会到:所谓的"不可能",往往只是还没找到正确的切入点。EdgeClaw 和 OpenClaw 的差异看似巨大,但归根结底只有三个关键函数的行为不同。精准定位、最小化修改、逐步验证——这才是工程实践的正道。
现在,Agent 们终于有了记忆。它们会记住每一次对话、每一个项目、每一个关于用户的事实。从白纸一张到积累成册,这正是 ClawXMemory 的魅力所在。
部署日期:2026 年 4 月 10 日 平台:OpenClaw on Docker / Intel J1900 / 8GB RAM 记忆插件:openbmb-clawxmemory(从 EdgeClaw 源码移植) LLM 后端:OpenAI gpt-4.1-mini
💬 评论 (0)
暂无评论,来说第一句话吧~
发表评论