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
| 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 个差异:
| 字段 | OpenAI | MiniMax |
|---|---|---|
| 请求体 | {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:defaultprofile 的 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 一升级就没了——这是最容易被忽略的坑
文章评论