AI agent 没有长期记忆就像金鱼——每次对话从零开始。memory_search 是 OpenClaw 内置的长期记忆检索能力,让 agent 能跨越多个会话回忆「上次那个方案」「之前讨论过什么」。
本文分两部分:
它是什么、解决什么问题 怎么从 OpenAI/oLLama 改成 MiniMax(架构 + 关键改造点)
此方法已验证可用,并由 AI 实现,可直接复制发给 OpenClaw 让它照搬复刻。
一、memory_search 是做什么的
1.1 解决什么问题
AI agent 默认每次对话都是全新的——不记得昨天说过什么、上周讨论过什么方案。memory_search 让 agent 能从过去的对话历史、文档、笔记里找到相关内容,跨会话保持连续性。
1.2 它怎么工作(一张架构图)
memory_search 跑在 agent 背后,处理流程:
【写入阶段】(agent 对话时自动跑) 对话 / 文档 ↓ 分块(每块约 400 token) 文本块 ↓ 调 embedding API(每个 provider 实现) 向量(一串数字,代表语义) ↓ 本地 SQLite + 向量库【查询阶段】(agent 调 memory_search 时跑) 用户的问题 ↓ 转成向量 在向量库找「最相似」的 top-k 个块(余弦相似度) + BM25 关键词检索做补充 ↓ 返回带引用的片段(哪个文件、哪一行)→ 给 agent
1.3 跟普通 RAG 的区别
普通 RAG 只索引静态文档。memory_search 索引的是:
agent 的对话历史(每次会话自动加入) 工作区里的文档 agent 自己跑出来的 dream reports(自动洞察笔记)
而且全自动——agent 启动就自动 ingest,不用手动触发或写 ETL 脚本。
1.4 典型使用场景
「那个合同模板用哪一版来着」 「我们之前讨论过用 Qdrant 那个方案」 「老板喜欢先看大纲再写正文」
二、OpenClaw 原生 memory_search 怎么用
OpenClaw 默认只支持两个 embedding provider:
2.1 接口很简单
agent 调用 memory_search 工具,传入「查询关键词」+ 可选「限定语料范围」,返回带引用的相关片段。每个片段带:
来源文件路径 + 行号 相似度分数(语义 + 关键词) 命中片段原文 引用(方便回溯)
2.2 原生 provider
| openai | text-embedding-3-small | OPENAI_API_KEY | |
| ollama | nomic-embed-text |
在 openclaw.json 里配置 memorySearch.provider 和 model 即可启用。
三、改造用 MiniMax 向量模型
3.1 为什么不能直接用
MiniMax 的 embedding API 不是 OpenAI 兼容的——虽然看着像,但实测下来有 4 个差异:
{model, input:[...]} | {model, texts:[...], type:"query"} | |
无 | type: "query"(document 返 2013 错误) | |
{data:[{embedding}]} | {vectors:[...], base_resp:{...}} | |
跟 model 走 | 固定 1536 |
所以不能直接复用 OpenAI 的 adapter,必须自己写一个。
3.2 关键架构:adapter 是什么
OpenClaw 启动时会扫描所有声明了「我能提供 memory embedding」的扩展。每个 adapter 必须实现这个契约:
[memory embedding provider adapter] ├─ id: "minimax-portal" ← OpenClaw 用这个 id 查找你 ├─ defaultModel: "embo-01" ← embedding 模型名 ├─ authProviderId: "minimax-portal" ← 从 auth-profiles.json 读 OAuth token └─ create(options) → { provider: { embedQuery(text) → [1536 个数字] ← 单条查询 embedBatch(texts) → [[1536 个数字], ...] ← 批量(重建索引用) } }
OpenClaw 在需要 embedding 时调你的 adapter:
它从 auth-profiles.json 自动拿 OAuth token 你内部 POST 到 https://api.minimaxi.com/v1/embeddings body 是 {model, texts, type:"query"} 解析 {vectors, base_resp} 响应 返回向量数组
3.3 关键改造点(4 个)
- 请求格式
— body 用 texts 字段(不是 OpenAI 的 input),且必填 type: "query" - 响应格式
— 解析 vectors[] 数组(不是 OpenAI 的 data[].embedding),且要校验 base_resp.status_code === 0 - OAuth 鉴权
— 用 OpenClaw 提供的 helper 从 auth-profiles.json 读 minimax-portal:default profile 的 access token - endpoint URL
— MiniMax 同一个 provider 在 chat 配置里用了 /anthropic/v1,embedding 必须在 adapter 里硬编码https://api.minimaxi.com/v1(不能依赖 provider config,否则会被覆盖成 chat endpoint)
3.4 集成路径(高层步骤)
在 ~/.openclaw/extensions/minimax-portal-embedding/ 创建 user-level extension(不要改 bundled 扩展,npm upgrade OpenClaw 会被覆盖) 实现上面的 adapter(30-100 行)+ 注册扩展的入口文件 用 OpenClaw 自己的 openclaw plugins install 命令安装(不是手动 cp,否则 OpenClaw 不加载) 在 openclaw.json 里把 memorySearch.provider 从 minimax 改成 minimax-portal,加 plugins.allow 白名单 重启 gateway,跑 openclaw memory index --force --agent 让所有 agent 重建索引(每个 agent 约 5-15 分钟)
3.5 让 OpenClaw 自己复刻的指令
直接跟 OpenClaw 说:
「OpenClaw memory_search 不支持 MiniMax(OAuth provider)。要给它加一个 user-level extension:注册一个叫 minimax-portal 的 memory embedding provider,调 MiniMax 的 https://api.minimaxi.com/v1/embeddings(注意 body 用 texts 不是 input,必填 type: "query",响应解析 vectors 数组),用 OAuth token 从 auth-profiles.json 读。装好后所有 agent 跑 memory index --force 重建索引。」
OpenClaw 拿到这段指令,按上面的架构和改造点自己实现即可。
结尾
memory_search 是给 OpenClaw agent 加长期记忆的关键能力。原生支持 openai/oLLama,要用 MiniMax 需要写一个 user-level extension 适配 4 个 API 差异。
两个 takeaway:
- MiniMax 不是 OpenAI 兼容
,必须自己写 adapter(请求体字段、必填 type、响应结构、维度都不同) - adapter 必须装到 user-level 而不是 bundled
,否则 OpenClaw 一升级就没了——这是最容易被忽略的坑
夜雨聆风