引言
你有没有遇到过这种尴尬——AI 助手聊完就忘,每次都要重新交代背景?MemClaw 就是来解决这个问题的。它是 OpenClaw 的记忆插件,结合 Ollama 本地大模型和 Qdrant 向量数据库,能让你的 AI 真正"记住"你说过的每一件事。
本文是我在 Windows 上完整部署 MemClaw + Ollama 的实战记录,重点解决 Ollama 0.19+ API 兼容性问题,以及 cortex-mem-service 源码修复。全程可复现,分享给有同样需求的朋友。
整体架构一览
部署之前,先搞清各个组件之间的关系:
OpenClaw
└── MemClaw 插件 (v0.9.36)
├── Qdrant(向量数据库,端口 6333/6334)
├── cortex-mem-service(记忆服务,端口 8085)
├── LLM → Ollama(qwen2.5:3b,端口 11434)
└── Embedding → Ollama(nomic-embed-text,端口 11434)
Web 控制台
└── Cortex Memory Insights(端口 8159)
核心流程很清晰:用户消息通过 MemClaw 存入 Qdrant,检索时用 Embedding 模型生成向量做语义搜索,LLM 负责理解和生成回答。
环境准备与组件版本
| 组件 | 版本 | 说明 |
|---|---|---|
| OpenClaw | 2026.4.2 | 基础运行环境 |
| Ollama | 0.19.0 | 本地大模型推理 |
| MemClaw 插件 | 0.9.36 | 记忆管理插件 |
| Qdrant | 1.17.1 | 向量数据库 |
| cortex-mem-service | 2.7.0 | 记忆服务(需源码修复) |
| LLM 模型 | qwen2.5:3b | ~1.9GB,推荐使用 |
| Embedding 模型 | nomic-embed-text | 274MB |
核心问题修复(重点)
部署过程中踩了三个坑,其中最关键的是 Ollama 0.19+ 的 API breaking change,这个不修的话 cortex-mem-service 完全跑不起来。
问题一:Embedding API 参数变更
Ollama 0.19+ 将 embedding API 的参数名从 input 改成了 prompt,且不再接受批量数组请求。需要修改 cortex-mem-core/src/embedding/client.rs:
// 修改前(Ollama 旧版本)
struct EmbeddingRequest {
prompt: Vec<String>, // ❌ 数组格式
model: String,
}
// 修改后(Ollama 0.19+)
struct EmbeddingRequest {
prompt: String, // ✅ 单个字符串
model: String,
}
// 遍历每个文本,单独调用 API
for text in texts.iter() {
let request = EmbeddingRequest {
prompt: text.clone(),
model: self.config.model_name.clone(),
};
// ... 调用 API
}
问题二:API 端点格式差异
Ollama 有两套 API 格式——原生格式和 OpenAI 兼容格式,配置错了就会 404:
[llm]
api_base_url = "http://localhost:11434/v1" # ✅ OpenAI 兼容格式
[embedding]
api_base_url = "http://localhost:11434/api" # ✅ Ollama 原生格式
问题三:Qdrant 端口与协议
部分场景下 HTTP/2 通过 WSL 有问题,解决方案是直接用 Windows 原生 Qdrant 二进制:
$qdrantBin = "$env:USERPROFILE\.openclaw\extensions\memclaw\node_modules\@memclaw\bin-win-x64\bin\qdrant.exe"
Start-Process -FilePath $qdrantBin
config.toml 配置详解
在 C:\Users\ysong\.openclaw\extensions\memclaw\config.toml 中写入以下配置:
[qdrant]
url = "http://localhost:6334"
collection_name = "cortex-memory"
embedding_dim = 768
timeout_secs = 30
[embedding]
api_base_url = "http://localhost:11434/api"
api_key = "ollama"
model_name = "nomic-embed-text"
batch_size = 10
timeout_secs = 60
[llm]
api_base_url = "http://localhost:11434/v1"
api_key = "ollama"
model_efficient = "qwen2.5:3b"
temperature = 0.7
max_tokens = 100
timeout_secs = 60
[server]
host = "0.0.0.0"
port = 8085
cors_origins = ["*"]
[logging]
enabled = false
log_directory = "logs"
level = "info"
[cortex]
enable_intent_analysis = false
服务启动脚本
每次手动启动太麻烦,写一个 PowerShell 脚本一键启动所有服务:
# MemClaw Auto-Start Script
$ErrorActionPreference = "Stop"
Write-Host "Starting MemClaw services..."
# 1. 启动 Qdrant
$qdrantPath = "$env:USERPROFILE\.openclaw\extensions\memclaw\node_modules\@memclaw\bin-win-x64\bin\qdrant.exe"
$qdrantWorkDir = "$env:USERPROFILE\.openclaw\extensions\memclaw"
if (Get-NetTCPConnection -LocalPort 6333 -ErrorAction SilentlyContinue | Where-Object { $_.State -eq "Listen" }) {
Write-Host "Qdrant already running"
} else {
Write-Host "Starting Qdrant..."
Start-Process -FilePath $qdrantPath -WorkingDirectory $qdrantWorkDir
Start-Sleep -Seconds 3
}
# 2. 启动 cortex-mem-service
$cortexPath = "$env:USERPROFILE\.openclaw\extensions\memclaw\node_modules\@memclaw\bin-win-x64\bin\cortex-mem-service.exe"
$configPath = "$env:USERPROFILE\.openclaw\extensions\memclaw\config.toml"
if (Get-NetTCPConnection -LocalPort 8085 -ErrorAction SilentlyContinue | Where-Object { $_.State -eq "Listen" }) {
Write-Host "cortex-mem-service already running"
} else {
Write-Host "Starting cortex-mem-service..."
Start-Process -FilePath $cortexPath -ArgumentList "--config", $configPath -WorkingDirectory $qdrantWorkDir
Start-Sleep -Seconds 5
}
# 3. 验证服务状态
Write-Host "`nVerifying services..."
$qdrantRunning = Get-NetTCPConnection -LocalPort 6333 -ErrorAction SilentlyContinue | Where-Object { $_.State -eq "Listen" }
if ($qdrantRunning) { Write-Host "✅ Qdrant (6333) - running" } else { Write-Host "❌ Qdrant - NOT running" }
try {
$health = Invoke-RestMethod -Uri "http://localhost:8085/health" -TimeoutSec 5
Write-Host "✅ cortex-mem-service - running (status: $($health.status))"
} catch {
Write-Host "❌ cortex-mem-service - NOT running"
}
Write-Host "`nDone."
运行只需执行 .\start-memclaw.ps1,所有服务自动启动并验证状态。
API 测试命令
服务启动后,用以下命令验证功能是否正常:
# 存入一条记忆
$body = @{
role = "user"
content = "今天完成了MemClaw的Ollama embedding API修复,解决了Ollama API从input改为prompt的问题"
} | ConvertTo-Json
Invoke-RestMethod -Uri "http://localhost:8085/api/v2/sessions/default/messages" `
-Method Post `
-ContentType "application/json" `
-Body $body
# 检索记忆
$body = @{
query = "MemClaw embedding 修复"
limit = 3
} | ConvertTo-Json
$r = Invoke-RestMethod -Uri "http://localhost:8085/api/v2/search" `
-Method Post `
-ContentType "application/json" `
-Body $body
$r.data | ForEach-Object {
Write-Host "Score: $($_.score) - $($_.uri)"
}
故障排查速查表
| 问题 | 原因 | 解决方案 |
|---|---|---|
Embedding API error (400) |
prompt 字段格式错误 | 源码修改为单个字符串 |
classification=500 |
模型太大生成慢 | 改用 qwen2.5:3b |
| Qdrant 连接失败 | HTTP/2 WSL 问题 | 使用 Windows 原生 Qdrant |
| LLM API 404 | 端点格式错误 | 使用 /v1/chat/completions |
| 服务无法启动 | config.toml 缺失 | 创建配置文件 |
与 MEMORY.md 的关系
很多人会问:MemClaw 来了,MEMORY.md 还要不要保留?答案是两者共存、互补使用:
| MEMORY.md | MemClaw | |
|---|---|---|
| 定位 | 核心规范、人工维护 | 项目记忆、语义检索 |
| 更新方式 | 手动编辑 | 自动积累 |
| 检索 | 关键词 grep | 语义搜索 |
| 协作 | 各 agent 共享 | 分 session 隔离 |
MEMORY.md 继续用,MemClaw 作为补充检索工具,强强联合。
结语
整个部署过程最大的坑就是 Ollama 0.19+ 的 API breaking change,官方版本没有及时跟进,导致 cortex-mem-service 无法正常使用。本文记录了从源码修复到配置调优的完整路径,希望能帮你少走弯路。
本地 AI 记忆系统一旦跑起来,体验还是很爽的——AI 能记住你们聊过的内容,语义检索精准找到相关记忆,这才是真正好用的个人 AI 助手。如果你也成功部署了,欢迎来交流心得!