Windows 10 · DeepSeek API · OpenClaw 2026.4.24 · claude-mem v12.4.7 · 2026-04-28
一、这篇教程解决什么问题
一句话定位:在 Windows 上把 claude-mem 持久化记忆插件接入 OpenClaw Gateway,使用 DeepSeek 作为 AI Provider,并解决 Windows 环境下独有的兼容性问题。
阅读前提:
- 已安装 OpenClaw Gateway,能通过 WebChat 正常对话
- 拥有 DeepSeek API Key
- 使用 Windows 操作系统
- 有基本的命令行操作经验
读完能得到什么:一个具备跨会话持久记忆的 AI 助手——它能记住你每次工具调用、生成 AI 摘要、通过 Chroma 向量数据库支持语义搜索。
二、环境准备
2.1 依赖清单
| 组件 | 最低版本 | 说明 |
|---|---|---|
| Node.js | 22.14+ | 已有 OpenClaw 则已满足 |
| Bun | ≥ 1.1.14 | Worker 运行时 |
| Git | 任意版本 | 获取源码 |
| uv / uvx | ≥ 0.11 | Python 包管理器 |
| Python | 3.13 | uvx 自动管理,无需手动安装 |
2.2 逐条验证
node--version# 应输出 v22.14.0 或更高bun--version# 应输出 1.x.xgit--version# 应输出 git version 2.x.xuv--version# 应输出 uv 0.11.x 或更高如果缺少某个组件:
- Bun:
powershell -c "irm bun.sh/install.ps1 | iex" - uv:
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
三、安装步骤
3.1 拉源码并安装依赖
cd C:\SoftWare\OpenClaw git clone https://github.com/thedotmack/claude-mem.git cd claude-mem npm install3.2 安装 Python 3.13
claude-mem 内部通过chroma-mcp管理向量数据库,chroma-mcp是一个 Python 包,需要 Python 3.13:
uv python install 3.13系统已安装 Python 3.14 不影响——
uvx --python 3.13会使用 uv 独立管理的 Python 3.13,两者隔离。
3.3 构建
node scripts/build-hooks.jsesbuild 将 TypeScript 源码打包为plugin/scripts/worker-service.cjs(约 2.4MB)。
3.4 Worker 配置
文件:C:\Users\Friend\.claude-mem\settings.json
{"CLAUDE_MEM_PROVIDER":"openrouter","CLAUDE_MEM_OPENROUTER_MODEL":"deepseek-chat","CLAUDE_MEM_OPENROUTER_API_KEY":"sk-你的DeepSeek-API-Key","CLAUDE_MEM_MODE":"code--zh","CLAUDE_MEM_WORKER_PORT":"37777","CLAUDE_MEM_CHROMA_ENABLED":"true","CLAUDE_MEM_CHROMA_MODE":"local"}为何
PROVIDER填openrouter但实际用的是 DeepSeek?见 Debug #3。
3.5 创建插件目录
mkdir C:\Users\Friend\.openclaw\extensions\claude-mem-native在该目录下创建三个文件:
文件一:C:\Users\Friend\.openclaw\extensions\claude-mem-native\openclaw.plugin.json
{"id":"claude-mem-native","kind":"extension","name":"Claude-Mem Native Plugin"}文件二:C:\Users\Friend\.openclaw\extensions\claude-mem-native\package.json
{"name":"claude-mem-native","openclaw":{"extensions":["./index.js"]}}文件三:C:\Users\Friend\.openclaw\extensions\claude-mem-native\index.js
从C:\SoftWare\OpenClaw\claude-mem\openclaw\dist\index.js复制过去。
3.6 Gateway 配置
⚠️ 必须先停 Gateway,否则编辑会被自动回滚:
openclaw gateway stop编辑C:\Users\Friend\AppData\Roaming\openclaw\openclaw.json,在plugins中添加:
"plugins":{"load":{"paths":["C:/SoftWare/OpenClaw/claude-mem","C:/Users/Friend/.openclaw/extensions/claude-mem-native"]},"entries":{"claude-mem-native":{"enabled":true,"config":{"project":"openclaw","syncMemoryFile":true}}}}⚠️ 不要设置
"memory"字段——OpenClaw 不识别,会自动回滚。
⚠️ 路径中使用正斜杠/,不要用反斜杠。
保存后重新启动:
openclaw gatewaystart3.7 打补丁
构建完成后必须运行补丁脚本:
node C:\SoftWare\OpenClaw\claude-mem\patch_worker.cjs脚本会修改C:\SoftWare\OpenClaw\claude-mem\plugin\scripts\worker-service.cjs,具体内容和原理见 Debug #3、#4。
如果这个文件不存在,先跳到 Debug #4 查看完整内容后创建。
3.8 启动与验证
启动 Worker:
C:\Users\Friend\AppData\Roaming\npm\node_modules\bun\bin\bun.exe C:\SoftWare\OpenClaw\claude-mem\plugin\scripts\worker-service.cjs--daemon验证 Worker 是否正常运行:
node-e"require('http').get('http://127.0.0.1:37777/health',r=>r.pipe(process.stdout))"预期输出:
{"status":"ok","timestamp":...}然后启动 Gateway(如果还没启动):
openclaw gateway run启动后观察 Gateway 日志,应出现:
[plugins] [claude-mem] OpenClaw plugin loaded — v1.0.0 (worker: 127.0.0.1:37777)四、Debug #1 — 插件 kind 冲突
报错日志
openclaw plugins list显示 claude-mem 状态为disabled。Worker 运行正常(37777 端口健康),但所有钩子不触发——不会记录工具调用、不会注入上下文、/claude_mem_status命令不可用。
根因
OpenClaw 内置memory-core插件(kind: "memory")占据唯一 memory 槽位。任何外部插件如果也声明kind: "memory",OpenClaw 在加载时自动禁用,不报错、不警告。
一览对比表
| 对比维度 | 修复前 | 修复后 |
|---|---|---|
| kind 字段值 | "memory" | "extension" |
| 与内置 memory-core 关系 | 抢槽位,被禁用 | 共存,不冲突 |
| Gateway 日志 | 插件显示 disabled | Plugin loaded v1.0.0 |
| 四个钩子触发 | ❌ 全部静默跳过 | ✅ before_agent_start / before_prompt_build / tool_result_persist / agent_end |
代码修复
文件:C:\Users\Friend\.openclaw\extensions\claude-mem-native\openclaw.plugin.json
修复前:
{"id":"claude-mem-native","kind":"memory","name":"Claude-Mem Native Plugin"}修复后:
{"id":"claude-mem-native","kind":"extension","name":"Claude-Mem Native Plugin"}改动只有一行:"memory"→"extension"。
验证
openclaw gateway restartGateway 启动日志应出现[claude-mem] OpenClaw plugin loaded — v1.0.0。
五、Debug #2 — workspaceDir 缺失
报错日志
[claude-mem] Skipping observation — tool_result_persist: no workspaceDir插件加载成功,但每次工具调用都被跳过,/claude_mem_status中观察数量始终为 0。
根因
WebChat 会话不会向插件传递workspaceDir字段。插件代码中tool_result_persist检查到该字段为空时直接return,所有工具调用记录全部丢弃。
一览对比表
| 对比维度 | 修复前 | 修复后 |
|---|---|---|
| workspaceDir 值 | undefined(WebChat 不传) | C:/SoftWare/OpenClaw/WorkSpace(fallback) |
| 工具调用记录 | 全部跳过(return) | 正常发送到 Worker |
| 观察数据 | 不生成 | 正常生成 |
代码修复
文件:C:\Users\Friend\.openclaw\extensions\claude-mem-native\index.js
在tool_result_persist事件处理函数中,找到ctx.workspaceDir的引用处(约第 560 行附近),将其替换为带回退的取值:
修复前:
constcwd=ctx.workspaceDir;修复后:
constcwd=ctx.workspaceDir||'C:/SoftWare/OpenClaw/WorkSpace';如果文件中有多处引用,全部替换。
验证
重启 Gateway 后,在 WebChat 中执行任意命令(如dir),然后/claude_mem_status应显示 observation 计数增加。
六、Debug #3 — DeepSeek API 适配
报错日志
[ERROR] [SDK] [session-X] OpenRouter init failed {model=deepseek-chat} OpenRouter API error: 401 - {"error":{"message":"Missing Authentication header","code":401}} [ERROR] [SDK] OpenRouter agent error [ERROR] [SESSION] Generator failedWorker 将观察数据写入 SQLite 正常,但 AI 摘要生成全部失败——每次都在 SDK 初始化时报 401。
根因
claude-mem 内置 SDK 代理仅支持 OpenRouter / Claude / Gemini 三种 Provider,不直接支持 DeepSeek。但 DeepSeek API 与 OpenRouter 的/v1/chat/completions端点格式兼容,只需替换 URL 地址和模型名即可。
一览对比表
| 对比维度 | 修复前 | 修复后 |
|---|---|---|
| API 请求地址 | https://openrouter.ai/api/v1/... | https://api.deepseek.com/v1/... |
| 模型名 | 为空(默认 Claud) | deepseek-chat |
| 实际调用链路 | OpenRouter 代理 → DeepSeek(多一层中转) | DeepSeek API 直连 |
| AI 摘要生成 | 401 报错 | 正常 |
| Provider 配置字段 | "openrouter"(保持不变) | "openrouter"(保持不变) |
settings 变更
文件:C:\Users\Friend\.claude-mem\settings.json
添加模型名配置(Provider 字段本身不变,SDK 仍按 OpenRouter 协议发出请求):
{"CLAUDE_MEM_PROVIDER":"openrouter","CLAUDE_MEM_OPENROUTER_MODEL":"deepseek-chat","CLAUDE_MEM_OPENROUTER_API_KEY":"sk-你的DeepSeek-API-Key"}代码修复
文件:C:\SoftWare\OpenClaw\claude-mem\plugin\scripts\worker-service.cjs
Worker 的 SDK 初始化时硬编码了 OpenRouter 的 API 地址,需要通过字符串替换改为 DeepSeek 地址。
修复前:
// worker-service.cjs 中 SDK 初始化片段(压缩代码,约 2250000 字节处)FNe="https://openrouter.ai/api/v1/chat/completions"修复后:
// 替换为 DeepSeek 兼容端点FNe="https://api.deepseek.com/v1/chat/completions"由于worker-service.cjs是约 2.4MB 的 esbuild 压缩输出,手工查找比较困难。推荐使用补丁脚本自动处理。
补丁脚本
文件:C:\SoftWare\OpenClaw\claude-mem\patch_worker.cjs
varfs=require('fs');varfile='plugin/scripts/worker-service.cjs';varc=fs.readFileSync(file,'utf8');// 1. DeepSeek URL(OpenRouter → DeepSeek)c=c.replace(/https:\/\/openrouter\.ai\/api\/v1/g,'https://api.deepseek.com/v1');// 2. chroma-mcp spawn 修复(cmd.exe → uvx.exe 绝对路径,详见 Debug #4)c=c.replace(/process\.env\.ComSpec\|\|"cmd\.exe":"uvx",s=\w+\?\["\/c","uvx",\.\.\.\w+\]:\w+/,'"C:/Users/Friend/.local/bin/uvx.exe":"uvx",s=e');fs.writeFileSync(file,c);console.log('Patched successfully.');⚠️ 脚本中的用户名路径
Friend需替换为你的实际 Windows 用户名。
运行后重启 Worker:
node patch_worker.cjs bun plugin/scripts/worker-service.cjs restart验证
[INFO] [SDK] OpenRouter API usage {model=deepseek-chat, inputTokens=2143, outputTokens=289, totalTokens=2432, estimatedCostUSD=0.0108} [INFO] [DB] STORED {obsIds=[841]} | summaryId=noneAI 摘要正常生成,不再出现 401 错误。
七、Debug #4 — Chroma MCP Windows 连接失败
报错日志
[2026-04-28 03:48:12.321] [INFO ] [CHROMA_MCP] Connecting to chroma-mcp via MCP stdio {command=C:\Windows\system32\cmd.exe, args=/c uvx --python 3.13 chroma-mcp==0.2.6 --client-type persistent --data-dir C:/Users/Friend/.claude-mem/chroma} [2026-04-28 03:48:12.353] [WARN ] [CHROMA_MCP] Connection failed, killing subprocess to prevent zombie {error=MCP error -32000: Connection closed} [2026-04-28 03:48:12.354] [ERROR] [CHROMA] chroma sync failed, continuing without vector search连接在33ms内断开(第一行 12.321 → 第三行 12.353),不是超时,是 stdio 管道被截断。Chroma 向量同步成功率 0%,但 SQLite 存储正常,Worker 优雅降级。
排查过程
| 步 | 假设 | 操作 | 结果 |
|---|---|---|---|
| 1 | Chroma 服务没装,需要 HTTP 服务器 | pip install chromadb,启动 8000 端口 | ❌ Worker 不连这个端口,方向错误 |
| 2 | Worker 用的是 HTTP Chroma | 检查源码ChromaMcpManager.ts | ❌ Worker 内部自管 chroma-mcp,与 HTTP 无关 |
| 3 | Python 3.13 首次下载超时 | uvx --python 3.13 chroma-mcp==0.2.6 --help预热 | ❌ 预热后仍秒断 |
| 4 | daemon 模式下 PATH 找不到uvx.exe | where uvx.exe确认路径存在 | ❌ 路径没问题 |
| 5 | cmd.exe /c中间层破坏 MCP stdio 管道 | 分析源码 → 搜索 GitHub Issue → 修改 spawn 命令 | ✅ |
根因
Worker 通过MCP (Model Context Protocol)协议与chroma-mcpPython 子进程通信,通信介质是标准输入输出管道(stdio)。
Windows 版代码用cmd.exe /c uvx启动子进程:
Worker (bun) chroma-mcp (Python) │ │ └──spawn──→ cmd.exe ──再 spawn──→ uvx ──→ chroma-mcp ↑ MCP 握手 JSON 在这一层被截断cmd.exe /c启动后会在uvx完成初始化之前关闭自己的 stdin。MCP 协议的握手消息(客户端发送initialize请求,服务器回复initialized通知)在cmd.exe这一层丢失,导致连接在 33ms 内断开。
一览对比表
| 对比维度 | 修复前 | 修复后 |
|---|---|---|
| spawn 命令 | cmd.exe | C:/Users/Friend/.local/bin/uvx.exe |
| spawn 参数 | ["/c","uvx","--python","3.13",...] | ["--python","3.13",...] |
| 进程结构 | Worker→cmd.exe→uvx→chroma-mcp | Worker→uvx.exe→chroma-mcp |
| stdio 管道 | cmd.exe 中间层截断(33ms 断开) | 直连 stdout/stdin |
| MCP 握手结果 | Connection closed | Connected successfully |
| 向量同步成功率 | 0% | 100% |
代码修复
文件:C:\SoftWare\OpenClaw\claude-mem\src\services\sync\ChromaMcpManager.ts
修复前(第 131-135 行):
// On Windows, .cmd files require shell resolution. Since MCP SDK's// StdioClientTransport doesn't support `shell: true`, route through// cmd.exe which resolves .cmd/.bat extensions and PATH automatically.constisWindows=process.platform==='win32';constuvxSpawnCommand=isWindows?(process.env.ComSpec||'cmd.exe'):'uvx';constuvxSpawnArgs=isWindows?['/c','uvx',...commandArgs]:commandArgs;修复后:
// On Windows, use uvx.exe directly (native PE executable, not .cmd wrapper).// The previous approach of routing through cmd.exe /c broke MCP stdio transport// because the intermediate shell process disrupts stdin/stdout pipe forwarding.// Must use absolute path — daemon-mode workers don't have ~/.local/bin in PATH.// References: #1190, #1489 (uvx.cmd EINVAL), #1824/#1885 (cmd.exe stdio breakage).constisWindows=process.platform==='win32';constuvxExePath=path.join(os.homedir(),'.local','bin','uvx.exe');constuvxSpawnCommand=isWindows?(fs.existsSync(uvxExePath)?uvxExePath:'uvx.exe'):'uvx';constuvxSpawnArgs=commandArgs;关键点:
uvx.exe是 uv 安装的原生 Windows PE 可执行文件,不走.cmd/.bat包装- 必须用绝对路径—— daemon 模式启动的 Worker 进程的 PATH 环境变量不含
~/.local/bin
构建与重启
修改源码后重新构建并打补丁:
cd C:\SoftWare\OpenClaw\claude-mem node scripts/build-hooks.js node patch_worker.cjs bun plugin/scripts/worker-service.cjs restart⚠️
patch_worker.cjs中的第二步替换会自动完成本 Debug 的 spawn 修复。如果你在源码层面修改后重新构建,补丁会自动生效(因为build-hooks.js会生成新的worker-service.cjs,然后patch_worker.cjs再次替换)。
相关 GitHub Issues
- #1190 — uvx.cmd breaks MCP stdio transport(同症状,根因:uvx.cmd 包装)
- #1489 — uvx.cmd fails with EINVAL on Node.js(Node.js CVE-2024-27980 安全补丁禁止 spawn .cmd 文件)
- #1824 — chroma_add_documents timeout on Windows(连接成功但操作超时,不同问题)
验证
[CHROMA_MCP] Connecting to chroma-mcp via MCP stdio {command=C:/Users/Friend/.local/bin/uvx.exe, args=--python 3.13 ...} [CHROMA_MCP] Connected to chroma-mcp successfully [CHROMA_SYNC] Starting smart backfill {project=openclaw-main, missing=76} [CHROMA_SYNC] Smart backfill complete {project=openclaw-main} [CHROMA_SYNC] Syncing observation {observationId=1015, documentCount=7} [CHROMA_SYNC] Syncing observation {observationId=1016, documentCount=4}不再出现Connection closed,向量同步正常。
八、日常维护
8.1 启停命令
# 启动 WorkerC:\Users\Friend\AppData\Roaming\npm\node_modules\bun\bin\bun.exe C:\SoftWare\OpenClaw\claude-mem\plugin\scripts\worker-service.cjs--daemon# 停止 WorkerC:\Users\Friend\AppData\Roaming\npm\node_modules\bun\bin\bun.exe C:\SoftWare\OpenClaw\claude-mem\plugin\scripts\worker-service.cjs stop# 重启 WorkerC:\Users\Friend\AppData\Roaming\npm\node_modules\bun\bin\bun.exe C:\SoftWare\OpenClaw\claude-mem\plugin\scripts\worker-service.cjs restart# Gatewayopenclaw gatewaystart/stop/restart启动顺序:先 Worker,后 Gateway。关闭顺序:先 Gateway,后 Worker。
8.2 源码更新后重构建流程
当 claude-mem 发布新版本,或你修改了 TypeScript 源码后:
cd C:\SoftWare\OpenClaw\claude-mem git pull# 获取最新代码npm install# 更新依赖node scripts/build-hooks.js# 重新打包node patch_worker.cjs# 打补丁(每次构建后必须跑)bun plugin/scripts/worker-service.cjs restart8.3 日志位置
Worker 日志:
C:\Users\Friend\.claude-mem\logs\claude-mem-YYYY-MM-DD.log关键搜索词:
# Chroma 状态findstr"CHROMA"C:\Users\Friend\.claude-mem\logs\claude-mem-2026-04-28.log# AI SDK 调用findstr"SDK"C:\Users\Friend\.claude-mem\logs\claude-mem-2026-04-28.log# 观察存储findstr"STORED"C:\Users\Friend\.claude-mem\logs\claude-mem-2026-04-28.log# 错误findstr"ERROR"C:\Users\Friend\.claude-mem\logs\claude-mem-2026-04-28.log九、速查卡
9.1 文件路径汇总
| 文件 | 绝对路径 |
|---|---|
| claude-mem 源码根目录 | C:\SoftWare\OpenClaw\claude-mem\ |
| Worker 主程序(构建输出) | C:\SoftWare\OpenClaw\claude-mem\plugin\scripts\worker-service.cjs |
| ChromaMcpManager 源码 | C:\SoftWare\OpenClaw\claude-mem\src\services\sync\ChromaMcpManager.ts |
| 补丁脚本 | C:\SoftWare\OpenClaw\claude-mem\patch_worker.cjs |
| 启动脚本 | C:\SoftWare\OpenClaw\claude-mem\start_all.bat |
| 插件配置文件 | C:\Users\Friend\.openclaw\extensions\claude-mem-native\openclaw.plugin.json |
| 插件包配置 | C:\Users\Friend\.openclaw\extensions\claude-mem-native\package.json |
| 插件入口 | C:\Users\Friend\.openclaw\extensions\claude-mem-native\index.js |
| Worker 设置 | C:\Users\Friend\.claude-mem\settings.json |
| Gateway 配置 | C:\Users\Friend\AppData\Roaming\openclaw\openclaw.json |
| Worker 日志 | C:\Users\Friend\.claude-mem\logs\claude-mem-YYYY-MM-DD.log |
| SQLite 数据库 | C:\Users\Friend\.claude-mem\claude-mem.db |
| Chroma 向量数据 | C:\Users\Friend\.claude-mem\chroma\ |
| uvx.exe 可执行文件 | C:\Users\Friend\.local\bin\uvx.exe |
9.2 端口
| 端口 | 服务 | 验证命令 |
|---|---|---|
| 18789 | OpenClaw Gateway WebSocket | openclaw gateway health |
| 37777 | claude-mem Worker API | node -e "require('http').get('http://127.0.0.1:37777/health',r=>r.pipe(process.stdout))" |
9.3 常见报错 → 解决方案
| 报错 | 解决 |
|---|---|
插件不触发钩子,plugins list显示 disabled | Debug #1:kind改为"extension" |
Skipping — no workspaceDir | Debug #2:index.js加 workspaceDir fallback |
OpenRouter API error: 401 | Debug #3:替换 API URL,配置模型名 |
CHROMA_MCP Connection closed | Debug #4:uvx.exe绝对路径替代cmd.exe /c |
openclaw.json修改后自动还原 | 先执行openclaw gateway stop再编辑 |
| Worker 端口连不上 | netstat -ano | findstr 37777确认 LISTENING |
uvx提示下载 Python 超时 | 手动预热:uvx --python 3.13 chroma-mcp==0.2.6 --help |